Merge pull request #2210 from JacobBarthelmeh/Compatibility-Layer-Part2

JSSE additions
This commit is contained in:
toddouska
2019-04-24 11:04:05 -07:00
committed by GitHub
11 changed files with 538 additions and 67 deletions

View File

@@ -16033,6 +16033,27 @@ void SetErrorString(int error, char* str)
static const CipherSuiteInfo cipher_names[] =
{
#ifdef BUILD_TLS_AES_128_GCM_SHA256
SUITE_INFO("TLS13-AES128-GCM-SHA256","TLS_AES_128_GCM_SHA256",TLS13_BYTE,TLS_AES_128_GCM_SHA256),
#endif
#ifdef BUILD_TLS_AES_256_GCM_SHA384
SUITE_INFO("TLS13-AES256-GCM-SHA384","TLS_AES_256_GCM_SHA384",TLS13_BYTE,TLS_AES_256_GCM_SHA384),
#endif
#ifdef BUILD_TLS_CHACHA20_POLY1305_SHA256
SUITE_INFO("TLS13-CHACHA20-POLY1305-SHA256","TLS_CHACHA20_POLY1305_SHA256",TLS13_BYTE,TLS_CHACHA20_POLY1305_SHA256),
#endif
#ifdef BUILD_TLS_AES_128_CCM_SHA256
SUITE_INFO("TLS13-AES128-CCM-SHA256","TLS_AES_128_CCM_SHA256",TLS13_BYTE,TLS_AES_128_CCM_SHA256),
#endif
#ifdef BUILD_TLS_AES_128_CCM_8_SHA256
SUITE_INFO("TLS13-AES128-CCM-8-SHA256","TLS_AES_128_CCM_8_SHA256",TLS13_BYTE,TLS_AES_128_CCM_8_SHA256),
#endif
#ifndef WOLFSSL_NO_TLS12
#ifdef BUILD_SSL_RSA_WITH_RC4_128_SHA
@@ -16484,26 +16505,6 @@ static const CipherSuiteInfo cipher_names[] =
#endif
#endif /* WOLFSSL_NO_TLS12 */
#ifdef BUILD_TLS_AES_128_GCM_SHA256
SUITE_INFO("TLS13-AES128-GCM-SHA256","TLS_AES_128_GCM_SHA256",TLS13_BYTE,TLS_AES_128_GCM_SHA256),
#endif
#ifdef BUILD_TLS_AES_256_GCM_SHA384
SUITE_INFO("TLS13-AES256-GCM-SHA384","TLS_AES_256_GCM_SHA384",TLS13_BYTE,TLS_AES_256_GCM_SHA384),
#endif
#ifdef BUILD_TLS_CHACHA20_POLY1305_SHA256
SUITE_INFO("TLS13-CHACHA20-POLY1305-SHA256","TLS_CHACHA20_POLY1305_SHA256",TLS13_BYTE,TLS_CHACHA20_POLY1305_SHA256),
#endif
#ifdef BUILD_TLS_AES_128_CCM_SHA256
SUITE_INFO("TLS13-AES128-CCM-SHA256","TLS_AES_128_CCM_SHA256",TLS13_BYTE,TLS_AES_128_CCM_SHA256),
#endif
#ifdef BUILD_TLS_AES_128_CCM_8_SHA256
SUITE_INFO("TLS13-AES128-CCM-8-SHA256","TLS_AES_128_CCM_8_SHA256",TLS13_BYTE,TLS_AES_128_CCM_8_SHA256),
#endif
};
@@ -16636,7 +16637,11 @@ int SetCipherList(WOLFSSL_CTX* ctx, Suites* suites, const char* list)
name[(length == sizeof(name)) ? length - 1 : length] = 0;
for (i = 0; i < suiteSz; i++) {
if (XSTRNCMP(name, cipher_names[i].name, sizeof(name)) == 0) {
if (XSTRNCMP(name, cipher_names[i].name, sizeof(name)) == 0
#ifndef NO_ERROR_STRINGS
|| XSTRNCMP(name, cipher_names[i].name_iana, sizeof(name)) == 0
#endif
) {
#ifdef WOLFSSL_DTLS
/* don't allow stream ciphers with DTLS */
if (ctx->method->version.major == DTLS_MAJOR) {
@@ -16656,29 +16661,12 @@ int SetCipherList(WOLFSSL_CTX* ctx, Suites* suites, const char* list)
return 0; /* suites buffer not large enough, error out */
}
suites->suites[idx++] =
#ifdef WOLFSSL_TLS13
(XSTRSTR(name, "TLS13")) ? TLS13_BYTE :
#endif
#ifdef HAVE_CHACHA
(XSTRSTR(name, "CHACHA")) ? CHACHA_BYTE :
#endif
#ifdef HAVE_QSH
(XSTRSTR(name, "QSH")) ? QSH_BYTE :
#endif
#if defined(HAVE_ECC) || defined(HAVE_CURVE25519)
(XSTRSTR(name, "EC")) ? ECC_BYTE :
#endif
#ifdef HAVE_AESCCM
(XSTRSTR(name, "CCM")) ? ECC_BYTE :
#endif
CIPHER_BYTE; /* normal */
suites->suites[idx++] = cipher_names[i].cipherSuite0;
suites->suites[idx++] = cipher_names[i].cipherSuite;
/* The suites are either ECDSA, RSA, PSK, or Anon. The RSA
* suites don't necessarily have RSA in the name. */
#ifdef WOLFSSL_TLS13
if (XSTRSTR(name, "TLS13")) {
if (cipher_names[i].cipherSuite0 == TLS13_BYTE) {
#ifndef NO_RSA
haveRSAsig = 1;
#endif
@@ -17869,6 +17857,30 @@ exit_dpk:
return ret;
}
#ifdef WOLFSSL_TLS13
/* returns 1 if able to do TLS 1.3 otherwise 0 */
static int TLSv1_3_Capable(WOLFSSL* ssl)
{
#ifndef WOLFSSL_TLS13
return 0;
#else
int ret = 0;
if (IsAtLeastTLSv1_3(ssl->ctx->method->version)) {
ret = 1;
}
#ifdef OPENSSL_EXTRA
if ((wolfSSL_get_options(ssl) & SSL_OP_NO_TLSv1_3)) {
/* option set at run time to disable TLS 1.3 */
ret = 0;
}
#endif
return ret;
#endif
}
#endif /* WOLFSSL_TLS13 */
int CompleteServerHello(WOLFSSL* ssl)
{
int ret;
@@ -17878,7 +17890,7 @@ exit_dpk:
TLS13_DOWNGRADE_SZ - 1;
byte vers = ssl->arrays->serverRandom[RAN_LEN - 1];
#ifdef WOLFSSL_TLS13
if (IsAtLeastTLSv1_3(ssl->ctx->method->version)) {
if (TLSv1_3_Capable(ssl)) {
/* TLS v1.3 capable client not allowed to downgrade when
* connecting to TLS v1.3 capable server unless cipher suite
* demands it.

269
src/ssl.c
View File

@@ -720,6 +720,41 @@ int wolfSSL_get_ciphers(char* buf, int len)
return WOLFSSL_SUCCESS;
}
#ifndef NO_ERROR_STRINGS
/* places a list of all supported cipher suites in TLS_* format into "buf"
* return WOLFSSL_SUCCESS on success */
int wolfSSL_get_ciphers_iana(char* buf, int len)
{
const CipherSuiteInfo* ciphers = GetCipherNames();
int ciphersSz = GetCipherNamesSize();
int i;
int cipherNameSz;
if (buf == NULL || len <= 0)
return BAD_FUNC_ARG;
/* Add each member to the buffer delimited by a : */
for (i = 0; i < ciphersSz; i++) {
cipherNameSz = (int)XSTRLEN(ciphers[i].name_iana);
if (cipherNameSz + 1 < len) {
XSTRNCPY(buf, ciphers[i].name_iana, len);
buf += cipherNameSz;
if (i < ciphersSz - 1)
*buf++ = ':';
*buf = 0;
len -= cipherNameSz + 1;
}
else
return BUFFER_E;
}
return WOLFSSL_SUCCESS;
}
#endif /* NO_ERROR_STRINGS */
const char* wolfSSL_get_shared_ciphers(WOLFSSL* ssl, char* buf, int len)
{
const char* cipher;
@@ -15318,7 +15353,8 @@ WOLFSSL_X509* wolfSSL_X509_d2i(WOLFSSL_X509** x509, const byte* in, int len)
unsigned char* buf, int* bufSz)
{
WOLFSSL_ENTER("wolfSSL_X509_get_signature");
if (x509 == NULL || bufSz == NULL || *bufSz < (int)x509->sig.length)
if (x509 == NULL || bufSz == NULL || (*bufSz < (int)x509->sig.length &&
buf != NULL))
return WOLFSSL_FATAL_ERROR;
if (buf != NULL)
@@ -15329,6 +15365,91 @@ WOLFSSL_X509* wolfSSL_X509_d2i(WOLFSSL_X509** x509, const byte* in, int len)
}
/* Getter function that copies over the DER public key buffer to "buf" and
* sets the size in bufSz. If "buf" is NULL then just bufSz is set to needed
* buffer size. "bufSz" passed in should initially be set by the user to be
* the size of "buf". This gets checked to make sure the buffer is large
* enough to hold the public key.
*
* Note: this is the X.509 form of key with "header" info.
* return WOLFSSL_SUCCESS on success
*/
int wolfSSL_X509_get_pubkey_buffer(WOLFSSL_X509* x509,
unsigned char* buf, int* bufSz)
{
#ifdef WOLFSSL_SMALL_STACK
DecodedCert* cert;
#else
DecodedCert cert[1];
#endif
word32 idx;
const byte* der;
int length = 0;
int ret, derSz = 0;
int badDate = 0;
const byte* pubKeyX509 = NULL;
int pubKeyX509Sz = 0;
WOLFSSL_ENTER("wolfSSL_X509_get_pubkey_buffer");
if (x509 == NULL || bufSz == NULL) {
WOLFSSL_LEAVE("wolfSSL_X509_get_pubkey_buffer", BAD_FUNC_ARG);
return WOLFSSL_FATAL_ERROR;
}
#ifdef WOLFSSL_SMALL_STACK
cert = (DecodedCert*)XMALLOC(sizeof(DecodedCert),
x509->heap, DYNAMIC_TYPE_TMP_BUFFER);
if (cert == NULL) {
WOLFSSL_LEAVE("wolfSSL_X509_get_pubkey_buffer", MEMORY_E);
return WOLFSSL_FATAL_ERROR;
}
#endif
der = wolfSSL_X509_get_der(x509, &derSz);
InitDecodedCert(cert, der, derSz, NULL);
ret = wc_GetPubX509(cert, 0, &badDate);
if (ret >= 0) {
idx = cert->srcIdx;
pubKeyX509 = cert->source + cert->srcIdx;
ret = GetSequence(cert->source, &cert->srcIdx, &length,
cert->maxIdx);
pubKeyX509Sz = length + (cert->srcIdx - idx);
}
FreeDecodedCert(cert);
#ifdef WOLFSSL_SMALL_STACK
XFREE(cert, x509->heap, DYNAMIC_TYPE_TMP_BUFFER);
#endif
if (ret < 0) {
WOLFSSL_LEAVE("wolfSSL_X509_get_pubkey_buffer", ret);
return WOLFSSL_FATAL_ERROR;
}
if (buf != NULL) {
if (pubKeyX509Sz > *bufSz) {
WOLFSSL_LEAVE("wolfSSL_X509_get_pubkey_buffer", BUFFER_E);
return WOLFSSL_FATAL_ERROR;
}
XMEMCPY(buf, pubKeyX509, pubKeyX509Sz);
}
*bufSz = pubKeyX509Sz;
return WOLFSSL_SUCCESS;
}
/* Getter function for the public key OID value
* return public key OID stored in WOLFSSL_X509 structure */
int wolfSSL_X509_get_pubkey_type(WOLFSSL_X509* x509)
{
if (x509 == NULL)
return WOLFSSL_FAILURE;
return x509->pubKeyOID;
}
/* write X509 serial number in unsigned binary to buffer
buffer needs to be at least EXTERNAL_SERIAL_SIZE (32) for all cases
return WOLFSSL_SUCCESS on success */
@@ -15359,6 +15480,40 @@ WOLFSSL_X509* wolfSSL_X509_d2i(WOLFSSL_X509** x509, const byte* in, int len)
}
/* get the buffer to be signed (tbs) from the WOLFSSL_X509 certificate
*
* outSz : gets set to the size of the buffer
* returns a pointer to the internal buffer at the location of TBS on
* on success and NULL on failure.
*/
const unsigned char* wolfSSL_X509_get_tbs(WOLFSSL_X509* x509, int* outSz)
{
int sz = 0, len;
unsigned int idx = 0, tmpIdx;
const unsigned char* der = NULL;
const unsigned char* tbs = NULL;
if (x509 == NULL || outSz == NULL) {
return NULL;
}
der = wolfSSL_X509_get_der(x509, &sz);
if (der == NULL) {
return NULL;
}
if (GetSequence(der, &idx, &len, sz) < 0) {
return NULL;
}
tbs = der + idx;
tmpIdx = idx;
if (GetSequence(der, &idx, &len, sz) < 0) {
return NULL;
}
*outSz = len + (idx - tmpIdx);
return tbs;
}
int wolfSSL_X509_version(WOLFSSL_X509* x509)
{
WOLFSSL_ENTER("wolfSSL_X509_version");
@@ -16643,6 +16798,7 @@ WOLFSSL_EVP_PKEY* wolfSSL_X509_get_pubkey(WOLFSSL_X509* x509)
case AUTH_KEY_OID: isSet = x509->authKeyIdSet; break;
case SUBJ_KEY_OID: isSet = x509->subjKeyIdSet; break;
case KEY_USAGE_OID: isSet = x509->keyUsageSet; break;
case CRL_DIST_OID: isSet = x509->CRLdistSet; break;
#ifdef WOLFSSL_SEP
case CERT_POLICY_OID: isSet = x509->certPolicySet; break;
#endif /* WOLFSSL_SEP */
@@ -16668,6 +16824,7 @@ WOLFSSL_EVP_PKEY* wolfSSL_X509_get_pubkey(WOLFSSL_X509* x509)
case AUTH_KEY_OID: crit = x509->authKeyIdCrit; break;
case SUBJ_KEY_OID: crit = x509->subjKeyIdCrit; break;
case KEY_USAGE_OID: crit = x509->keyUsageCrit; break;
case CRL_DIST_OID: crit= x509->CRLdistCrit; break;
#ifdef WOLFSSL_SEP
case CERT_POLICY_OID: crit = x509->certPolicyCrit; break;
#endif /* WOLFSSL_SEP */
@@ -19113,6 +19270,53 @@ int wolfSSL_X509_verify_cert(WOLFSSL_X509_STORE_CTX* ctx)
}
return WOLFSSL_FATAL_ERROR;
}
/* Use the public key to verify the signature. Note: this only verifies
* the certificate signature.
* returns WOLFSSL_SUCCESS on successful signature verification */
int wolfSSL_X509_verify(WOLFSSL_X509* x509, WOLFSSL_EVP_PKEY* pkey)
{
int ret;
const byte* der;
int derSz = 0;
int type;
if (x509 == NULL || pkey == NULL) {
return WOLFSSL_FATAL_ERROR;
}
der = wolfSSL_X509_get_der(x509, &derSz);
if (der == NULL) {
WOLFSSL_MSG("Error getting WOLFSSL_X509 DER");
return WOLFSSL_FATAL_ERROR;
}
switch (pkey->type) {
case EVP_PKEY_RSA:
type = RSAk;
break;
case EVP_PKEY_EC:
type = ECDSAk;
break;
case EVP_PKEY_DSA:
type = DSAk;
break;
default:
WOLFSSL_MSG("Unknown pkey key type");
return WOLFSSL_FATAL_ERROR;
}
ret = CheckCertSignaturePubKey(der, derSz, x509->heap,
(unsigned char*)pkey->pkey.ptr, pkey->pkey_sz, type);
if (ret == 0) {
return WOLFSSL_SUCCESS;
}
return WOLFSSL_FAILURE;
}
#endif /* NO_CERTS */
#if !defined(NO_FILESYSTEM)
@@ -31278,8 +31482,8 @@ void* wolfSSL_GetDhAgreeCtx(WOLFSSL* ssl)
{ KEY_USAGE_OID, KEY_USAGE_OID, oidCertExtType, "X509 key usage" },
{ INHIBIT_ANY_OID, INHIBIT_ANY_OID, oidCertExtType,
"X509 inhibit any" },
{ NID_ext_key_usage, KEY_USAGE_OID, oidCertExtType,
"X509 ext key usage" },
{ NID_key_usage, KEY_USAGE_OID, oidCertExtType,
"X509 key usage" },
{ NID_name_constraints, NAME_CONS_OID, oidCertExtType,
"X509 name constraints" },
{ NID_certificate_policies, CERT_POLICY_OID, oidCertExtType,
@@ -32016,7 +32220,7 @@ void* wolfSSL_GetDhAgreeCtx(WOLFSSL* ssl)
case INHIBIT_ANY_OID:
return INHIBIT_ANY_OID;
case KEY_USAGE_OID:
return NID_ext_key_usage;
return NID_key_usage;
case NAME_CONS_OID:
return NID_name_constraints;
case CERT_POLICY_OID:
@@ -32173,15 +32377,47 @@ void* wolfSSL_GetDhAgreeCtx(WOLFSSL* ssl)
}
#endif
#ifndef NO_WOLFSSL_STUB
#ifdef WOLFSSL_CERT_EXT
/* Gets the NID value that is related to the OID string passed in. Example
* string would be "2.5.29.14" for subject key ID.
*
* @TODO does not handle short names yet
*
* returns NID value on success and NID_undef on error
*/
int wolfSSL_OBJ_txt2nid(const char* s)
{
(void)s;
WOLFSSL_STUB("OBJ_txt2nid");
int ret;
unsigned int outSz = MAX_OID_SZ;
unsigned char out[MAX_OID_SZ];
return 0;
WOLFSSL_ENTER("OBJ_txt2nid");
if (s == NULL) {
return NID_undef;
}
ret = EncodePolicyOID(out, &outSz, s, NULL);
if (ret == 0) {
unsigned int i, sum = 0;
/* sum OID */
for (i = 0; i < outSz; i++) {
sum += out[i];
}
/* get the group that the OID's sum is in
* @TODO possible conflict with multiples */
for (i = 0; i < WOLFSSL_OBJECT_INFO_SZ; i++) {
if (wolfssl_object_info[i].id == (int)sum) {
return wolfssl_object_info[i].nid;
}
}
}
return NID_undef;
}
#endif
#endif /* WOLFSSL_CERT_EXT */
/* compatibility function. It's intended use is to remove OID's from an
* internal table that have been added with OBJ_create. wolfSSL manages it's
@@ -33878,8 +34114,8 @@ WOLFSSL_CTX* wolfSSL_get_SSL_CTX(WOLFSSL* ssl)
}
#if defined(OPENSSL_ALL) || \
(defined(OPENSSL_EXTRA) && (defined(HAVE_STUNNEL) || \
defined(WOLFSSL_NGINX)) || defined(WOLFSSL_HAPROXY))
defined(OPENSSL_EXTRA) || defined(HAVE_STUNNEL) || \
defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY)
const byte* wolfSSL_SESSION_get_id(WOLFSSL_SESSION* sess, unsigned int* idLen)
{
@@ -34450,6 +34686,17 @@ long wolfSSL_SSL_CTX_get_timeout(const WOLFSSL_CTX *ctx)
return ctx->timeout;
}
/* returns the time in seconds of the current timeout */
long wolfSSL_get_timeout(WOLFSSL* ssl)
{
WOLFSSL_ENTER("wolfSSL_get_timeout");
if (ssl == NULL)
return 0;
return ssl->timeout;
}
#ifdef HAVE_ECC
int wolfSSL_SSL_CTX_set_tmp_ecdh(WOLFSSL_CTX *ctx, WOLFSSL_EC_KEY *ecdh)
{

View File

@@ -10755,6 +10755,31 @@ int TLSX_Parse(WOLFSSL* ssl, byte* input, word16 length, byte msgType,
}
#endif /* !WOLFSSL_NO_TLS12 */
#ifdef WOLFSSL_TLS13
/* Gets a WOLFSL_METHOD type that is not set as client or server
*
* Returns a pointer to a WOLFSSL_METHOD struct
*/
WOLFSSL_METHOD* wolfTLSv1_3_method(void)
{
return wolfTLSv1_3_method_ex(NULL);
}
WOLFSSL_METHOD* wolfTLSv1_3_method_ex(void* heap)
{
WOLFSSL_METHOD* m;
WOLFSSL_ENTER("TLSv1_3_method");
#ifndef NO_WOLFSSL_CLIENT
m = wolfTLSv1_3_client_method_ex(heap);
#else
m = wolfTLSv1_3_server_method_ex(heap);
#endif
if (m != NULL) {
m->side = WOLFSSL_NEITHER_END;
}
return m;
}
#endif /* WOLFSSL_TLS13 */
#ifdef WOLFSSL_DTLS
WOLFSSL_METHOD* wolfDTLS_method(void)
{

View File

@@ -1486,6 +1486,30 @@ WOLFSSL_API void wolfSSL_CTX_SetIOSend(WOLFSSL_CTX *ctx, CallbackIOSend CBIOSend
}
/* sets the IO callback to use for receives at WOLFSSL level */
WOLFSSL_API void wolfSSL_SSLSetIORecv(WOLFSSL *ssl, CallbackIORecv CBIORecv)
{
if (ssl != NULL) {
ssl->CBIORecv = CBIORecv;
#ifdef OPENSSL_EXTRA
ssl->cbioFlag |= WOLFSSL_CBIO_RECV;
#endif
}
}
/* sets the IO callback to use for sends at WOLFSSL level */
WOLFSSL_API void wolfSSL_SSLSetIOSend(WOLFSSL *ssl, CallbackIOSend CBIOSend)
{
if (ssl != NULL) {
ssl->CBIOSend = CBIOSend;
#ifdef OPENSSL_EXTRA
ssl->cbioFlag |= WOLFSSL_CBIO_SEND;
#endif
}
}
WOLFSSL_API void wolfSSL_SetIOReadCtx(WOLFSSL* ssl, void *rctx)
{
ssl->IOCB_ReadCtx = rctx;