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.
This commit is contained in:
Sean Parkinson
2017-07-03 18:29:15 +10:00
parent d956181911
commit 5bddb2e4ef
10 changed files with 321 additions and 62 deletions

View File

@@ -644,9 +644,15 @@ static void Usage(void)
printf("-? Help, print this usage\n");
printf("-h <host> Host to connect to, default %s\n", wolfSSLIP);
printf("-p <num> Port to connect on, not 0, default %d\n", wolfSSLPort);
#ifndef WOLFSSL_TLS13
printf("-v <num> 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 <num> 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 <str> Cipher suite list (: delimited)\n");
printf("-c <file> Certificate file, default %s\n", cliCertFile);
printf("-k <file> Key file, default %s\n", cliKeyFile);

View File

@@ -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 <num> Port to listen on, not 0, default %d\n", yasslPort);
#ifndef WOLFSSL_TLS13
printf("-v <num> SSL version [0-3], SSLv3(0) - TLS1.2(3)), default %d\n",
SERVER_DEFAULT_VERSION);
#else
printf("-v <num> SSL version [0-4], SSLv3(0) - TLS1.3(4)), default %d\n",
SERVER_DEFAULT_VERSION);
#endif
printf("-l <str> Cipher suite list (: delimited)\n");
printf("-c <file> Certificate file, default %s\n", svrCertFile);
printf("-k <file> Key file, default %s\n", svrKeyFile);

View File

@@ -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;

View File

@@ -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;

122
src/ssl.c
View File

@@ -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

View File

@@ -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());

View File

@@ -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;

View File

@@ -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

View File

@@ -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

View File

@@ -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,