From 5bddb2e4efed860489e3f67cc25a09000bc478ad Mon Sep 17 00:00:00 2001 From: Sean Parkinson Date: Mon, 3 Jul 2017 18:29:15 +1000 Subject: [PATCH 1/2] Changes for Nginx Support TLS v1.3 clients connecting to Nginx. Fix for PSS to not advertise hash unless the signature fits the private key size. Allow curves to be chosen by user. Support maximum verification depth (maximum number of untrusted certs in chain.) Add support for SSL_is_server() API. Fix number of certificates in chain when using wolfSSL_CTX_add_extra_chain_cert(). Allow TLS v1.2 client hello parsing to call TLS v1.3 parsing when SupportedVersions extension seen. Minor fixes. --- examples/client/client.c | 6 ++ examples/server/server.c | 5 ++ src/internal.c | 167 ++++++++++++++++++++++++++++++++++----- src/keys.c | 6 ++ src/ssl.c | 122 ++++++++++++++++++++++------ src/tls.c | 21 +++-- src/tls13.c | 22 ++++-- wolfssl/internal.h | 26 +++++- wolfssl/openssl/ssl.h | 3 + wolfssl/ssl.h | 5 +- 10 files changed, 321 insertions(+), 62 deletions(-) diff --git a/examples/client/client.c b/examples/client/client.c index 8a2f9db81..52f1ab828 100644 --- a/examples/client/client.c +++ b/examples/client/client.c @@ -644,9 +644,15 @@ static void Usage(void) printf("-? Help, print this usage\n"); printf("-h Host to connect to, default %s\n", wolfSSLIP); printf("-p Port to connect on, not 0, default %d\n", wolfSSLPort); +#ifndef WOLFSSL_TLS13 printf("-v SSL version [0-3], SSLv3(0) - TLS1.2(3)), default %d\n", CLIENT_DEFAULT_VERSION); printf("-V Prints valid ssl version numbers, SSLv3(0) - TLS1.2(3)\n"); +#else + printf("-v SSL version [0-4], SSLv3(0) - TLS1.3(4)), default %d\n", + CLIENT_DEFAULT_VERSION); + printf("-V Prints valid ssl version numbers, SSLv3(0) - TLS1.3(4)\n"); +#endif printf("-l Cipher suite list (: delimited)\n"); printf("-c Certificate file, default %s\n", cliCertFile); printf("-k Key file, default %s\n", cliKeyFile); diff --git a/examples/server/server.c b/examples/server/server.c index 26b735b4a..6dfc55539 100644 --- a/examples/server/server.c +++ b/examples/server/server.c @@ -339,8 +339,13 @@ static void Usage(void) " NOTE: All files relative to wolfSSL home dir\n"); printf("-? Help, print this usage\n"); printf("-p Port to listen on, not 0, default %d\n", yasslPort); +#ifndef WOLFSSL_TLS13 printf("-v SSL version [0-3], SSLv3(0) - TLS1.2(3)), default %d\n", SERVER_DEFAULT_VERSION); +#else + printf("-v SSL version [0-4], SSLv3(0) - TLS1.3(4)), default %d\n", + SERVER_DEFAULT_VERSION); +#endif printf("-l Cipher suite list (: delimited)\n"); printf("-c Certificate file, default %s\n", svrCertFile); printf("-k Key file, default %s\n", svrKeyFile); diff --git a/src/internal.c b/src/internal.c index 79283d3da..8a6bbe285 100755 --- a/src/internal.c +++ b/src/internal.c @@ -1359,6 +1359,9 @@ int InitSSL_Ctx(WOLFSSL_CTX* ctx, WOLFSSL_METHOD* method, void* heap) ctx->minEccKeySz = MIN_ECCKEY_SZ; ctx->eccTempKeySz = ECDHE_SIZE; #endif +#ifdef WOLFSSL_NGINX + ctx->verifyDepth = MAX_CHAIN_DEPTH; +#endif #ifndef WOLFSSL_USER_IO ctx->CBIORecv = EmbedReceive; @@ -1688,11 +1691,12 @@ void InitCipherSpecs(CipherSpecs* cs) } void InitSuitesHashSigAlgo(Suites* suites, int haveECDSAsig, int haveRSAsig, - int haveAnon, int tls1_2) + int haveAnon, int tls1_2, int keySz) { int idx = 0; (void)tls1_2; + (void)keySz; if (haveECDSAsig) { #ifdef WOLFSSL_SHA512 @@ -1722,12 +1726,16 @@ void InitSuitesHashSigAlgo(Suites* suites, int haveECDSAsig, int haveRSAsig, #ifdef WC_RSA_PSS if (tls1_2) { #ifdef WOLFSSL_SHA512 - suites->hashSigAlgo[idx++] = rsa_pss_sa_algo; - suites->hashSigAlgo[idx++] = sha512_mac; + if (keySz >= MIN_RSA_SHA512_PSS_BITS) { + suites->hashSigAlgo[idx++] = rsa_pss_sa_algo; + suites->hashSigAlgo[idx++] = sha512_mac; + } #endif #ifdef WOLFSSL_SHA384 - suites->hashSigAlgo[idx++] = rsa_pss_sa_algo; - suites->hashSigAlgo[idx++] = sha384_mac; + if (keySz >= MIN_RSA_SHA384_PSS_BITS) { + suites->hashSigAlgo[idx++] = rsa_pss_sa_algo; + suites->hashSigAlgo[idx++] = sha384_mac; + } #endif #ifndef NO_SHA256 suites->hashSigAlgo[idx++] = rsa_pss_sa_algo; @@ -1764,7 +1772,7 @@ void InitSuitesHashSigAlgo(Suites* suites, int haveECDSAsig, int haveRSAsig, suites->hashSigAlgoSz = (word16)idx; } -void InitSuites(Suites* suites, ProtocolVersion pv, word16 haveRSA, +void InitSuites(Suites* suites, ProtocolVersion pv, int keySz, word16 haveRSA, word16 havePSK, word16 haveDH, word16 haveNTRU, word16 haveECDSAsig, word16 haveECC, word16 haveStaticECC, int side) @@ -2632,7 +2640,7 @@ void InitSuites(Suites* suites, ProtocolVersion pv, word16 haveRSA, suites->suiteSz = idx; - InitSuitesHashSigAlgo(suites, haveECDSAsig, haveRSAsig, 0, tls1_2); + InitSuitesHashSigAlgo(suites, haveECDSAsig, haveRSAsig, 0, tls1_2, keySz); } #if !defined(NO_WOLFSSL_SERVER) || !defined(NO_CERTS) @@ -3804,6 +3812,9 @@ int SetSSL_CTX(WOLFSSL* ssl, WOLFSSL_CTX* ctx, int writeDup) #ifdef HAVE_ECC ssl->options.minEccKeySz = ctx->minEccKeySz; #endif +#ifdef WOLFSSL_NGINX + ssl->options.verifyDepth = ctx->verifyDepth; +#endif ssl->options.sessionCacheOff = ctx->sessionCacheOff; ssl->options.sessionCacheFlushOff = ctx->sessionCacheFlushOff; @@ -3835,6 +3846,7 @@ int SetSSL_CTX(WOLFSSL* ssl, WOLFSSL_CTX* ctx, int writeDup) #endif ssl->buffers.key = ctx->privateKey; ssl->buffers.keyType = ctx->privateKeyType; + ssl->buffers.keySz = ctx->privateKeySz; #endif #ifdef WOLFSSL_ASYNC_CRYPT @@ -3842,6 +3854,10 @@ int SetSSL_CTX(WOLFSSL* ssl, WOLFSSL_CTX* ctx, int writeDup) #endif if (writeDup == 0) { + int keySz = 0; +#ifndef NO_CERTS + keySz = ssl->buffers.keySz; +#endif #ifndef NO_PSK if (ctx->server_hint[0]) { /* set in CTX */ @@ -3858,15 +3874,15 @@ int SetSSL_CTX(WOLFSSL* ssl, WOLFSSL_CTX* ctx, int writeDup) /* make sure server has DH parms, and add PSK if there, add NTRU too */ if (ssl->options.side == WOLFSSL_SERVER_END) - InitSuites(ssl->suites, ssl->version, haveRSA, havePSK, - ssl->options.haveDH, ssl->options.haveNTRU, - ssl->options.haveECDSAsig, ssl->options.haveECC, - ssl->options.haveStaticECC, ssl->options.side); + InitSuites(ssl->suites, ssl->version, keySz, haveRSA, havePSK, + ssl->options.haveDH, ssl->options.haveNTRU, + ssl->options.haveECDSAsig, ssl->options.haveECC, + ssl->options.haveStaticECC, ssl->options.side); else - InitSuites(ssl->suites, ssl->version, haveRSA, havePSK, TRUE, - ssl->options.haveNTRU, ssl->options.haveECDSAsig, - ssl->options.haveECC, ssl->options.haveStaticECC, - ssl->options.side); + InitSuites(ssl->suites, ssl->version, keySz, haveRSA, havePSK, + TRUE, ssl->options.haveNTRU, + ssl->options.haveECDSAsig, ssl->options.haveECC, + ssl->options.haveStaticECC, ssl->options.side); #if !defined(NO_CERTS) && !defined(WOLFSSL_SESSION_EXPORT) /* make sure server has cert and key unless using PSK or Anon @@ -7251,6 +7267,10 @@ int CopyDecodedToX509(WOLFSSL_X509* x509, DecodedCert* dCert) } x509->subject.x509 = x509; #endif /* OPENSSL_EXTRA */ +#ifdef WOLFSSL_NGINX + XMEMCPY(x509->subject.raw, dCert->subjectRaw, dCert->subjectRawLen); + x509->subject.rawLen = dCert->subjectRawLen; +#endif XMEMCPY(x509->serial, dCert->serial, EXTERNAL_SERIAL_SIZE); x509->serialSz = dCert->serialSz; @@ -7454,6 +7474,9 @@ typedef struct ProcPeerCertArgs { #ifdef WOLFSSL_TRUST_PEER_CERT byte haveTrustPeer; /* was cert verified by loaded trusted peer cert */ #endif +#ifdef WOLFSSL_NGINX + char untrustedDepth; +#endif } ProcPeerCertArgs; static void FreeProcPeerCertArgs(WOLFSSL* ssl, void* pArgs) @@ -7765,6 +7788,42 @@ int ProcessPeerCerts(WOLFSSL* ssl, byte* input, word32* inOutIdx, } } #endif /* WOLFSSL_TRUST_PEER_CERT */ + #ifdef WOLFSSL_NGINX + if (args->certIdx == 0) { + byte* subjectHash; + + if (!args->dCertInit) { + InitDecodedCert(args->dCert, + args->certs[args->certIdx].buffer, + args->certs[args->certIdx].length, ssl->heap); + args->dCert->sigCtx.devId = ssl->devId; + args->dCertInit = 1; + } + + ret = ParseCertRelative(args->dCert, CERT_TYPE, 0, + ssl->ctx->cm); + if (ret != 0) { + #ifdef WOLFSSL_ASYNC_CRYPT + if (ret == WC_PENDING_E) { + ret = wolfSSL_AsyncPush(ssl, + args->dCert->sigCtx.asyncDev, + WC_ASYNC_FLAG_CALL_AGAIN); + } + #endif + goto exit_ppc; + } + + #ifndef NO_SKID + subjectHash = args->dCert->extSubjKeyId; + #else + subjectHash = args->dCert->subjectHash; + #endif + if (!AlreadySigner(ssl->ctx->cm, subjectHash)) + args->untrustedDepth = 1; + FreeDecodedCert(args->dCert); + args->dCertInit = 0; + } + #endif /* verify up to peer's first */ /* do not verify chain if trusted peer cert found */ @@ -7865,6 +7924,12 @@ int ProcessPeerCerts(WOLFSSL* ssl, byte* input, word32* inOutIdx, XMEMCPY(add->buffer, args->certs[args->certIdx].buffer, args->certs[args->certIdx].length); + + #ifdef WOLFSSL_NGINX + if (args->certIdx > args->untrustedDepth) + args->untrustedDepth = args->certIdx + 1; + #endif + /* already verified above */ ret = AddCA(ssl->ctx->cm, &add, WOLFSSL_CHAIN_CA, 0); if (ret == 1) { @@ -8418,6 +8483,12 @@ int ProcessPeerCerts(WOLFSSL* ssl, byte* input, word32* inOutIdx, ret = args->lastErr; } + #ifdef WOLFSSL_NGINX + if (args->untrustedDepth > ssl->options.verifyDepth) { + ssl->peerVerifyRet = X509_V_ERR_CERT_CHAIN_TOO_LONG; + ret = MAX_CHAIN_ERROR; + } + #endif if (ret != 0) { if (!ssl->options.verifyNone) { int why = bad_certificate; @@ -12655,6 +12726,10 @@ int SendCertificateRequest(WOLFSSL* ssl) int ret; int sendSz; word32 i = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ; + word32 dnLen = 0; +#ifdef WOLFSSL_NGINX + STACK_OF(WOLFSSL_X509_NAME)* names; +#endif int typeTotal = 1; /* only 1 for now */ int reqSz = ENUM_LEN + typeTotal + REQ_HEADER_SZ; /* add auth later */ @@ -12662,6 +12737,20 @@ int SendCertificateRequest(WOLFSSL* ssl) if (IsAtLeastTLSv1_2(ssl)) reqSz += LENGTH_SZ + ssl->suites->hashSigAlgoSz; +#ifdef WOLFSSL_NGINX + /* Certificate Authorities */ + names = ssl->ctx->ca_names; + while (names != NULL) { + byte seq[MAX_SEQ_SZ]; + + /* 16-bit length | SEQ | Len | DER of name */ + dnLen += OPAQUE16_LEN + SetSequence(names->data.name->rawLen, seq) + + names->data.name->rawLen; + names = names->next; + } + reqSz += dnLen; +#endif + if (ssl->options.usingPSK_cipher || ssl->options.usingAnon_cipher) return 0; /* not needed */ @@ -12706,9 +12795,24 @@ int SendCertificateRequest(WOLFSSL* ssl) i += ssl->suites->hashSigAlgoSz; } - c16toa(0, &output[i]); /* auth's */ - /* if add more to output, adjust i - i += REQ_HEADER_SZ; */ + /* Certificate Authorities */ + c16toa((word16)dnLen, &output[i]); /* auth's */ + i += REQ_HEADER_SZ; +#ifdef WOLFSSL_NGINX + names = ssl->ctx->ca_names; + while (names != NULL) { + byte seq[MAX_SEQ_SZ]; + + c16toa(names->data.name->rawLen + + SetSequence(names->data.name->rawLen, seq), &output[i]); + i += OPAQUE16_LEN; + i += SetSequence(names->data.name->rawLen, output + i); + XMEMCPY(output + i, names->data.name->raw, names->data.name->rawLen); + i += names->data.name->rawLen; + names = names->next; + } +#endif + (void)i; #ifdef WOLFSSL_DTLS if (IsDtlsNotSctpMode(ssl)) { @@ -15470,9 +15574,14 @@ int SetCipherList(WOLFSSL_CTX* ctx, Suites* suites, const char* list) while (next++); /* ++ needed to skip ':' */ if (ret) { + int keySz = 0; + #ifndef NO_CERTS + keySz = ctx->privateKeySz; + #endif suites->setSuites = 1; suites->suiteSz = (word16)idx; - InitSuitesHashSigAlgo(suites, haveECDSAsig, haveRSAsig, haveAnon, 1); + InitSuitesHashSigAlgo(suites, haveECDSAsig, haveRSAsig, haveAnon, 1, + keySz); } (void)ctx; @@ -21589,7 +21698,7 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, havePSK = ssl->options.havePSK; #endif - InitSuites(ssl->suites, ssl->version, haveRSA, havePSK, + InitSuites(ssl->suites, ssl->version, ssl->keySz, haveRSA, havePSK, ssl->options.haveDH, ssl->options.haveNTRU, ssl->options.haveECDSAsig, ssl->options.haveECC, ssl->options.haveStaticECC, ssl->options.side); @@ -21767,6 +21876,7 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, word16 haveRSA = 0; word16 havePSK = 0; + int keySz = 0; if (!ssl->options.downgrade) { WOLFSSL_MSG("Client trying to connect with lesser version"); @@ -21804,7 +21914,10 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, #ifndef NO_PSK havePSK = ssl->options.havePSK; #endif - InitSuites(ssl->suites, ssl->version, haveRSA, havePSK, +#ifndef NO_CERTS + keySz = ssl->buffers.keySz; +#endif + InitSuites(ssl->suites, ssl->version, keySz, haveRSA, havePSK, ssl->options.haveDH, ssl->options.haveNTRU, ssl->options.haveECDSAsig, ssl->options.haveECC, ssl->options.haveStaticECC, ssl->options.side); @@ -22037,6 +22150,18 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, if ((ret = TLSX_Parse(ssl, (byte *) input + i, totalExtSz, client_hello, &clSuites))) return ret; + #ifdef WOLFSSL_TLS13 + if (TLSX_Find(ssl->extensions, + TLSX_SUPPORTED_VERSIONS) != NULL) { + TLSX_FreeAll(ssl->extensions, ssl->heap); + ssl->extensions = NULL; + ssl->version.minor = TLSv1_3_MINOR; + *inOutIdx = begin; + if ((ret = InitHandshakeHashes(ssl)) != 0) + return ret; + return DoTls13ClientHello(ssl, input, inOutIdx, helloSz); + } + #endif #if defined(HAVE_STUNNEL) || defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY) if((ret=SNI_Callback(ssl))) return ret; diff --git a/src/keys.c b/src/keys.c index 8239b0ff6..b8726d28a 100644 --- a/src/keys.c +++ b/src/keys.c @@ -2900,6 +2900,7 @@ int SetKeysSide(WOLFSSL* ssl, enum encrypt_side side) switch (side) { case ENCRYPT_SIDE_ONLY: +#ifdef WOLFSSL_DEBUG_TLS WOLFSSL_MSG("Provisioning ENCRYPT key"); if (ssl->options.side == WOLFSSL_CLIENT_END) { WOLFSSL_BUFFER(ssl->keys.client_write_key, AES_256_KEY_SIZE); @@ -2907,10 +2908,12 @@ int SetKeysSide(WOLFSSL* ssl, enum encrypt_side side) else { WOLFSSL_BUFFER(ssl->keys.server_write_key, AES_256_KEY_SIZE); } +#endif wc_encrypt = &ssl->encrypt; break; case DECRYPT_SIDE_ONLY: +#ifdef WOLFSSL_DEBUG_TLS WOLFSSL_MSG("Provisioning DECRYPT key"); if (ssl->options.side == WOLFSSL_CLIENT_END) { WOLFSSL_BUFFER(ssl->keys.server_write_key, AES_256_KEY_SIZE); @@ -2918,10 +2921,12 @@ int SetKeysSide(WOLFSSL* ssl, enum encrypt_side side) else { WOLFSSL_BUFFER(ssl->keys.client_write_key, AES_256_KEY_SIZE); } +#endif wc_decrypt = &ssl->decrypt; break; case ENCRYPT_AND_DECRYPT_SIDE: +#ifdef WOLFSSL_DEBUG_TLS WOLFSSL_MSG("Provisioning ENCRYPT key"); if (ssl->options.side == WOLFSSL_CLIENT_END) { WOLFSSL_BUFFER(ssl->keys.client_write_key, AES_256_KEY_SIZE); @@ -2936,6 +2941,7 @@ int SetKeysSide(WOLFSSL* ssl, enum encrypt_side side) else { WOLFSSL_BUFFER(ssl->keys.client_write_key, AES_256_KEY_SIZE); } +#endif wc_encrypt = &ssl->encrypt; wc_decrypt = &ssl->decrypt; break; diff --git a/src/ssl.c b/src/ssl.c index 0acc0832c..393ec21fc 100755 --- a/src/ssl.c +++ b/src/ssl.c @@ -380,6 +380,11 @@ void wolfSSL_free(WOLFSSL* ssl) } +int wolfSSL_is_server(WOLFSSL* ssl) +{ + return ssl->options.side == WOLFSSL_SERVER_END; +} + #ifdef HAVE_WRITE_DUP /* @@ -1182,6 +1187,7 @@ int wolfSSL_SetTmpDH(WOLFSSL* ssl, const unsigned char* p, int pSz, { word16 havePSK = 0; word16 haveRSA = 1; + int keySz = 0; WOLFSSL_ENTER("wolfSSL_SetTmpDH"); if (ssl == NULL || p == NULL || g == NULL) return BAD_FUNC_ARG; @@ -1228,10 +1234,13 @@ int wolfSSL_SetTmpDH(WOLFSSL* ssl, const unsigned char* p, int pSz, #ifdef NO_RSA haveRSA = 0; #endif - InitSuites(ssl->suites, ssl->version, haveRSA, havePSK, ssl->options.haveDH, - ssl->options.haveNTRU, ssl->options.haveECDSAsig, - ssl->options.haveECC, ssl->options.haveStaticECC, - ssl->options.side); + #ifndef NO_CERTS + keySz = ssl->buffers.keySz; + #endif + InitSuites(ssl->suites, ssl->version, keySz, haveRSA, havePSK, + ssl->options.haveDH, ssl->options.haveNTRU, + ssl->options.haveECDSAsig, ssl->options.haveECC, + ssl->options.haveStaticECC, ssl->options.side); WOLFSSL_LEAVE("wolfSSL_SetTmpDH", 0); return SSL_SUCCESS; @@ -3218,6 +3227,7 @@ int wolfSSL_SetVersion(WOLFSSL* ssl, int version) { word16 haveRSA = 1; word16 havePSK = 0; + int keySz = 0; WOLFSSL_ENTER("wolfSSL_SetVersion"); @@ -3259,11 +3269,14 @@ int wolfSSL_SetVersion(WOLFSSL* ssl, int version) #ifndef NO_PSK havePSK = ssl->options.havePSK; #endif + #ifndef NO_CERTS + keySz = ssl->buffers.keySz; + #endif - InitSuites(ssl->suites, ssl->version, haveRSA, havePSK, ssl->options.haveDH, - ssl->options.haveNTRU, ssl->options.haveECDSAsig, - ssl->options.haveECC, ssl->options.haveStaticECC, - ssl->options.side); + InitSuites(ssl->suites, ssl->version, keySz, haveRSA, havePSK, + ssl->options.haveDH, ssl->options.haveNTRU, + ssl->options.haveECDSAsig, ssl->options.haveECC, + ssl->options.haveStaticECC, ssl->options.side); return SSL_SUCCESS; } @@ -4701,21 +4714,27 @@ int ProcessBuffer(WOLFSSL_CTX* ctx, const unsigned char* buff, #endif } else { /* check that the size of the RSA key is enough */ - int RsaSz = wc_RsaEncryptSize((RsaKey*)key); + int rsaSz = wc_RsaEncryptSize((RsaKey*)key); if (ssl) { - if (RsaSz < ssl->options.minRsaKeySz) { + if (rsaSz < ssl->options.minRsaKeySz) { ret = RSA_KEY_SIZE_E; WOLFSSL_MSG("Private Key size too small"); } ssl->buffers.keyType = rsa_sa_algo; + #ifdef WC_RSA_PSS + ssl->buffers.keySz = rsaSz; + #endif } else if(ctx) { - if (RsaSz < ctx->minRsaKeySz) { + if (rsaSz < ctx->minRsaKeySz) { ret = RSA_KEY_SIZE_E; WOLFSSL_MSG("Private Key size too small"); } ctx->privateKeyType = rsa_sa_algo; + #ifdef WC_RSA_PSS + ctx->privateKeySz = rsaSz; + #endif } rsaKey = 1; (void)rsaKey; /* for no ecc builds */ @@ -5009,8 +5028,8 @@ int ProcessBuffer(WOLFSSL_CTX* ctx, const unsigned char* buff, #endif /* let's reset suites */ - InitSuites(ssl->suites, ssl->version, haveRSA, havePSK, - ssl->options.haveDH, ssl->options.haveNTRU, + InitSuites(ssl->suites, ssl->version, ssl->buffers.keySz, haveRSA, + havePSK, ssl->options.haveDH, ssl->options.haveNTRU, ssl->options.haveECDSAsig, ssl->options.haveECC, ssl->options.haveStaticECC, ssl->options.side); } @@ -6257,7 +6276,11 @@ long wolfSSL_get_verify_depth(WOLFSSL* ssl) if(ssl == NULL) { return BAD_FUNC_ARG; } +#ifndef WOLFSSL_NGINX return MAX_CHAIN_DEPTH; +#else + return ssl->options.verifyDepth; +#endif } @@ -6267,7 +6290,11 @@ long wolfSSL_CTX_get_verify_depth(WOLFSSL_CTX* ctx) if(ctx == NULL) { return BAD_FUNC_ARG; } +#ifndef WOLFSSL_NGINX return MAX_CHAIN_DEPTH; +#else + return ctx->verifyDepth; +#endif } @@ -10103,6 +10130,7 @@ int wolfSSL_set_compression(WOLFSSL* ssl) void wolfSSL_set_psk_client_callback(WOLFSSL* ssl,wc_psk_client_callback cb) { byte haveRSA = 1; + int keySz = 0; WOLFSSL_ENTER("SSL_set_psk_client_callback"); ssl->options.havePSK = 1; @@ -10111,7 +10139,10 @@ int wolfSSL_set_compression(WOLFSSL* ssl) #ifdef NO_RSA haveRSA = 0; #endif - InitSuites(ssl->suites, ssl->version, haveRSA, TRUE, + #ifndef NO_CERTS + keySz = ssl->buffers.keySz; + #endif + InitSuites(ssl->suites, ssl->version, keySz, haveRSA, TRUE, ssl->options.haveDH, ssl->options.haveNTRU, ssl->options.haveECDSAsig, ssl->options.haveECC, ssl->options.haveStaticECC, ssl->options.side); @@ -10130,6 +10161,7 @@ int wolfSSL_set_compression(WOLFSSL* ssl) void wolfSSL_set_psk_server_callback(WOLFSSL* ssl,wc_psk_server_callback cb) { byte haveRSA = 1; + int keySz = 0; WOLFSSL_ENTER("SSL_set_psk_server_callback"); ssl->options.havePSK = 1; @@ -10138,7 +10170,10 @@ int wolfSSL_set_compression(WOLFSSL* ssl) #ifdef NO_RSA haveRSA = 0; #endif - InitSuites(ssl->suites, ssl->version, haveRSA, TRUE, + #ifndef NO_CERTS + keySz = ssl->buffers.keySz; + #endif + InitSuites(ssl->suites, ssl->version, keySz, haveRSA, TRUE, ssl->options.haveDH, ssl->options.haveNTRU, ssl->options.haveECDSAsig, ssl->options.haveECC, ssl->options.haveStaticECC, ssl->options.side); @@ -10686,8 +10721,8 @@ int wolfSSL_set_compression(WOLFSSL* ssl) #ifndef NO_PSK havePSK = ssl->options.havePSK; #endif - InitSuites(ssl->suites, ssl->version, haveRSA, havePSK, - ssl->options.haveDH, ssl->options.haveNTRU, + InitSuites(ssl->suites, ssl->version, ssl->buffers.keySz, haveRSA, + havePSK, ssl->options.haveDH, ssl->options.haveNTRU, ssl->options.haveECDSAsig, ssl->options.haveECC, ssl->options.haveStaticECC, ssl->options.side); } @@ -14328,8 +14363,8 @@ void wolfSSL_set_connect_state(WOLFSSL* ssl) #ifndef NO_PSK havePSK = ssl->options.havePSK; #endif - InitSuites(ssl->suites, ssl->version, haveRSA, havePSK, - ssl->options.haveDH, ssl->options.haveNTRU, + InitSuites(ssl->suites, ssl->version, ssl->buffers.keySz, haveRSA, + havePSK, ssl->options.haveDH, ssl->options.haveNTRU, ssl->options.haveECDSAsig, ssl->options.haveECC, ssl->options.haveStaticECC, ssl->options.side); } @@ -15929,6 +15964,12 @@ unsigned long wolfSSL_set_options(WOLFSSL* ssl, unsigned long op) WOLFSSL_MSG("\tSSL_OP_NO_SSLv2 : wolfSSL does not support SSLv2"); } + if ((ssl->options.mask & SSL_OP_NO_TLSv1_3) == SSL_OP_NO_TLSv1_3) { + WOLFSSL_MSG("\tSSL_OP_NO_TLSv1_3"); + if (ssl->version.minor == TLSv1_3_MINOR) + ssl->version.minor = TLSv1_2_MINOR; + } + if ((ssl->options.mask & SSL_OP_NO_TLSv1_2) == SSL_OP_NO_TLSv1_2) { WOLFSSL_MSG("\tSSL_OP_NO_TLSv1_2"); if (ssl->version.minor == TLSv1_2_MINOR) @@ -16472,6 +16513,9 @@ long wolfSSL_CTX_add_extra_chain_cert(WOLFSSL_CTX* ctx, WOLFSSL_X509* x509) idx += OPAQUE24_LEN, XMEMCPY(chain + idx, der, derSz); idx += derSz; +#ifdef WOLFSSL_TLS13 + ctx->certChainCnt++; +#endif FreeDer(&ctx->certChain); ret = AllocDer(&ctx->certChain, idx, CERT_TYPE, ctx->heap); @@ -22724,19 +22768,25 @@ void* wolfSSL_GetRsaDecCtx(WOLFSSL* ssl) void wolfSSL_CTX_set_verify_depth(WOLFSSL_CTX *ctx, int depth) { + WOLFSSL_ENTER("wolfSSL_CTX_set_verify_depth"); +#ifndef WOLFSSL_NGINX (void)ctx; (void)depth; - WOLFSSL_ENTER("wolfSSL_CTX_set_verify_depth"); WOLFSSL_STUB("wolfSSL_CTX_set_verify_depth"); - +#else + ctx->verifyDepth = depth; +#endif } void wolfSSL_set_verify_depth(WOLFSSL *ssl, int depth) { + WOLFSSL_ENTER("wolfSSL_set_verify_depth"); +#ifndef WOLFSSL_NGINX (void)ssl; (void)depth; - WOLFSSL_ENTER("wolfSSL_set_verify_depth"); WOLFSSL_STUB("wolfSSL_set_verify_depth"); - +#else + ssl->options.verifyDepth = depth; +#endif } void* wolfSSL_get_app_data( const WOLFSSL *ssl) { @@ -24958,6 +25008,32 @@ void wolfSSL_get0_next_proto_negotiated(const WOLFSSL *s, const unsigned char ** } #endif /* HAVE_ALPN */ +WOLFSSL_API int wolfSSL_CTX_set1_curves_list(WOLFSSL_CTX* ctx, char* names) +{ + int idx, start = 0; + int curve; + + ctx->disabledCurves = (word32)-1; + for (idx = 1; names[idx-1] != '\0'; idx++) { + if (names[idx] != ':' && names[idx] != '\0') + continue; + + if (XSTRNCMP(names, "prime256v1", idx - 1 - start) == 0) + curve = WOLFSSL_ECC_SECP256R1; + else if (XSTRNCMP(names, "secp384r1", idx - 1 - start) == 0) + curve = WOLFSSL_ECC_SECP384R1; + else if (XSTRNCMP(names, "X25519", idx - 1 - start) == 0) + curve = WOLFSSL_ECC_X25519; + else + return SSL_FAILURE; + + ctx->disabledCurves ^= 1 << curve; + start = idx + 1; + } + + return SSL_SUCCESS; +} + #endif /* WOLFSSL_NGINX / WOLFSSL_HAPROXY */ #ifdef OPENSSL_EXTRA diff --git a/src/tls.c b/src/tls.c index 1b5636eef..5a715e1d4 100755 --- a/src/tls.c +++ b/src/tls.c @@ -3016,6 +3016,11 @@ int TLSX_ValidateEllipticCurves(WOLFSSL* ssl, byte first, byte second) { curve && !(sig && key); curve = curve->next) { + #ifdef WOLFSSL_NGINX + if (ssl->ctx->disabledCurves & (1 << curve->name)) + continue; + #endif + /* find supported curve */ switch (curve->name) { #if defined(HAVE_ECC160) || defined(HAVE_ALL_CURVES) @@ -5860,7 +5865,11 @@ int TLSX_KeyShare_Establish(WOLFSSL *ssl) if (!TLSX_SupportedGroups_Find(ssl, clientKSE->group)) return BAD_KEY_SHARE_DATA; + #ifdef WOLFSSL_NGINX /* Check if server supports group. */ + if (ssl->ctx->disabledCurves & (1 << clientKSE->group)) + continue; + #endif if (TLSX_KeyShare_IsSupported(clientKSE->group)) break; } @@ -7761,8 +7770,10 @@ word16 TLSX_GetRequestSize(WOLFSSL* ssl, byte msgType) length += TLSX_GetSize(ssl->ctx->extensions, semaphore, msgType); #ifdef HAVE_EXTENDED_MASTER - if (msgType == client_hello && ssl->options.haveEMS) + if (msgType == client_hello && ssl->options.haveEMS && + !IsAtLeastTLSv1_3(ssl->version)) { length += HELLO_EXT_SZ; + } #endif if (length) @@ -7836,7 +7847,8 @@ word16 TLSX_WriteRequest(WOLFSSL* ssl, byte* output, byte msgType) } #ifdef HAVE_EXTENDED_MASTER - if (msgType == client_hello && ssl->options.haveEMS) { + if (msgType == client_hello && ssl->options.haveEMS && + !IsAtLeastTLSv1_3(ssl->version)) { c16toa(HELLO_EXT_EXTMS, output + offset); offset += HELLO_EXT_TYPE_SZ; c16toa(0, output + offset); @@ -8213,9 +8225,6 @@ int TLSX_Parse(WOLFSSL* ssl, byte* input, word16 length, byte msgType, case TLSX_SUPPORTED_VERSIONS: WOLFSSL_MSG("Supported Versions extension received"); - if (!IsAtLeastTLSv1_3(ssl->version)) - break; - if (IsAtLeastTLSv1_3(ssl->version) && msgType != client_hello) { return EXT_NOT_ALLOWED; @@ -8433,7 +8442,7 @@ int TLSX_Parse(WOLFSSL* ssl, byte* input, word16 length, byte msgType, (void)heap; if (method) { #if !defined(NO_SHA256) || defined(WOLFSSL_SHA384) || defined(WOLFSSL_SHA512) -#ifdef WOLFSSL_TLS13 +#if defined(WOLFSSL_TLS13) && !defined(WOLFSSL_NGINX) InitSSL_Method(method, MakeTLSv1_3()); #else InitSSL_Method(method, MakeTLSv1_2()); diff --git a/src/tls13.c b/src/tls13.c index 3981b1f48..6d3046b9d 100644 --- a/src/tls13.c +++ b/src/tls13.c @@ -3252,8 +3252,8 @@ static int RestartHandshakeHashWithCookie(WOLFSSL* ssl, Cookie* cookie) * helloSz The length of the current handshake message. * returns 0 on success and otherwise failure. */ -static int DoTls13ClientHello(WOLFSSL* ssl, const byte* input, word32* inOutIdx, - word32 helloSz) +int DoTls13ClientHello(WOLFSSL* ssl, const byte* input, word32* inOutIdx, + word32 helloSz) { int ret; byte b; @@ -3263,6 +3263,7 @@ static int DoTls13ClientHello(WOLFSSL* ssl, const byte* input, word32* inOutIdx, word32 begin = i; word16 totalExtSz; int usingPSK = 0; + byte sessIdSz; WOLFSSL_ENTER("DoTls13ClientHello"); @@ -3295,10 +3296,14 @@ static int DoTls13ClientHello(WOLFSSL* ssl, const byte* input, word32* inOutIdx, #endif /* Session id - empty in TLS v1.3 */ - b = input[i++]; - if (b != 0) { - WOLFSSL_MSG("Client sent session id - not supported"); - return BUFFER_ERROR; + sessIdSz = input[i++]; + if (sessIdSz > 0) { + ssl->version.major = pv.major; + ssl->version.minor = pv.minor; + ret = DoClientHello(ssl, input, inOutIdx, helloSz); + if (ret != 0) + return ret; + return HashInput(ssl, input + begin, helloSz); } /* Cipher suites */ @@ -3362,6 +3367,7 @@ static int DoTls13ClientHello(WOLFSSL* ssl, const byte* input, word32* inOutIdx, if (TLSX_Find(ssl->extensions, TLSX_SUPPORTED_VERSIONS) == NULL) ssl->version.minor = pv.minor; + #ifdef WOLFSSL_SEND_HRR_COOKIE if (ssl->options.sendCookie && ssl->options.serverState == SERVER_HELLO_RETRY_REQUEST) { @@ -3380,7 +3386,7 @@ static int DoTls13ClientHello(WOLFSSL* ssl, const byte* input, word32* inOutIdx, } #endif - ssl->options.sendVerify = SEND_CERT; + ssl->options.sendVerify = SEND_CERT; #if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK) /* Process the Pre-Shared Key extension if present. */ @@ -3708,7 +3714,7 @@ static int SendTls13CertificateRequest(WOLFSSL* ssl, byte* reqCtx, WOLFSSL_ENTER("SendTls13CertificateRequest"); if (ssl->options.side == WOLFSSL_SERVER_END) - InitSuitesHashSigAlgo(ssl->suites, 1, 1, 0, 1); + InitSuitesHashSigAlgo(ssl->suites, 1, 1, 0, 1, ssl->buffers.keySz); #ifdef WOLFSSL_TLS13_DRAFT_18 i = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ; diff --git a/wolfssl/internal.h b/wolfssl/internal.h index 0f28c4106..ef65a5fcf 100755 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -1103,6 +1103,9 @@ enum Misc { ED448_SA_MAJOR = 8, /* Most significant byte for ED448 */ ED448_SA_MINOR = 8, /* Least significant byte for ED448 */ + MIN_RSA_SHA512_PSS_BITS = 512 * 2 + 8 * 8, /* Min key size */ + MIN_RSA_SHA384_PSS_BITS = 384 * 2 + 8 * 8, /* Min key size */ + #ifdef HAVE_QSH /* qsh handshake sends 600+ size keys over hello extensions */ MAX_HELLO_SZ = 2048, /* max client or server hello */ @@ -1370,6 +1373,10 @@ WOLFSSL_LOCAL int DoApplicationData(WOLFSSL* ssl, byte* input, word32* inOutIdx) /* TLS v1.3 needs these */ WOLFSSL_LOCAL int DoClientHello(WOLFSSL* ssl, const byte* input, word32*, word32); +#ifdef WOLFSSL_TLS13 +WOLFSSL_LOCAL int DoTls13ClientHello(WOLFSSL* ssl, const byte* input, + word32* inOutIdx, word32 helloSz); +#endif WOLFSSL_LOCAL int DoServerHello(WOLFSSL* ssl, const byte* input, word32*, word32); WOLFSSL_LOCAL int CheckVersion(WOLFSSL *ssl, ProtocolVersion pv); @@ -1504,9 +1511,9 @@ typedef struct Suites { WOLFSSL_LOCAL void InitSuitesHashSigAlgo(Suites* suites, int haveECDSAsig, int haveRSAsig, int haveAnon, - int tls1_2); -WOLFSSL_LOCAL void InitSuites(Suites*, ProtocolVersion, word16, word16, word16, word16, - word16, word16, word16, int); + int tls1_2, int keySz); +WOLFSSL_LOCAL void InitSuites(Suites*, ProtocolVersion, int, word16, word16, + word16, word16, word16, word16, word16, int); WOLFSSL_LOCAL int MatchSuite(WOLFSSL* ssl, Suites* peerSuites); WOLFSSL_LOCAL int SetCipherList(WOLFSSL_CTX*, Suites*, const char* list); @@ -2186,6 +2193,7 @@ struct WOLFSSL_CTX { #endif DerBuffer* privateKey; byte privateKeyType; + int privateKeySz; WOLFSSL_CERT_MANAGER* cm; /* our cert manager, ctx owns SSL will use */ #endif #ifdef KEEP_OUR_CERT @@ -2236,6 +2244,10 @@ struct WOLFSSL_CTX { #if defined(HAVE_ECC) || defined(HAVE_ED25519) short minEccKeySz; /* minimum ECC key size */ #endif +#ifdef WOLFSSL_NGINX + word32 disabledCurves; /* curves disabled by user */ + byte verifyDepth; /* maximum verification depth */ +#endif #ifdef OPENSSL_EXTRA unsigned long mask; /* store SSL_OP_ flags */ #endif @@ -2690,6 +2702,7 @@ typedef struct Buffers { DerBuffer* certificate; /* WOLFSSL_CTX owns, unless we own */ DerBuffer* key; /* WOLFSSL_CTX owns, unless we own */ byte keyType; /* Type of key: RSA, ECC, Ed25519 */ + int keySz; /* Size of RSA key */ DerBuffer* certChain; /* WOLFSSL_CTX owns, unless we own */ /* chain after self, in DER, with leading size for each cert */ #ifdef WOLFSSL_TLS13 @@ -2858,6 +2871,9 @@ typedef struct Options { #if defined(HAVE_ECC) || defined(HAVE_ED25519) short minEccKeySz; /* minimum ECC key size */ #endif +#ifdef WOLFSSL_NGINX + byte verifyDepth; /* maximum verification depth */ +#endif #ifdef WOLFSSL_EARLY_DATA word32 maxEarlyDataSz; #endif @@ -2925,6 +2941,10 @@ struct WOLFSSL_X509_NAME { WOLFSSL_X509_NAME_ENTRY cnEntry; WOLFSSL_X509* x509; /* x509 that struct belongs to */ #endif /* OPENSSL_EXTRA */ +#ifdef WOLFSSL_NGINX + byte raw[ASN_NAME_MAX]; + int rawLen; +#endif }; #ifndef EXTERNAL_SERIAL_SIZE diff --git a/wolfssl/openssl/ssl.h b/wolfssl/openssl/ssl.h index 4091826d1..ea6bfedf8 100644 --- a/wolfssl/openssl/ssl.h +++ b/wolfssl/openssl/ssl.h @@ -760,6 +760,7 @@ typedef WOLFSSL_ASN1_BIT_STRING ASN1_BIT_STRING; #define ERR_LIB_PEM 9 #ifdef HAVE_SESSION_TICKET +#define SSL_OP_NO_TICKET SSL_OP_NO_TICKET #define SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB 72 #endif @@ -796,6 +797,8 @@ typedef WOLFSSL_ASN1_BIT_STRING ASN1_BIT_STRING; #define SSL_CTX_set_next_protos_advertised_cb wolfSSL_CTX_set_next_protos_advertised_cb #define SSL_CTX_set_next_proto_select_cb wolfSSL_CTX_set_next_proto_select_cb #define SSL_get0_next_proto_negotiated wolfSSL_get0_next_proto_negotiated +#define SSL_is_server wolfSSL_is_server +#define SSL_CTX_set1_curves_list wolfSSL_CTX_set1_curves_list #endif diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h index 671ac473f..38f00a7fb 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -383,6 +383,7 @@ WOLFSSL_API int wolfSSL_use_RSAPrivateKey_file(WOLFSSL*, const char*, int); WOLFSSL_API WOLFSSL_CTX* wolfSSL_CTX_new(WOLFSSL_METHOD*); WOLFSSL_API WOLFSSL* wolfSSL_new(WOLFSSL_CTX*); +WOLFSSL_API int wolfSSL_is_server(WOLFSSL*); WOLFSSL_API WOLFSSL* wolfSSL_write_dup(WOLFSSL*); WOLFSSL_API int wolfSSL_set_fd (WOLFSSL*, int); WOLFSSL_API int wolfSSL_set_write_fd (WOLFSSL*, int); @@ -839,6 +840,7 @@ enum { SSL_OP_NO_TLSv1_1 = 0x04000000, SSL_OP_NO_TLSv1_2 = 0x08000000, SSL_OP_NO_COMPRESSION = 0x10000000, + SSL_OP_NO_TLSv1_3 = 0x20000000, }; @@ -1921,7 +1923,6 @@ enum { /* Not implemented. */ WOLFSSL_ECC_X448 = 30, - /* Not implemented. */ WOLFSSL_FFDHE_2048 = 256, WOLFSSL_FFDHE_3072 = 257, WOLFSSL_FFDHE_4096 = 258, @@ -2396,6 +2397,8 @@ WOLFSSL_API char* wolfSSL_sk_WOLFSSL_STRING_value( WOLFSSL_API int PEM_write_bio_WOLFSSL_X509(WOLFSSL_BIO *bio, WOLFSSL_X509 *cert); + +WOLFSSL_API int wolfSSL_CTX_set1_curves_list(WOLFSSL_CTX* ctx, char* names); #endif /* WOLFSSL_NGINX */ WOLFSSL_API void wolfSSL_get0_alpn_selected(const WOLFSSL *ssl, From 31ac379c4f5533c1ff98b495ce2c1c49ddafc2fc Mon Sep 17 00:00:00 2001 From: Sean Parkinson Date: Thu, 6 Jul 2017 14:44:20 +1000 Subject: [PATCH 2/2] Code review fixes Change verify depth and set curve to be compiled in whe using: OPENSSL_EXTRA Fix comparison of curve name strings to use ecc function. Fix verify depth check when compiling with both OPENSSL_EXTRA and WOLFSSL_TRUST_PEER_CERT. --- src/internal.c | 25 +++++++++++++++------- src/ssl.c | 53 +++++++++++++++++++++++++++++++++------------- src/tls.c | 4 ++-- src/tls13.c | 8 ++----- wolfssl/internal.h | 11 +++++----- wolfssl/ssl.h | 3 ++- 6 files changed, 66 insertions(+), 38 deletions(-) diff --git a/src/internal.c b/src/internal.c index 8a6bbe285..42588a274 100755 --- a/src/internal.c +++ b/src/internal.c @@ -1359,7 +1359,7 @@ int InitSSL_Ctx(WOLFSSL_CTX* ctx, WOLFSSL_METHOD* method, void* heap) ctx->minEccKeySz = MIN_ECCKEY_SZ; ctx->eccTempKeySz = ECDHE_SIZE; #endif -#ifdef WOLFSSL_NGINX +#ifdef OPENSSL_EXTRA ctx->verifyDepth = MAX_CHAIN_DEPTH; #endif @@ -3812,7 +3812,7 @@ int SetSSL_CTX(WOLFSSL* ssl, WOLFSSL_CTX* ctx, int writeDup) #ifdef HAVE_ECC ssl->options.minEccKeySz = ctx->minEccKeySz; #endif -#ifdef WOLFSSL_NGINX +#ifdef OPENSSL_EXTRA ssl->options.verifyDepth = ctx->verifyDepth; #endif @@ -7474,7 +7474,7 @@ typedef struct ProcPeerCertArgs { #ifdef WOLFSSL_TRUST_PEER_CERT byte haveTrustPeer; /* was cert verified by loaded trusted peer cert */ #endif -#ifdef WOLFSSL_NGINX +#ifdef OPENSSL_EXTRA char untrustedDepth; #endif } ProcPeerCertArgs; @@ -7778,6 +7778,9 @@ int ProcessPeerCerts(WOLFSSL* ssl, byte* input, word32* inOutIdx, "Checking CAs"); FreeDecodedCert(args->dCert); args->dCertInit = 0; + #ifdef OPENSSL_EXTRA + args->untrustedDepth = 1; + #endif } else if (MatchTrustedPeer(tp, args->dCert)){ WOLFSSL_MSG("Found matching trusted peer cert"); haveTrustPeer = 1; @@ -7785,10 +7788,16 @@ int ProcessPeerCerts(WOLFSSL* ssl, byte* input, word32* inOutIdx, WOLFSSL_MSG("Trusted peer cert did not match!"); FreeDecodedCert(args->dCert); args->dCertInit = 0; + #ifdef OPENSSL_EXTRA + args->untrustedDepth = 1; + #endif } } #endif /* WOLFSSL_TRUST_PEER_CERT */ - #ifdef WOLFSSL_NGINX + #ifdef OPENSSL_EXTRA + #ifdef WOLFSSL_TRUST_PEER_CERT + else + #endif if (args->certIdx == 0) { byte* subjectHash; @@ -7801,13 +7810,13 @@ int ProcessPeerCerts(WOLFSSL* ssl, byte* input, word32* inOutIdx, } ret = ParseCertRelative(args->dCert, CERT_TYPE, 0, - ssl->ctx->cm); + ssl->ctx->cm); if (ret != 0) { #ifdef WOLFSSL_ASYNC_CRYPT if (ret == WC_PENDING_E) { ret = wolfSSL_AsyncPush(ssl, - args->dCert->sigCtx.asyncDev, - WC_ASYNC_FLAG_CALL_AGAIN); + args->dCert->sigCtx.asyncDev, + WC_ASYNC_FLAG_CALL_AGAIN); } #endif goto exit_ppc; @@ -8483,7 +8492,7 @@ int ProcessPeerCerts(WOLFSSL* ssl, byte* input, word32* inOutIdx, ret = args->lastErr; } - #ifdef WOLFSSL_NGINX + #ifdef OPENSSL_EXTRA if (args->untrustedDepth > ssl->options.verifyDepth) { ssl->peerVerifyRet = X509_V_ERR_CERT_CHAIN_TOO_LONG; ret = MAX_CHAIN_ERROR; diff --git a/src/ssl.c b/src/ssl.c index 393ec21fc..195b08fb8 100755 --- a/src/ssl.c +++ b/src/ssl.c @@ -382,6 +382,8 @@ void wolfSSL_free(WOLFSSL* ssl) int wolfSSL_is_server(WOLFSSL* ssl) { + if (ssl == NULL) + return BAD_FUNC_ARG; return ssl->options.side == WOLFSSL_SERVER_END; } @@ -6276,7 +6278,7 @@ long wolfSSL_get_verify_depth(WOLFSSL* ssl) if(ssl == NULL) { return BAD_FUNC_ARG; } -#ifndef WOLFSSL_NGINX +#ifndef OPENSSL_EXTRA return MAX_CHAIN_DEPTH; #else return ssl->options.verifyDepth; @@ -6290,7 +6292,7 @@ long wolfSSL_CTX_get_verify_depth(WOLFSSL_CTX* ctx) if(ctx == NULL) { return BAD_FUNC_ARG; } -#ifndef WOLFSSL_NGINX +#ifndef OPENSSL_EXTRA return MAX_CHAIN_DEPTH; #else return ctx->verifyDepth; @@ -22769,7 +22771,7 @@ void* wolfSSL_GetRsaDecCtx(WOLFSSL* ssl) void wolfSSL_CTX_set_verify_depth(WOLFSSL_CTX *ctx, int depth) { WOLFSSL_ENTER("wolfSSL_CTX_set_verify_depth"); -#ifndef WOLFSSL_NGINX +#ifndef OPENSSL_EXTRA (void)ctx; (void)depth; WOLFSSL_STUB("wolfSSL_CTX_set_verify_depth"); @@ -22780,7 +22782,7 @@ void* wolfSSL_GetRsaDecCtx(WOLFSSL* ssl) void wolfSSL_set_verify_depth(WOLFSSL *ssl, int depth) { WOLFSSL_ENTER("wolfSSL_set_verify_depth"); -#ifndef WOLFSSL_NGINX +#ifndef OPENSSL_EXTRA (void)ssl; (void)depth; WOLFSSL_STUB("wolfSSL_set_verify_depth"); @@ -25008,33 +25010,54 @@ void wolfSSL_get0_next_proto_negotiated(const WOLFSSL *s, const unsigned char ** } #endif /* HAVE_ALPN */ +#endif /* WOLFSSL_NGINX / WOLFSSL_HAPROXY */ + +#if defined(OPENSSL_EXTRA) && defined(HAVE_ECC) WOLFSSL_API int wolfSSL_CTX_set1_curves_list(WOLFSSL_CTX* ctx, char* names) { - int idx, start = 0; + int idx, start = 0, len; int curve; + char name[MAX_CURVE_NAME_SZ]; + /* Disable all curves so that only the ones the user wants are enabled. */ ctx->disabledCurves = (word32)-1; for (idx = 1; names[idx-1] != '\0'; idx++) { if (names[idx] != ':' && names[idx] != '\0') continue; - if (XSTRNCMP(names, "prime256v1", idx - 1 - start) == 0) - curve = WOLFSSL_ECC_SECP256R1; - else if (XSTRNCMP(names, "secp384r1", idx - 1 - start) == 0) - curve = WOLFSSL_ECC_SECP384R1; - else if (XSTRNCMP(names, "X25519", idx - 1 - start) == 0) - curve = WOLFSSL_ECC_X25519; - else + len = idx - 1 - start; + if (len > MAX_CURVE_NAME_SZ - 1) return SSL_FAILURE; - ctx->disabledCurves ^= 1 << curve; + XMEMCPY(name, names + start, len); + name[len] = 0; + + if ((XSTRNCMP(name, "prime256v1", len) == 0) || + (XSTRNCMP(name, "secp256r1", len) == 0) || + (XSTRNCMP(name, "P-256", len) == 0)) { + curve = WOLFSSL_ECC_SECP256R1; + } + else if ((XSTRNCMP(name, "secp384r1", len) == 0) || + (XSTRNCMP(name, "P-384", len) == 0)) { + curve = WOLFSSL_ECC_SECP384R1; + } + else if ((XSTRNCMP(name, "secp521r1", len) == 0) || + (XSTRNCMP(name, "P-521", len) == 0)) { + curve = WOLFSSL_ECC_SECP521R1; + } + else if (XSTRNCMP(name, "X25519", len) == 0) + curve = WOLFSSL_ECC_X25519; + else if ((curve = wc_ecc_get_curve_id_from_name(name)) < 0) + return SSL_FAILURE; + + /* Switch the bit to off and therefore is enabled. */ + ctx->disabledCurves &= ~(1 << curve); start = idx + 1; } return SSL_SUCCESS; } - -#endif /* WOLFSSL_NGINX / WOLFSSL_HAPROXY */ +#endif #ifdef OPENSSL_EXTRA int wolfSSL_CTX_set_msg_callback(WOLFSSL_CTX *ctx, SSL_Msg_Cb cb) diff --git a/src/tls.c b/src/tls.c index 5a715e1d4..0787abca0 100755 --- a/src/tls.c +++ b/src/tls.c @@ -3016,7 +3016,7 @@ int TLSX_ValidateEllipticCurves(WOLFSSL* ssl, byte first, byte second) { curve && !(sig && key); curve = curve->next) { - #ifdef WOLFSSL_NGINX + #ifdef OPENSSL_EXTRA if (ssl->ctx->disabledCurves & (1 << curve->name)) continue; #endif @@ -5865,7 +5865,7 @@ int TLSX_KeyShare_Establish(WOLFSSL *ssl) if (!TLSX_SupportedGroups_Find(ssl, clientKSE->group)) return BAD_KEY_SHARE_DATA; - #ifdef WOLFSSL_NGINX + #ifdef OPENSSL_EXTRA /* Check if server supports group. */ if (ssl->ctx->disabledCurves & (1 << clientKSE->group)) continue; diff --git a/src/tls13.c b/src/tls13.c index 6d3046b9d..add73ca16 100644 --- a/src/tls13.c +++ b/src/tls13.c @@ -3298,12 +3298,8 @@ int DoTls13ClientHello(WOLFSSL* ssl, const byte* input, word32* inOutIdx, /* Session id - empty in TLS v1.3 */ sessIdSz = input[i++]; if (sessIdSz > 0) { - ssl->version.major = pv.major; - ssl->version.minor = pv.minor; - ret = DoClientHello(ssl, input, inOutIdx, helloSz); - if (ret != 0) - return ret; - return HashInput(ssl, input + begin, helloSz); + WOLFSSL_MSG("Client sent session id - not supported"); + return BUFFER_ERROR; } /* Cipher suites */ diff --git a/wolfssl/internal.h b/wolfssl/internal.h index ef65a5fcf..d77da93de 100755 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -1096,6 +1096,7 @@ enum Misc { ECDHE_SIZE = 32, /* ECHDE server size defaults to 256 bit */ MAX_EXPORT_ECC_SZ = 256, /* Export ANS X9.62 max future size */ + MAX_CURVE_NAME_SZ = 16, /* Maximum size of curve name string */ NEW_SA_MAJOR = 8, /* Most signicant byte used with new sig algos */ ED25519_SA_MAJOR = 8, /* Most significant byte for ED25519 */ @@ -2244,12 +2245,10 @@ struct WOLFSSL_CTX { #if defined(HAVE_ECC) || defined(HAVE_ED25519) short minEccKeySz; /* minimum ECC key size */ #endif -#ifdef WOLFSSL_NGINX - word32 disabledCurves; /* curves disabled by user */ - byte verifyDepth; /* maximum verification depth */ -#endif #ifdef OPENSSL_EXTRA - unsigned long mask; /* store SSL_OP_ flags */ + word32 disabledCurves; /* curves disabled by user */ + byte verifyDepth; /* maximum verification depth */ + unsigned long mask; /* store SSL_OP_ flags */ #endif CallbackIORecv CBIORecv; CallbackIOSend CBIOSend; @@ -2871,7 +2870,7 @@ typedef struct Options { #if defined(HAVE_ECC) || defined(HAVE_ED25519) short minEccKeySz; /* minimum ECC key size */ #endif -#ifdef WOLFSSL_NGINX +#ifdef OPENSSL_EXTRA byte verifyDepth; /* maximum verification depth */ #endif #ifdef WOLFSSL_EARLY_DATA diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h index 38f00a7fb..8082aded2 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -2318,6 +2318,8 @@ WOLFSSL_API int wolfSSL_CTX_AsyncPoll(WOLFSSL_CTX* ctx, WOLF_EVENT** events, int #endif /* WOLFSSL_ASYNC_CRYPT */ #ifdef OPENSSL_EXTRA +WOLFSSL_API int wolfSSL_CTX_set1_curves_list(WOLFSSL_CTX* ctx, char* names); + typedef void (*SSL_Msg_Cb)(int write_p, int version, int content_type, const void *buf, size_t len, WOLFSSL *ssl, void *arg); @@ -2398,7 +2400,6 @@ WOLFSSL_API char* wolfSSL_sk_WOLFSSL_STRING_value( WOLFSSL_API int PEM_write_bio_WOLFSSL_X509(WOLFSSL_BIO *bio, WOLFSSL_X509 *cert); -WOLFSSL_API int wolfSSL_CTX_set1_curves_list(WOLFSSL_CTX* ctx, char* names); #endif /* WOLFSSL_NGINX */ WOLFSSL_API void wolfSSL_get0_alpn_selected(const WOLFSSL *ssl,