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 8daa3a636..ec5bae56a 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 OPENSSL_EXTRA + 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 OPENSSL_EXTRA + 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 OPENSSL_EXTRA + char untrustedDepth; +#endif } ProcPeerCertArgs; static void FreeProcPeerCertArgs(WOLFSSL* ssl, void* pArgs) @@ -7755,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; @@ -7762,9 +7788,51 @@ 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 OPENSSL_EXTRA + #ifdef WOLFSSL_TRUST_PEER_CERT + else + #endif + 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 +7933,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 +8492,12 @@ int ProcessPeerCerts(WOLFSSL* ssl, byte* input, word32* inOutIdx, ret = args->lastErr; } + #ifdef OPENSSL_EXTRA + 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; @@ -12664,6 +12744,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 */ @@ -12671,6 +12755,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 */ @@ -12715,9 +12813,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)) { @@ -15479,9 +15592,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; @@ -21601,7 +21719,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); @@ -21779,6 +21897,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"); @@ -21816,7 +21935,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); @@ -22049,6 +22171,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..195b08fb8 100755 --- a/src/ssl.c +++ b/src/ssl.c @@ -380,6 +380,13 @@ 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; +} + #ifdef HAVE_WRITE_DUP /* @@ -1182,6 +1189,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 +1236,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 +3229,7 @@ int wolfSSL_SetVersion(WOLFSSL* ssl, int version) { word16 haveRSA = 1; word16 havePSK = 0; + int keySz = 0; WOLFSSL_ENTER("wolfSSL_SetVersion"); @@ -3259,11 +3271,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 +4716,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 +5030,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 +6278,11 @@ long wolfSSL_get_verify_depth(WOLFSSL* ssl) if(ssl == NULL) { return BAD_FUNC_ARG; } +#ifndef OPENSSL_EXTRA return MAX_CHAIN_DEPTH; +#else + return ssl->options.verifyDepth; +#endif } @@ -6267,7 +6292,11 @@ long wolfSSL_CTX_get_verify_depth(WOLFSSL_CTX* ctx) if(ctx == NULL) { return BAD_FUNC_ARG; } +#ifndef OPENSSL_EXTRA return MAX_CHAIN_DEPTH; +#else + return ctx->verifyDepth; +#endif } @@ -10103,6 +10132,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 +10141,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 +10163,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 +10172,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 +10723,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 +14365,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 +15966,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 +16515,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 +22770,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 OPENSSL_EXTRA (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 OPENSSL_EXTRA (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) { @@ -24960,6 +25012,53 @@ void wolfSSL_get0_next_proto_negotiated(const WOLFSSL *s, const unsigned char ** #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, 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; + + len = idx - 1 - start; + if (len > MAX_CURVE_NAME_SZ - 1) + return SSL_FAILURE; + + 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 + #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 1b5636eef..0787abca0 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 OPENSSL_EXTRA + 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 OPENSSL_EXTRA /* 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 e93ccf487..178d32a22 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,8 +3296,8 @@ static int DoTls13ClientHello(WOLFSSL* ssl, const byte* input, word32* inOutIdx, #endif /* Session id - empty in TLS v1.3 */ - b = input[i++]; - if (b != 0) { + sessIdSz = input[i++]; + if (sessIdSz > 0) { WOLFSSL_MSG("Client sent session id - not supported"); return BUFFER_ERROR; } @@ -3362,6 +3363,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 +3382,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 +3710,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..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 */ @@ -1103,6 +1104,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 +1374,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 +1512,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 +2194,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 @@ -2237,7 +2246,9 @@ struct WOLFSSL_CTX { short minEccKeySz; /* minimum ECC key size */ #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; @@ -2690,6 +2701,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 +2870,9 @@ typedef struct Options { #if defined(HAVE_ECC) || defined(HAVE_ED25519) short minEccKeySz; /* minimum ECC key size */ #endif +#ifdef OPENSSL_EXTRA + byte verifyDepth; /* maximum verification depth */ +#endif #ifdef WOLFSSL_EARLY_DATA word32 maxEarlyDataSz; #endif @@ -2925,6 +2940,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..8082aded2 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, @@ -2317,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); @@ -2396,6 +2399,7 @@ WOLFSSL_API char* wolfSSL_sk_WOLFSSL_STRING_value( WOLFSSL_API int PEM_write_bio_WOLFSSL_X509(WOLFSSL_BIO *bio, WOLFSSL_X509 *cert); + #endif /* WOLFSSL_NGINX */ WOLFSSL_API void wolfSSL_get0_alpn_selected(const WOLFSSL *ssl,