diff --git a/configure.ac b/configure.ac index f752b42d6..a9ee566af 100644 --- a/configure.ac +++ b/configure.ac @@ -928,7 +928,7 @@ AC_ARG_ENABLE([opensslall], [ ENABLED_OPENSSLALL=$enableval ], [ ENABLED_OPENSSLALL=no ] ) -if test "$ENABLED_LIBWEBSOCKETS" = "yes" || test "$ENABLED_OPENVPN" = "yes" || test "$ENABLED_WPAS_DPP" = "yes" || test "$ENABLED_SMIME" = "yes" +if test "$ENABLED_LIBWEBSOCKETS" = "yes" || test "$ENABLED_OPENVPN" = "yes" || test "$ENABLED_WPAS_DPP" = "yes" || test "$ENABLED_SMIME" = "yes" || test "$ENABLED_HAPROXY" = "yes" then ENABLED_OPENSSLALL="yes" fi @@ -2771,7 +2771,7 @@ AC_ARG_ENABLE([anon], [ ENABLED_ANON=no ] ) -if test "x$ENABLED_WPAS" = "xyes" || test "$ENABLED_NGINX" = "yes" +if test "x$ENABLED_WPAS" = "xyes" || test "x$ENABLED_NGINX" = "xyes" || test "x$ENABLED_HAPROXY" = "xyes" then ENABLED_ANON=yes fi @@ -3722,6 +3722,11 @@ AC_ARG_ENABLE([secure-renegotiation], [ ENABLED_SECURE_RENEGOTIATION=no ] ) +if test "x$ENABLED_HAPROXY" = "xyes" +then + ENABLED_SECURE_RENEGOTIATION=yes +fi + if test "x$ENABLED_SECURE_RENEGOTIATION" = "xyes" then if test "x$ENABLED_RENEGOTIATION_INDICATION" = "xyes" @@ -4266,13 +4271,40 @@ fi if test "$ENABLED_HAPROXY" = "yes" then - AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_HAPROXY" - # Requires opensslextra make sure on - if test "x$ENABLED_OPENSSLEXTRA" = "xno" && test "x$ENABLED_OPENSSLCOEXIST" = "xno" + AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_HAPROXY -DOPENSSL_COMPATIBLE_DEFAULTS" + AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_SIGNER_DER_CERT" + # --enable-all defines its own FP_MAX_BITS + if test "$ENABLED_ALL" != "yes" + then + AM_CFLAGS="$AM_CFLAGS -DFP_MAX_BITS=16384" + fi + # Requires opensslextra and opensslall + if test "x$ENABLED_OPENSSLALL" = "xno" && test "x$ENABLED_OPENSSLCOEXIST" = "xno" then + ENABLED_OPENSSLALL="yes" ENABLED_OPENSSLEXTRA="yes" - AM_CFLAGS="-DOPENSSL_EXTRA $AM_CFLAGS" + AM_CFLAGS="-DOPENSSL_EXTRA -DOPENSSL_ALL $AM_CFLAGS" fi + + if test "x$ENABLED_CERTGEN" = "xno" + then + ENABLED_CERTGEN="yes" + AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_CERT_GEN" + fi + + if test "x$ENABLED_CERTREQ" = "xno" + then + ENABLED_CERTREQ="yes" + AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_CERT_REQ" + fi + + # Requires sessioncerts make sure on + if test "x$ENABLED_SESSIONCERTS" = "xno" + then + ENABLED_SESSIONCERTS="yes" + AM_CFLAGS="$AM_CFLAGS -DSESSION_CERTS" + fi + fi if test "$ENABLED_SIGNAL" = "yes" diff --git a/examples/client/client.c b/examples/client/client.c index 6772c82cd..dca20247e 100644 --- a/examples/client/client.c +++ b/examples/client/client.c @@ -933,7 +933,7 @@ static int ClientRead(WOLFSSL* ssl, char* reply, int replyLen, int mustRead, } else #endif - if (err != WOLFSSL_ERROR_WANT_READ) { + if (err != WOLFSSL_ERROR_WANT_READ && err != APP_DATA_READY) { printf("SSL_read reply error %d, %s\n", err, wolfSSL_ERR_error_string(err, buffer)); if (!exitWithRet) { @@ -957,6 +957,7 @@ static int ClientRead(WOLFSSL* ssl, char* reply, int replyLen, int mustRead, #ifdef WOLFSSL_ASYNC_CRYPT || err == WC_PENDING_E #endif + || err == APP_DATA_READY ); if (ret > 0) { reply[ret] = 0; /* null terminate */ @@ -2577,7 +2578,12 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) } #endif - +#ifdef OPENSSL_COMPATIBLE_DEFAULTS + /* Restore wolfSSL verify defaults */ + if (ctx) { + wolfSSL_CTX_set_verify(ctx, WOLFSSL_VERIFY_DEFAULT, NULL); + } +#endif #ifdef WOLFSSL_WOLFSENTRY_HOOKS if (wolfsentry_setup(&wolfsentry, wolfsentry_config_path, diff --git a/examples/server/server.c b/examples/server/server.c index c787c2cbf..bb42c3754 100644 --- a/examples/server/server.c +++ b/examples/server/server.c @@ -2008,6 +2008,11 @@ THREAD_RETURN WOLFSSL_THREAD server_test(void* args) wolfSSL_CTX_SetMinVersion(ctx, minVersion); } +#ifdef OPENSSL_COMPATIBLE_DEFAULTS + /* Restore wolfSSL verify defaults */ + wolfSSL_CTX_set_verify(ctx, WOLFSSL_VERIFY_DEFAULT, NULL); +#endif + #ifdef WOLFSSL_WOLFSENTRY_HOOKS if (wolfsentry_setup(&wolfsentry, wolfsentry_config_path, WOLFSENTRY_ROUTE_FLAG_DIRECTION_IN) < 0) { diff --git a/src/internal.c b/src/internal.c index 2d9877e7e..c3cb2921e 100644 --- a/src/internal.c +++ b/src/internal.c @@ -1951,6 +1951,9 @@ void SSL_CtxResourceFree(WOLFSSL_CTX* ctx) #ifndef NO_CERTS FreeDer(&ctx->privateKey); +#ifdef OPENSSL_ALL + wolfSSL_EVP_PKEY_free(ctx->privateKeyPKey); +#endif FreeDer(&ctx->certificate); #ifdef KEEP_OUR_CERT if (ctx->ourCert && ctx->ownOurCert) { @@ -1961,6 +1964,12 @@ void SSL_CtxResourceFree(WOLFSSL_CTX* ctx) FreeDer(&ctx->certChain); wolfSSL_CertManagerFree(ctx->cm); ctx->cm = NULL; + #ifdef OPENSSL_ALL + if (ctx->x509_store.objs != NULL) { + wolfSSL_sk_X509_OBJECT_free(ctx->x509_store.objs); + ctx->x509_store.objs = NULL; + } + #endif #ifdef OPENSSL_EXTRA wolfSSL_X509_STORE_free(ctx->x509_store_pt); while (ctx->ca_names != NULL) { @@ -3529,7 +3538,7 @@ void InitX509(WOLFSSL_X509* x509, int dynamicFlag, void* heap) InitX509Name(&x509->issuer, 0, heap); InitX509Name(&x509->subject, 0, heap); x509->dynamicMemory = (byte)dynamicFlag; - #if defined(OPENSSL_EXTRA) || defined(OPENSSL_ALL) + #if defined(OPENSSL_EXTRA_X509_SMALL) || defined(OPENSSL_EXTRA) x509->refCount = 1; (void)wc_InitMutex(&x509->refMutex); #endif @@ -5646,11 +5655,19 @@ int SetSSL_CTX(WOLFSSL* ssl, WOLFSSL_CTX* ctx, int writeDup) ssl->ConnectFilter_arg = ctx->ConnectFilter_arg; #endif - ssl->CBIORecv = ctx->CBIORecv; - ssl->CBIOSend = ctx->CBIOSend; #ifdef OPENSSL_EXTRA ssl->readAhead = ctx->readAhead; #endif +#ifdef OPENSSL_EXTRA + /* Don't change recv callback if currently using BIO's */ + if (ssl->CBIORecv != BioReceive) +#endif + ssl->CBIORecv = ctx->CBIORecv; +#ifdef OPENSSL_EXTRA + /* Don't change send callback if currently using BIO's */ + if (ssl->CBIOSend != BioSend) +#endif + ssl->CBIOSend = ctx->CBIOSend; ssl->verifyDepth = ctx->verifyDepth; return ret; @@ -8406,17 +8423,6 @@ retry: if (recvd < 0) { switch (recvd) { case WOLFSSL_CBIO_ERR_GENERAL: /* general/unknown error */ - #if defined(OPENSSL_ALL) || defined(WOLFSSL_APACHE_HTTPD) - #ifndef NO_BIO - if (ssl->biord) { - /* If retry and read flags are set, return WANT_READ */ - if ((ssl->biord->flags & WOLFSSL_BIO_FLAG_READ) && - (ssl->biord->flags & WOLFSSL_BIO_FLAG_RETRY)) { - return WANT_READ; - } - } - #endif - #endif return -1; case WOLFSSL_CBIO_ERR_WANT_READ: /* want read, would block */ @@ -11401,7 +11407,8 @@ int ProcessPeerCerts(WOLFSSL* ssl, byte* input, word32* inOutIdx, #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL) if (args->totalCerts >= MAX_CHAIN_DEPTH) { - ssl->peerVerifyRet = X509_V_ERR_CERT_CHAIN_TOO_LONG; + if (!ssl->peerVerifyRet) /* Return first cert error here */ + ssl->peerVerifyRet = X509_V_ERR_CERT_CHAIN_TOO_LONG; ret = MAX_CHAIN_ERROR; WOLFSSL_MSG("Too many certs for MAX_CHAIN_DEPTH"); break; /* break out to avoid reading more certs then buffer @@ -11618,7 +11625,8 @@ int ProcessPeerCerts(WOLFSSL* ssl, byte* input, word32* inOutIdx, else { WOLFSSL_MSG("Failed to verify CA from chain"); #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL) - ssl->peerVerifyRet = X509_V_ERR_INVALID_CA; + if (!ssl->peerVerifyRet) /* Return first cert error here */ + ssl->peerVerifyRet = X509_V_ERR_INVALID_CA; #endif } @@ -11677,7 +11685,8 @@ int ProcessPeerCerts(WOLFSSL* ssl, byte* input, word32* inOutIdx, /* extend the limit "+1" until reaching * an ultimately trusted issuer.*/ args->count > (ssl->verifyDepth + 1)) { - ssl->peerVerifyRet = X509_V_ERR_CERT_CHAIN_TOO_LONG; + if (!ssl->peerVerifyRet) /* Return first cert error here */ + ssl->peerVerifyRet = X509_V_ERR_CERT_CHAIN_TOO_LONG; ret = MAX_CHAIN_ERROR; } #endif @@ -11804,7 +11813,7 @@ int ProcessPeerCerts(WOLFSSL* ssl, byte* input, word32* inOutIdx, !ssl->options.verifyNone ? VERIFY : NO_VERIFY, &subjectHash, &alreadySigner); } else - ret = ASN_NO_SIGNER_E; + ret = ASN_NO_SIGNER_E; } #endif #ifdef WOLFSSL_ASYNC_CRYPT @@ -11814,7 +11823,8 @@ int ProcessPeerCerts(WOLFSSL* ssl, byte* input, word32* inOutIdx, if (ret == 0) { WOLFSSL_MSG("Verified Peer's cert"); #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL) - ssl->peerVerifyRet = X509_V_OK; + if (!ssl->peerVerifyRet) /* Return first cert error here */ + ssl->peerVerifyRet = X509_V_OK; #endif #if defined(SESSION_CERTS) && defined(WOLFSSL_ALT_CERT_CHAINS) /* if using alternate chain, store the cert used */ @@ -11853,15 +11863,24 @@ int ProcessPeerCerts(WOLFSSL* ssl, byte* input, word32* inOutIdx, DoCertFatalAlert(ssl, ret); #endif #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL) - ssl->peerVerifyRet = X509_V_ERR_CERT_REJECTED; + if (!ssl->peerVerifyRet) /* Return first cert error here */ + ssl->peerVerifyRet = X509_V_ERR_CERT_REJECTED; #endif args->fatal = 1; } else { WOLFSSL_MSG("Failed to verify Peer's cert"); - #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL) - ssl->peerVerifyRet = X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE; - #endif + #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL) + if (!ssl->peerVerifyRet) { /* Return first cert error here */ + if (ret == ASN_BEFORE_DATE_E) + ssl->peerVerifyRet = X509_V_ERR_CERT_NOT_YET_VALID; + else if (ret == ASN_AFTER_DATE_E) + ssl->peerVerifyRet = X509_V_ERR_CERT_HAS_EXPIRED; + else + ssl->peerVerifyRet = + X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE; + } + #endif if (ssl->verifyCallback) { WOLFSSL_MSG( "\tCallback override available, will continue"); @@ -11984,7 +12003,11 @@ int ProcessPeerCerts(WOLFSSL* ssl, byte* input, word32* inOutIdx, WOLFSSL_MSG("\tOCSP Lookup not ok"); args->fatal = 0; #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL) - ssl->peerVerifyRet = X509_V_ERR_CERT_REJECTED; + if (!ssl->peerVerifyRet) /* Return first cert error here */ + ssl->peerVerifyRet = + ret == OCSP_CERT_REVOKED + ? X509_V_ERR_CERT_REVOKED + : X509_V_ERR_CERT_REJECTED; #endif } } @@ -12003,7 +12026,11 @@ int ProcessPeerCerts(WOLFSSL* ssl, byte* input, word32* inOutIdx, WOLFSSL_MSG("\tCRL check not ok"); args->fatal = 0; #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL) - ssl->peerVerifyRet = X509_V_ERR_CERT_REJECTED; + if (!ssl->peerVerifyRet) /* Return first cert error here */ + ssl->peerVerifyRet = + ret == CRL_CERT_REVOKED + ? X509_V_ERR_CERT_REVOKED + : X509_V_ERR_CERT_REJECTED;; #endif } } @@ -12101,7 +12128,8 @@ int ProcessPeerCerts(WOLFSSL* ssl, byte* input, word32* inOutIdx, ssl->error = ret; #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL) SendAlert(ssl, alert_fatal, bad_certificate); - ssl->peerVerifyRet = X509_V_ERR_CERT_REJECTED; + if (!ssl->peerVerifyRet) /* Return first cert error here */ + ssl->peerVerifyRet = X509_V_ERR_CERT_REJECTED; #endif goto exit_ppc; } @@ -12444,7 +12472,8 @@ int ProcessPeerCerts(WOLFSSL* ssl, byte* input, word32* inOutIdx, * we hit the limit, with X509_V_ERR_CERT_CHAIN_TOO_LONG */ if (args->untrustedDepth > (ssl->options.verifyDepth + 1)) { - ssl->peerVerifyRet = X509_V_ERR_CERT_CHAIN_TOO_LONG; + if (!ssl->peerVerifyRet) /* Return first cert error here */ + ssl->peerVerifyRet = X509_V_ERR_CERT_CHAIN_TOO_LONG; ret = MAX_CHAIN_ERROR; } #endif @@ -18168,10 +18197,12 @@ int SendCertificateRequest(WOLFSSL* ssl) names = ssl->ctx->ca_names; while (names != NULL) { byte seq[MAX_SEQ_SZ]; + WOLFSSL_X509_NAME* name = names->data.name; - /* 16-bit length | SEQ | Len | DER of name */ - dnLen += OPAQUE16_LEN + SetSequence(names->data.name->rawLen, seq) + - names->data.name->rawLen; + if (name != NULL) + /* 16-bit length | SEQ | Len | DER of name */ + dnLen += OPAQUE16_LEN + SetSequence(name->rawLen, seq) + + name->rawLen; names = names->next; } reqSz += dnLen; @@ -18236,13 +18267,16 @@ int SendCertificateRequest(WOLFSSL* ssl) names = ssl->ctx->ca_names; while (names != NULL) { byte seq[MAX_SEQ_SZ]; + WOLFSSL_X509_NAME* name = names->data.name; - c16toa((word16)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; + if (name != NULL) { + c16toa((word16)name->rawLen + + SetSequence(name->rawLen, seq), &output[i]); + i += OPAQUE16_LEN; + i += SetSequence(name->rawLen, output + i); + XMEMCPY(output + i, name->raw, name->rawLen); + i += name->rawLen; + } names = names->next; } #endif @@ -19587,6 +19621,15 @@ const char* wolfSSL_ERR_reason_error_string(unsigned long e) #endif /* NO_ERROR_STRINGS */ } +const char* wolfSSL_ERR_func_error_string(unsigned long e) +{ + (void)e; + WOLFSSL_MSG("wolfSSL_ERR_func_error_string does not return the name of " + "the function that failed. Please inspect the wolfSSL debug " + "logs to determine where the error occurred."); + return ""; +} + void SetErrorString(int error, char* str) { XSTRNCPY(str, wolfSSL_ERR_reason_error_string(error), WOLFSSL_MAX_ERROR_SZ); @@ -28564,11 +28607,17 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, if (!ssl->options.downgrade) { WOLFSSL_MSG("Client trying to connect with lesser version"); +#ifdef OPENSSL_EXTRA + SendAlert(ssl, alert_fatal, handshake_failure); +#endif ret = VERSION_ERROR; goto out; } if (pv.minor < ssl->options.minDowngrade) { WOLFSSL_MSG("\tversion below minimum allowed, fatal error"); +#ifdef OPENSSL_EXTRA + SendAlert(ssl, alert_fatal, handshake_failure); +#endif ret = VERSION_ERROR; goto out; } @@ -31884,14 +31933,20 @@ static int DefTicketEncCb(WOLFSSL* ssl, byte key_name[WOLFSSL_TICKET_NAME_SZ], if(ssl && ssl->ctx && ssl->ctx->sniRecvCb) { WOLFSSL_MSG("Calling custom sni callback"); sniRet = ssl->ctx->sniRecvCb(ssl, &ad, ssl->ctx->sniRecvCbArg); - if (sniRet == alert_fatal) { - WOLFSSL_MSG("Error in custom sni callback. Fatal alert"); - SendAlert(ssl, alert_fatal, ad); - return FATAL_ERROR; - } - else if (sniRet == alert_warning) { - WOLFSSL_MSG("Error in custom sni callback. Warning alert"); - SendAlert(ssl, alert_warning, ad); + switch (sniRet) { + case warning_return: + WOLFSSL_MSG("Error in custom sni callback. Warning alert"); + SendAlert(ssl, alert_warning, ad); + break; + case fatal_return: + WOLFSSL_MSG("Error in custom sni callback. Fatal alert"); + SendAlert(ssl, alert_fatal, ad); + return FATAL_ERROR; + case noack_return: + WOLFSSL_MSG("Server quietly not acking servername."); + break; + default: + break; } } return 0; diff --git a/src/ocsp.c b/src/ocsp.c index f4b264bd3..3b2dfce6d 100644 --- a/src/ocsp.c +++ b/src/ocsp.c @@ -959,7 +959,7 @@ WOLFSSL_OCSP_CERTID* wolfSSL_OCSP_CERTID_dup(WOLFSSL_OCSP_CERTID* id) } #endif -#if defined(OPENSSL_ALL) || defined(APACHE_HTTPD) +#if defined(OPENSSL_ALL) || defined(APACHE_HTTPD) || defined(WOLFSSL_HAPROXY) #ifndef NO_BIO int wolfSSL_i2d_OCSP_REQUEST_bio(WOLFSSL_BIO* out, WOLFSSL_OCSP_REQUEST *req) @@ -1021,6 +1021,40 @@ const WOLFSSL_OCSP_CERTID* wolfSSL_OCSP_SINGLERESP_get0_id(const WOLFSSL_OCSP_SI return single; } +/** + * Compare two WOLFSSL_OCSP_CERTID objects + * @param a + * @param b + * @return 0 on success and when objects have the same id otherwise either + * the id's don't match or an error occurred + */ +int wolfSSL_OCSP_id_cmp(WOLFSSL_OCSP_CERTID *a, WOLFSSL_OCSP_CERTID *b) +{ + int ret = 0; + if (a == NULL || b == NULL) + return WOLFSSL_FATAL_ERROR; + + ret = a->hashAlgoOID != b->hashAlgoOID; + if (ret == 0) + ret = XMEMCMP(a->issuerHash, b->issuerHash, OCSP_DIGEST_SIZE); + if (ret == 0) + ret = XMEMCMP(a->issuerKeyHash, b->issuerKeyHash, OCSP_DIGEST_SIZE); + if (ret == 0) { + if (a->status != NULL && b->status != NULL) { + if (a->status->serialSz == b->status->serialSz) + ret = XMEMCMP(a->status->serial, b->status->serial, + a->status->serialSz); + else + ret = -1; + } + else if (a->status != b->status) { + /* If either is not null then return non-zero */ + ret = -1; + } + } + return ret; +} + int wolfSSL_OCSP_single_get0_status(WOLFSSL_OCSP_SINGLERESP *single, int *reason, WOLFSSL_ASN1_TIME **revtime, @@ -1152,7 +1186,7 @@ int wolfSSL_OCSP_id_get0_info(WOLFSSL_ASN1_STRING **name, ser->dataMax = WOLFSSL_ASN1_INTEGER_MAX; } - #ifdef WOLFSSL_QT + #if defined(WOLFSSL_QT) || defined(WOLFSSL_HAPROXY) /* Serial number starts at 0 index of ser->data */ XMEMCPY(&ser->data[i], cid->status->serial, cid->status->serialSz); ser->length = cid->status->serialSz; @@ -1160,6 +1194,7 @@ int wolfSSL_OCSP_id_get0_info(WOLFSSL_ASN1_STRING **name, ser->data[i++] = ASN_INTEGER; i += SetLength(cid->status->serialSz, ser->data + i); XMEMCPY(&ser->data[i], cid->status->serial, cid->status->serialSz); + ser->length = i + cid->status->serialSz; #endif cid->status->serialInt = ser; diff --git a/src/ssl.c b/src/ssl.c index de5fc28ab..13b4d9970 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -145,6 +145,13 @@ #endif #endif /* !WOLFCRYPT_ONLY || OPENSSL_EXTRA */ +/* + * OPENSSL_COMPATIBLE_DEFAULTS: + * Enable default behaviour that is compatible with OpenSSL. For example + * SSL_CTX by default doesn't verify the loaded certs. Enabling this + * should make porting to new projects easier. + */ + #define WOLFSSL_EVP_INCLUDED #include "wolfcrypt/src/evp.c" @@ -429,6 +436,23 @@ WOLFSSL_CTX* wolfSSL_CTX_new_ex(WOLFSSL_METHOD* method, void* heap) XFREE(method, heap, DYNAMIC_TYPE_METHOD); } +#ifdef OPENSSL_COMPATIBLE_DEFAULTS + if (ctx) { + if (wolfSSL_CTX_set_min_proto_version(ctx, + SSL3_VERSION) != WOLFSSL_SUCCESS || +#ifdef HAVE_ANON + wolfSSL_CTX_allow_anon_cipher(ctx) != WOLFSSL_SUCCESS || +#endif + wolfSSL_CTX_set_group_messages(ctx) != WOLFSSL_SUCCESS + ) { + WOLFSSL_MSG("Setting OpenSSL CTX defaults failed"); + wolfSSL_CTX_free(ctx); + ctx = NULL; + } + else + wolfSSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, NULL); + } +#endif WOLFSSL_LEAVE("WOLFSSL_CTX_new", 0); return ctx; @@ -7618,6 +7642,49 @@ int wolfSSL_CTX_check_private_key(const WOLFSSL_CTX* ctx) } #endif /* !NO_CHECK_PRIVATE_KEY */ +#ifdef OPENSSL_ALL +WOLFSSL_EVP_PKEY* wolfSSL_CTX_get0_privatekey(const WOLFSSL_CTX* ctx) +{ + const unsigned char *key; + int type; + + WOLFSSL_ENTER("wolfSSL_CTX_get0_privatekey"); + + if (ctx == NULL || ctx->privateKey == NULL || + ctx->privateKey->buffer == NULL) { + WOLFSSL_MSG("Bad parameter or key not set"); + return NULL; + } + + switch (ctx->privateKeyType) { +#ifndef NO_RSA + case rsa_sa_algo: + type = EVP_PKEY_RSA; + break; +#endif +#ifdef HAVE_ECC + case ecc_dsa_sa_algo: + type = EVP_PKEY_EC; + break; +#endif + default: + /* Other key types not supported either as ssl private keys + * or in the EVP layer */ + WOLFSSL_MSG("Unsupported key type"); + return NULL; + } + + key = ctx->privateKey->buffer; + + if (ctx->privateKeyPKey != NULL) + return ctx->privateKeyPKey; + else + return wolfSSL_d2i_PrivateKey(type, + &((WOLFSSL_CTX*)ctx)->privateKeyPKey, &key, + (long)ctx->privateKey->length); +} +#endif + #ifdef OPENSSL_EXTRA #ifndef NO_BIO @@ -9934,9 +10001,8 @@ void* wolfSSL_X509_get_ext_d2i(const WOLFSSL_X509* x509, int nid, int* c, } gn->type = dns->type; - gn->d.ia5->length = dns->len; if (wolfSSL_ASN1_STRING_set(gn->d.ia5, dns->name, - gn->d.ia5->length) != WOLFSSL_SUCCESS) { + dns->len) != WOLFSSL_SUCCESS) { WOLFSSL_MSG("ASN1_STRING_set failed"); goto err; } @@ -10338,7 +10404,120 @@ void wolfSSL_X509V3_set_ctx_nodb(WOLFSSL_X509V3_CTX* ctx) } #endif /* !NO_WOLFSSL_STUB */ -#if defined(OPENSSL_ALL) +#ifdef OPENSSL_ALL +static WOLFSSL_X509_EXTENSION* createExtFromStr(int nid, const char *value) { + WOLFSSL_X509_EXTENSION* ext = wolfSSL_X509_EXTENSION_new(); + + if (ext == NULL) { + WOLFSSL_MSG("memory error"); + return NULL; + } + + if (value == NULL) + return NULL; + + switch (nid) { + case NID_subject_key_identifier: + case NID_authority_key_identifier: + if (wolfSSL_ASN1_STRING_set(&ext->value, value, -1) + != WOLFSSL_SUCCESS) { + WOLFSSL_MSG("wolfSSL_ASN1_STRING_set error"); + goto err_cleanup; + } + ext->value.type = CTC_UTF8; + break; + case NID_subject_alt_name: + { + WOLFSSL_GENERAL_NAMES* gns = wolfSSL_sk_new_null(); + WOLFSSL_GENERAL_NAME* gn; + if (gns == NULL) { + WOLFSSL_MSG("wolfSSL_sk_new_null error"); + goto err_cleanup; + } + ext->ext_sk = gns; /* wolfSSL_X509_EXTENSION_free will handle + * free'ing gns */ + gns->type = STACK_TYPE_GEN_NAME; + gn = wolfSSL_GENERAL_NAME_new(); + if (gn == NULL) { + WOLFSSL_MSG("wolfSSL_GENERAL_NAME_new error"); + goto err_cleanup; + } + if (wolfSSL_sk_GENERAL_NAME_push(gns, gn) != WOLFSSL_SUCCESS) { + WOLFSSL_MSG("wolfSSL_sk_GENERAL_NAME_push error"); + wolfSSL_GENERAL_NAME_free(gn); + goto err_cleanup; + } + if (wolfSSL_ASN1_STRING_set(gn->d.ia5, value, -1) + != WOLFSSL_SUCCESS) { + WOLFSSL_MSG("wolfSSL_ASN1_STRING_set failed"); + goto err_cleanup; + } + gn->type = ASN_DNS_TYPE; + break; + } + case NID_key_usage: + if (wolfSSL_ASN1_STRING_set(&ext->value, value, -1) + != WOLFSSL_SUCCESS) { + WOLFSSL_MSG("wolfSSL_ASN1_STRING_set error"); + goto err_cleanup; + } + ext->value.type = KEY_USAGE_OID; + break; + default: + WOLFSSL_MSG("invalid or unsupported NID"); + goto err_cleanup; + } + return ext; +err_cleanup: + wolfSSL_X509_EXTENSION_free(ext); + return NULL; +} + +WOLFSSL_X509_EXTENSION* wolfSSL_X509V3_EXT_nconf_nid(WOLFSSL_CONF* conf, + WOLFSSL_X509V3_CTX *ctx, int nid, const char *value) +{ + WOLFSSL_ENTER("wolfSSL_X509V3_EXT_nconf_nid"); + + if (value == NULL) { + WOLFSSL_MSG("value NULL parameter"); + return NULL; + } + + if (conf != NULL || ctx != NULL) { + WOLFSSL_MSG("wolfSSL_X509V3_EXT_nconf_nid does not handle either " + "conf or ctx parameters"); + } + + return createExtFromStr(nid, value); +} + +WOLFSSL_X509_EXTENSION* wolfSSL_X509V3_EXT_nconf(WOLFSSL_CONF *conf, + WOLFSSL_X509V3_CTX *ctx, const char *sName, const char *value) +{ + const WOLFSSL_ObjectInfo* info = wolfssl_object_info; + size_t i; + + WOLFSSL_ENTER("wolfSSL_X509V3_EXT_nconf"); + + if (value == NULL) { + WOLFSSL_MSG("value NULL parameter"); + return NULL; + } + + if (conf != NULL || ctx != NULL) { + WOLFSSL_MSG("wolfSSL_X509V3_EXT_nconf does not handle either " + "conf or ctx parameters"); + } + + for (i = 0; i < wolfssl_object_info_sz; i++, info++) { + if (XSTRCMP(info->sName, sName) == 0) + return createExtFromStr(info->nid, value); + } + + WOLFSSL_MSG("value didn't match any known NID"); + return NULL; +} + static void wolfSSL_X509V3_EXT_METHOD_populate(WOLFSSL_v3_ext_method *method, int nid) { @@ -10906,18 +11085,20 @@ void wolfSSL_CTX_set_verify(WOLFSSL_CTX* ctx, int mode, VerifyCallback vc) ctx->failNoCert = 0; ctx->failNoCertxPSK = 0; - if (mode == WOLFSSL_VERIFY_NONE) { - ctx->verifyNone = 1; - } - else { - if (mode & WOLFSSL_VERIFY_PEER) { - ctx->verifyPeer = 1; + if (mode != WOLFSSL_VERIFY_DEFAULT) { + if (mode == WOLFSSL_VERIFY_NONE) { + ctx->verifyNone = 1; } - if (mode & WOLFSSL_VERIFY_FAIL_EXCEPT_PSK) { - ctx->failNoCertxPSK = 1; - } - if (mode & WOLFSSL_VERIFY_FAIL_IF_NO_PEER_CERT) { - ctx->failNoCert = 1; + else { + if (mode & WOLFSSL_VERIFY_PEER) { + ctx->verifyPeer = 1; + } + if (mode & WOLFSSL_VERIFY_FAIL_EXCEPT_PSK) { + ctx->failNoCertxPSK = 1; + } + if (mode & WOLFSSL_VERIFY_FAIL_IF_NO_PEER_CERT) { + ctx->failNoCert = 1; + } } } @@ -10949,18 +11130,20 @@ void wolfSSL_set_verify(WOLFSSL* ssl, int mode, VerifyCallback vc) ssl->options.failNoCert = 0; ssl->options.failNoCertxPSK = 0; - if (mode == WOLFSSL_VERIFY_NONE) { - ssl->options.verifyNone = 1; - } - else { - if (mode & WOLFSSL_VERIFY_PEER) { - ssl->options.verifyPeer = 1; + if (mode != WOLFSSL_VERIFY_DEFAULT) { + if (mode == WOLFSSL_VERIFY_NONE) { + ssl->options.verifyNone = 1; } - if (mode & WOLFSSL_VERIFY_FAIL_EXCEPT_PSK) { - ssl->options.failNoCertxPSK = 1; - } - if (mode & WOLFSSL_VERIFY_FAIL_IF_NO_PEER_CERT) { - ssl->options.failNoCert = 1; + else { + if (mode & WOLFSSL_VERIFY_PEER) { + ssl->options.verifyPeer = 1; + } + if (mode & WOLFSSL_VERIFY_FAIL_EXCEPT_PSK) { + ssl->options.failNoCertxPSK = 1; + } + if (mode & WOLFSSL_VERIFY_FAIL_IF_NO_PEER_CERT) { + ssl->options.failNoCert = 1; + } } } @@ -13795,6 +13978,9 @@ static WC_INLINE void RestoreSession(WOLFSSL* ssl, WOLFSSL_SESSION* session, ssl->session.cipherSuite0 = session->cipherSuite0; ssl->session.cipherSuite = session->cipherSuite; #endif +#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL) + ssl->peerVerifyRet = (unsigned long)session->peerVerifyRet; +#endif } WOLFSSL_SESSION* GetSession(WOLFSSL* ssl, byte* masterSecret, @@ -14246,6 +14432,11 @@ int AddSession(WOLFSSL* ssl) session->cipherSuite = ssl->options.cipherSuite; } #endif +#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL) + if (error == 0) { + session->peerVerifyRet = (byte)ssl->peerVerifyRet; + } +#endif #if defined(WOLFSSL_TLS13) if (error == 0) { session->namedGroup = ssl->session.namedGroup; @@ -17158,6 +17349,24 @@ int wolfSSL_CTX_set_max_proto_version(WOLFSSL_CTX* ctx, int ver) return CheckSslMethodVersion(ctx->method->version.major, ctx->mask); } +int wolfSSL_set_min_proto_version(WOLFSSL* ssl, int ver) +{ + /* TODO Return true for now because proto version selection logic + * is refactored in https://github.com/wolfSSL/wolfssl/pull/3871 */ + (void)ssl; + (void)ver; + return WOLFSSL_SUCCESS; +} + +int wolfSSL_set_max_proto_version(WOLFSSL* ssl, int ver) +{ + /* TODO Return true for now because proto version selection logic + * is refactored in https://github.com/wolfSSL/wolfssl/pull/3871 */ + (void)ssl; + (void)ver; + return WOLFSSL_SUCCESS; +} + static int GetMinProtoVersion(int minDowngrade) { int ret; @@ -19124,7 +19333,7 @@ WOLF_STACK_OF(WOLFSSL_X509)* wolfSSL_set_peer_cert_chain(WOLFSSL* ssl) * don't */ static void ExternalFreeX509(WOLFSSL_X509* x509) { -#if defined(OPENSSL_EXTRA) || defined(OPENSSL_ALL) +#if defined(OPENSSL_EXTRA_X509_SMALL) || defined(OPENSSL_EXTRA) int doFree = 0; #endif @@ -19134,7 +19343,7 @@ static void ExternalFreeX509(WOLFSSL_X509* x509) wolfSSL_CRYPTO_cleanup_ex_data(&x509->ex_data); #endif if (x509->dynamicMemory) { - #if defined(OPENSSL_EXTRA) || defined(OPENSSL_ALL) + #if defined(OPENSSL_EXTRA_X509_SMALL) || defined(OPENSSL_EXTRA) if (wc_LockMutex(&x509->refMutex) != 0) { WOLFSSL_MSG("Couldn't lock x509 mutex"); } @@ -19143,11 +19352,11 @@ static void ExternalFreeX509(WOLFSSL_X509* x509) if (x509->refCount == 0) doFree = 1; wc_UnLockMutex(&x509->refMutex); - #endif /* OPENSSL_EXTRA || OPENSSL_ALL */ + #endif /* OPENSSL_EXTRA_X509_SMALL || OPENSSL_EXTRA */ - #if defined(OPENSSL_EXTRA) || defined(OPENSSL_ALL) + #if defined(OPENSSL_EXTRA_X509_SMALL) || defined(OPENSSL_EXTRA) if (doFree) - #endif /* OPENSSL_EXTRA || OPENSSL_ALL */ + #endif /* OPENSSL_EXTRA_X509_SMALL || OPENSSL_EXTRA */ { FreeX509(x509); XFREE(x509, x509->heap, DYNAMIC_TYPE_X509); @@ -19204,6 +19413,36 @@ char* wolfSSL_X509_NAME_oneline(WOLFSSL_X509_NAME* name, char* in, int sz) return in; } +unsigned long wolfSSL_X509_NAME_hash(WOLFSSL_X509_NAME* name) +{ +#ifndef NO_SHA + byte digest[WC_SHA_DIGEST_SIZE]; + unsigned long ret = 0; + WOLFSSL_ENTER("wolfSSL_X509_NAME_hash"); + if (name == NULL) { + WOLFSSL_MSG("WOLFSSL_X509_NAME pointer was NULL"); + return 0; + } + if (name->sz == 0) { + WOLFSSL_MSG("nothing to hash in WOLFSSL_X509_NAME"); + return 0; + } + if (wc_ShaHash((byte*)name->name, name->sz, digest) != 0) { + WOLFSSL_MSG("wc_ShaHash error"); + return 0; + } + ret = (unsigned long) digest[0]; + ret |= ((unsigned long) digest[1]) << 8; + ret |= ((unsigned long) digest[2]) << 16; + ret |= ((unsigned long) digest[3]) << 24; + return ret; +#else + (void)name; + WOLFSSL_MSG("wolfSSL_X509_NAME_hash sha support not compiled in"); + return 0; +#endif +} + #if defined(OPENSSL_EXTRA) && defined(XSNPRINTF) /* Copies X509 subject name into a buffer, with comma-separated name entries * (matching OpenSSL v1.0.0 format) @@ -19874,15 +20113,6 @@ WOLFSSL_X509* wolfSSL_sk_X509_shift(WOLF_STACK_OF(WOLFSSL_X509)* sk) return wolfSSL_sk_X509_pop(sk); } -#ifndef NO_WOLFSSL_STUB -void* wolfSSL_sk_X509_OBJECT_value(WOLF_STACK_OF(WOLFSSL_X509_OBJECT)* sk, int x) -{ - (void) sk; - (void) x; - return NULL; -} -#endif - #endif /* !NO_CERTS && OPENSSL_EXTRA */ #if !defined(NO_CERTS) && (defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL)) @@ -19895,38 +20125,17 @@ void* wolfSSL_sk_X509_OBJECT_value(WOLF_STACK_OF(WOLFSSL_X509_OBJECT)* sk, int x void wolfSSL_sk_X509_pop_free(STACK_OF(WOLFSSL_X509)* sk, void (*f) (WOLFSSL_X509*)) { - WOLFSSL_STACK* node; - WOLFSSL_ENTER("wolfSSL_sk_X509_pop_free"); - if (sk == NULL) { - return; - } - - /* parse through stack freeing each node */ - node = sk->next; - while (node && sk->num > 1) { - WOLFSSL_STACK* tmp = node; - node = node->next; - - if (f) - f(tmp->data.x509); - else - wolfSSL_X509_free(tmp->data.x509); - tmp->data.x509 = NULL; - XFREE(tmp, NULL, DYNAMIC_TYPE_X509); - sk->num -= 1; - } - - /* free head of stack */ - if (sk->num == 1) { + while (sk != NULL) { + WOLFSSL_STACK* next = sk->next; if (f) f(sk->data.x509); else wolfSSL_X509_free(sk->data.x509); - sk->data.x509 = NULL; + XFREE(sk, NULL, DYNAMIC_TYPE_OPENSSL); + sk = next; } - XFREE(sk, NULL, DYNAMIC_TYPE_X509); } @@ -26635,7 +26844,7 @@ WOLFSSL_ASN1_INTEGER* wolfSSL_X509_get_serialNumber(WOLFSSL_X509* x509) a->dataMax = WOLFSSL_ASN1_INTEGER_MAX; } - #ifdef WOLFSSL_QT + #if defined(WOLFSSL_QT) || defined(WOLFSSL_HAPROXY) XMEMCPY(&a->data[i], x509->serial, x509->serialSz); a->length = x509->serialSz; #else @@ -29737,6 +29946,8 @@ void* wolfSSL_sk_value(const WOLFSSL_STACK* sk, int i) return (void*)sk->data.obj; case STACK_TYPE_X509_EXT: return (void*)sk->data.ext; + case STACK_TYPE_X509_OBJ: + return (void*)sk->data.x509_obj; #ifdef OPENSSL_EXTRA case STACK_TYPE_CONF_VALUE: return (void*)sk->data.conf; @@ -30085,7 +30296,7 @@ int wolfSSL_sk_SSL_COMP_num(WOLF_STACK_OF(WOLFSSL_COMP)* sk) * the session to resume it. */ void wolfSSL_CTX_sess_set_get_cb(WOLFSSL_CTX* ctx, - WOLFSSL_SESSION*(*f)(WOLFSSL*, unsigned char*, int, int*)) + WOLFSSL_SESSION*(*f)(WOLFSSL*, const unsigned char*, int, int*)) { if (ctx == NULL) return; @@ -30173,6 +30384,10 @@ int wolfSSL_i2d_SSL_SESSION(WOLFSSL_SESSION* sess, unsigned char** p) /* session context ID len | session context ID */ size += OPAQUE8_LEN + sess->sessionCtxSz; #endif +#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL) + /* peerVerifyRet */ + size += OPAQUE8_LEN; +#endif #ifdef WOLFSSL_TLS13 /* namedGroup */ size += OPAQUE16_LEN; @@ -30238,6 +30453,9 @@ int wolfSSL_i2d_SSL_SESSION(WOLFSSL_SESSION* sess, unsigned char** p) XMEMCPY(data + idx, sess->sessionCtx, sess->sessionCtxSz); idx += sess->sessionCtxSz; #endif +#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL) + data[idx++] = sess->peerVerifyRet; +#endif #ifdef WOLFSSL_TLS13 c16toa(sess->namedGroup, data + idx); idx += OPAQUE16_LEN; @@ -30411,6 +30629,14 @@ WOLFSSL_SESSION* wolfSSL_d2i_SSL_SESSION(WOLFSSL_SESSION** sess, } XMEMCPY(s->sessionCtx, data + idx, s->sessionCtxSz); idx += s->sessionCtxSz; #endif +#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL) + /* byte for peerVerifyRet */ + if (i - idx < OPAQUE8_LEN) { + ret = BUFFER_ERROR; + goto end; + } + s->peerVerifyRet = data[idx++]; +#endif #ifdef WOLFSSL_TLS13 if (i - idx < OPAQUE16_LEN) { ret = BUFFER_ERROR; @@ -30815,8 +31041,8 @@ const WOLFSSL_ObjectInfo wolfssl_object_info[] = { { NID_dsa, DSAk, oidKeyType, "DSA", "dsaEncryption"}, #endif /* NO_DSA */ #ifndef NO_RSA - { RSAk, RSAk, oidKeyType, "RSA", "rsaEncryption"}, - { NID_rsaEncryption, RSAk, oidKeyType, "RSA", "rsaEncryption"}, + { RSAk, RSAk, oidKeyType, "rsaEncryption", "rsaEncryption"}, + { NID_rsaEncryption, RSAk, oidKeyType, "rsaEncryption", "rsaEncryption"}, #endif /* NO_RSA */ #ifdef HAVE_NTRU { NTRUk, NTRUk, oidKeyType, "NTRU", "ntruEncryption"}, @@ -39774,7 +40000,7 @@ int wolfSSL_DH_LoadDer(WOLFSSL_DH* dh, const unsigned char* derBuf, int derSz) #endif /* OPENSSL_EXTRA */ -#if defined(OPENSSL_EXTRA) || defined(OPENSSL_ALL) +#if defined(OPENSSL_EXTRA_X509_SMALL) || defined(OPENSSL_EXTRA) /* increments ref count of WOLFSSL_RSA. Return 1 on success, 0 on error */ int wolfSSL_RSA_up_ref(WOLFSSL_RSA* rsa) @@ -39807,8 +40033,16 @@ int wolfSSL_X509_up_ref(WOLFSSL_X509* x509) return WOLFSSL_FAILURE; } +#endif /* OPENSSL_EXTRA_X509_SMALL || OPENSSL_EXTRA */ -#endif /* OPENSSL_EXTRA || OPENSSL_ALL */ +#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL) +WOLF_STACK_OF(WOLFSSL_X509)* wolfSSL_X509_chain_up_ref( + WOLF_STACK_OF(WOLFSSL_X509)* chain) +{ + /* wolfSSL_sk_dup takes care of doing a deep copy */ + return wolfSSL_sk_dup(chain); +} +#endif #ifdef WOLFSSL_ALT_CERT_CHAINS @@ -45649,14 +45883,14 @@ int wolfSSL_sk_X509_NAME_push(WOLF_STACK_OF(WOLFSSL_X509_NAME)* sk, WOLFSSL_ENTER("wolfSSL_sk_X509_NAME_push"); if (sk == NULL || name == NULL) { - return BAD_FUNC_ARG; + return WOLFSSL_FAILURE; } /* no previous values in stack */ if (sk->data.name == NULL) { sk->data.name = name; sk->num += 1; - return 0; + return WOLFSSL_SUCCESS; } /* stack already has value(s) create a new node and add more */ @@ -45664,7 +45898,7 @@ int wolfSSL_sk_X509_NAME_push(WOLF_STACK_OF(WOLFSSL_X509_NAME)* sk, DYNAMIC_TYPE_OPENSSL); if (node == NULL) { WOLFSSL_MSG("Memory error"); - return MEMORY_E; + return WOLFSSL_FAILURE; } XMEMSET(node, 0, sizeof(WOLFSSL_STACK)); @@ -45676,7 +45910,7 @@ int wolfSSL_sk_X509_NAME_push(WOLF_STACK_OF(WOLFSSL_X509_NAME)* sk, sk->data.name = name; sk->num += 1; - return 0; + return WOLFSSL_SUCCESS; } /* return index of found, or negative to indicate not found */ @@ -45698,6 +45932,18 @@ int wolfSSL_sk_X509_NAME_find(const WOLF_STACK_OF(WOLFSSL_X509_NAME) *sk, return -1; } + +void* wolfSSL_sk_X509_OBJECT_value(WOLF_STACK_OF(WOLFSSL_X509_OBJECT)* sk, int i) +{ + WOLFSSL_ENTER("wolfSSL_sk_X509_OBJECT_value"); + for (; sk != NULL && i > 0; i--) + sk = sk->next; + + if (i != 0 || sk == NULL) + return NULL; + return sk->data.x509_obj; +} + int wolfSSL_sk_X509_OBJECT_num(const WOLF_STACK_OF(WOLFSSL_X509_OBJECT) *s) { WOLFSSL_ENTER("wolfSSL_sk_X509_OBJECT_num"); @@ -46160,6 +46406,42 @@ void wolfSSL_THREADID_set_numeric(void* id, unsigned long val) } #endif +#ifdef OPENSSL_ALL +WOLFSSL_X509_LOOKUP_TYPE wolfSSL_X509_OBJECT_get_type( + const WOLFSSL_X509_OBJECT* obj) +{ + if (obj != NULL) + return obj->type; + else + return WOLFSSL_X509_LU_NONE; +} + +WOLFSSL_X509_OBJECT* wolfSSL_X509_OBJECT_new(void) +{ + WOLFSSL_X509_OBJECT* ret = (WOLFSSL_X509_OBJECT*) + XMALLOC(sizeof(WOLFSSL_X509_OBJECT), NULL, DYNAMIC_TYPE_OPENSSL); + if (ret != NULL) + XMEMSET(ret, 0, sizeof(WOLFSSL_X509_OBJECT)); + return ret; +} + +void wolfSSL_X509_OBJECT_free(WOLFSSL_X509_OBJECT *obj) +{ + WOLFSSL_ENTER("wolfSSL_X509_OBJECT_free"); + if (obj != NULL) { + if (obj->type == WOLFSSL_X509_LU_X509) { + wolfSSL_X509_free(obj->data.x509); + } + else { + /* We don't free as this will point to + * store->cm->crl which we don't own */ + WOLFSSL_MSG("Not free'ing CRL in WOLFSSL_X509_OBJECT"); + } + XFREE(obj, NULL, DYNAMIC_TYPE_OPENSSL); + } +} +#endif /* OPENSSL_ALL */ + #ifndef NO_WOLFSSL_STUB WOLFSSL_X509_OBJECT* wolfSSL_sk_X509_OBJECT_delete( WOLF_STACK_OF(WOLFSSL_X509_OBJECT)* sk, int i) @@ -46170,16 +46452,23 @@ WOLFSSL_X509_OBJECT* wolfSSL_sk_X509_OBJECT_delete( (void)i; return NULL; } - -void wolfSSL_X509_OBJECT_free(WOLFSSL_X509_OBJECT *a) -{ - WOLFSSL_ENTER("wolfSSL_X509_OBJECT_free"); - WOLFSSL_STUB("wolfSSL_X509_OBJECT_free"); - (void)a; -} - #endif +WOLFSSL_X509 *wolfSSL_X509_OBJECT_get0_X509(const WOLFSSL_X509_OBJECT *obj) +{ + if (obj != NULL && obj->type == WOLFSSL_X509_LU_X509) + return obj->data.x509; + else + return NULL; +} + +WOLFSSL_X509_CRL *wolfSSL_X509_OBJECT_get0_X509_CRL(WOLFSSL_X509_OBJECT *obj) +{ + if (obj != NULL && obj->type == WOLFSSL_X509_LU_CRL) + return obj->data.crl; + else + return NULL; +} #endif /* OPENSSL_ALL || (OPENSSL_EXTRA && (HAVE_STUNNEL || WOLFSSL_NGINX || HAVE_LIGHTY)) */ @@ -48278,8 +48567,27 @@ int wolfSSL_CTX_get_extra_chain_certs(WOLFSSL_CTX* ctx, WOLF_STACK_OF(X509)** ch return WOLFSSL_SUCCESS; } -int wolfSSL_CTX_set_tlsext_status_cb(WOLFSSL_CTX* ctx, - int(*cb)(WOLFSSL*, void*)) +int wolfSSL_CTX_get_tlsext_status_cb(WOLFSSL_CTX* ctx, tlsextStatusCb* cb) +{ + if (ctx == NULL || ctx->cm == NULL || cb == NULL) + return WOLFSSL_FAILURE; + +#if !defined(NO_WOLFSSL_SERVER) && (defined(HAVE_CERTIFICATE_STATUS_REQUEST) \ + || defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2)) + if (ctx->cm->ocsp_stapling == NULL) + return WOLFSSL_FAILURE; + + *cb = ctx->cm->ocsp_stapling->statusCb; +#else + (void)cb; + *cb = NULL; +#endif + + return WOLFSSL_SUCCESS; + +} + +int wolfSSL_CTX_set_tlsext_status_cb(WOLFSSL_CTX* ctx, tlsextStatusCb cb) { if (ctx == NULL || ctx->cm == NULL) return WOLFSSL_FAILURE; @@ -48318,10 +48626,13 @@ static int x509GetIssuerFromCM(WOLFSSL_X509 **issuer, WOLFSSL_CERT_MANAGER* cm, #else DecodedCert cert[1]; #endif - /* sanity check */ - if (cm == NULL || x == NULL || x->derCert == NULL) + + if (cm == NULL || x == NULL || x->derCert == NULL) { + WOLFSSL_MSG("No cert DER buffer or NULL cm. Defining " + "WOLFSSL_SIGNER_DER_CERT could solve the issue"); return WOLFSSL_FAILURE; - + } + #ifdef WOLFSSL_SMALL_STACK cert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), NULL, DYNAMIC_TYPE_DCERT); if (cert == NULL) @@ -49616,7 +49927,7 @@ WOLFSSL_BIGNUM *wolfSSL_ASN1_INTEGER_to_BN(const WOLFSSL_ASN1_INTEGER *ai, ret = GetInt(&mpi, ai->data, &idx, ai->dataMax); if (ret != 0) { - #ifdef WOLFSSL_QT + #if defined(WOLFSSL_QT) || defined(WOLFSSL_HAPROXY) ret = mp_init(&mpi); /* must init mpi */ if (ret != MP_OKAY) { return NULL; @@ -52046,7 +52357,7 @@ void wolfSSL_RSA_free(WOLFSSL_RSA* rsa) #ifdef HAVE_EX_DATA_CLEANUP_HOOKS wolfSSL_CRYPTO_cleanup_ex_data(&rsa->ex_data); #endif -#if defined(OPENSSL_EXTRA) || defined(OPENSSL_ALL) +#if defined(OPENSSL_EXTRA_X509_SMALL) || defined(OPENSSL_EXTRA) int doFree = 0; if (wc_LockMutex(&rsa->refMutex) != 0) { WOLFSSL_MSG("Couldn't lock rsa mutex"); @@ -52176,7 +52487,7 @@ WOLFSSL_RSA* wolfSSL_RSA_new(void) external->internal = key; external->inSet = 0; -#if defined(OPENSSL_EXTRA) || defined(OPENSSL_ALL) +#if defined(OPENSSL_EXTRA_X509_SMALL) || defined(OPENSSL_EXTRA) external->refCount = 1; wc_InitMutex(&external->refMutex); #endif @@ -52189,7 +52500,7 @@ WOLFSSL_RSA* wolfSSL_RSA_new(void) WOLFSSL_STACK* wolfSSL_sk_X509_new(void) { WOLFSSL_STACK* s = (WOLFSSL_STACK*)XMALLOC(sizeof(WOLFSSL_STACK), NULL, - DYNAMIC_TYPE_X509); + DYNAMIC_TYPE_OPENSSL); if (s != NULL) { XMEMSET(s, 0, sizeof(*s)); s->type = STACK_TYPE_X509; @@ -52200,6 +52511,41 @@ WOLFSSL_STACK* wolfSSL_sk_X509_new(void) #endif #ifdef OPENSSL_ALL + +WOLFSSL_STACK* wolfSSL_sk_X509_OBJECT_new(void) +{ + WOLFSSL_STACK* s = (WOLFSSL_STACK*)XMALLOC(sizeof(WOLFSSL_STACK), NULL, + DYNAMIC_TYPE_OPENSSL); + WOLFSSL_ENTER("wolfSSL_sk_X509_OBJECT_new"); + if (s != NULL) { + XMEMSET(s, 0, sizeof(*s)); + s->type = STACK_TYPE_X509_OBJ; + } + return s; +} + +void wolfSSL_sk_X509_OBJECT_free(WOLFSSL_STACK* s) +{ + WOLFSSL_ENTER("wolfSSL_sk_X509_OBJECT_free"); + while (s != NULL) { + WOLFSSL_STACK* next = s->next; + wolfSSL_X509_OBJECT_free(s->data.x509_obj); + XFREE(s, NULL, DYNAMIC_TYPE_OPENSSL); + s = next; + } +} + +int wolfSSL_sk_X509_OBJECT_push(WOLFSSL_STACK* sk, WOLFSSL_X509_OBJECT* obj) +{ + WOLFSSL_ENTER("wolfSSL_sk_X509_OBJECT_push"); + + if (sk == NULL || obj == NULL) { + return WOLFSSL_FAILURE; + } + + return wolfSSL_sk_push(sk, obj); +} + #ifndef NO_BIO int wolfSSL_PEM_write_bio_PKCS8PrivateKey(WOLFSSL_BIO* bio, WOLFSSL_EVP_PKEY* pkey, @@ -55350,6 +55696,11 @@ void wolfSSL_X509_STORE_free(WOLFSSL_X509_STORE* store) wolfSSL_CertManagerFree(store->cm); store->cm = NULL; } +#ifdef OPENSSL_ALL + if (store->objs != NULL) { + wolfSSL_sk_X509_OBJECT_free(store->objs); + } +#endif #if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL) if (store->param != NULL) { XFREE(store->param, NULL, DYNAMIC_TYPE_OPENSSL); @@ -55651,25 +56002,87 @@ int wolfSSL_X509_CA_num(WOLFSSL_X509_STORE* store) return cnt_ret; } -#endif /* OPENSSL_EXTRA */ - -#if defined(OPENSSL_ALL) || (defined(OPENSSL_EXTRA) && (defined(HAVE_STUNNEL) || \ - defined(WOLFSSL_NGINX) || defined(HAVE_LIGHTY) || \ - defined(WOLFSSL_HAPROXY) || defined(WOLFSSL_OPENSSH))) - -#ifndef NO_WOLFSSL_STUB +#ifdef OPENSSL_ALL WOLF_STACK_OF(WOLFSSL_X509_OBJECT)* wolfSSL_X509_STORE_get0_objects( WOLFSSL_X509_STORE* store) { + WOLFSSL_STACK* ret = NULL; + WOLFSSL_STACK* cert_stack = NULL; + WOLFSSL_X509* x509 = NULL; WOLFSSL_ENTER("wolfSSL_X509_STORE_get0_objects"); - WOLFSSL_STUB("wolfSSL_X509_STORE_get0_objects"); - (void)store; + + if (store == NULL || store->cm == NULL) { + WOLFSSL_MSG("Missing or empty store"); + return NULL; + } + + if (store->objs != NULL) { + if (wolfSSL_sk_X509_OBJECT_num(store->objs) == 0) { + /* Let's try generating the stack again */ + wolfSSL_sk_X509_OBJECT_free(store->objs); + store->objs = NULL; + } + else + return store->objs; + } + + if ((ret = wolfSSL_sk_X509_OBJECT_new()) == NULL) { + WOLFSSL_MSG("wolfSSL_sk_X509_OBJECT_new error"); + goto err_cleanup; + } + +#ifdef WOLFSSL_SIGNER_DER_CERT + cert_stack = wolfSSL_CertManagerGetCerts(store->cm); + /* wolfSSL_sk_X509_pop checks for NULL */ + while ((x509 = wolfSSL_sk_X509_pop(cert_stack)) != NULL) { + WOLFSSL_X509_OBJECT* obj = wolfSSL_X509_OBJECT_new(); + if (obj == NULL) { + WOLFSSL_MSG("wolfSSL_X509_OBJECT_new error"); + goto err_cleanup; + } + if (wolfSSL_sk_X509_OBJECT_push(ret, obj) != WOLFSSL_SUCCESS) { + WOLFSSL_MSG("wolfSSL_sk_X509_OBJECT_push error"); + wolfSSL_X509_OBJECT_free(obj); + goto err_cleanup; + } + obj->type = WOLFSSL_X509_LU_X509; + obj->data.x509 = x509; + } +#endif + +#ifdef HAVE_CRL + if (store->cm->crl != NULL) { + WOLFSSL_X509_OBJECT* obj = wolfSSL_X509_OBJECT_new(); + if (obj == NULL) { + WOLFSSL_MSG("wolfSSL_X509_OBJECT_new error"); + goto err_cleanup; + } + if (wolfSSL_sk_X509_OBJECT_push(ret, obj) != WOLFSSL_SUCCESS) { + WOLFSSL_MSG("wolfSSL_sk_X509_OBJECT_push error"); + wolfSSL_X509_OBJECT_free(obj); + goto err_cleanup; + } + obj->type = WOLFSSL_X509_LU_CRL; + obj->data.crl = store->cm->crl; + } +#endif + + if (cert_stack) + wolfSSL_sk_X509_free(cert_stack); + store->objs = ret; + return ret; +err_cleanup: + if (ret) + wolfSSL_sk_X509_OBJECT_free(ret); + if (cert_stack) + wolfSSL_sk_X509_free(cert_stack); + if (x509) + wolfSSL_X509_free(x509); return NULL; } -#endif /* NO_WOLFSSL_STUB */ +#endif /* OPENSSL_ALL */ -#endif /* OPENSSL_ALL || (OPENSSL_EXTRA && HAVE_STUNNEL) || WOLFSSL_NGINX || - * HAVE_LIGHTY || WOLFSSL_HAPROXY || WOLFSSL_OPENSSH */ +#endif /* OPENSSL_EXTRA */ /******************************************************************************* * END OF X509_STORE APIs diff --git a/src/tls13.c b/src/tls13.c index 2d4aa1ffa..b3845c922 100644 --- a/src/tls13.c +++ b/src/tls13.c @@ -4626,11 +4626,19 @@ int DoTls13ClientHello(WOLFSSL* ssl, const byte* input, word32* inOutIdx, if (!ssl->options.downgrade) { WOLFSSL_MSG("Client trying to connect with lesser version than " "TLS v1.3"); +#ifdef OPENSSL_EXTRA + SendAlert(ssl, alert_fatal, handshake_failure); +#endif ERROR_OUT(VERSION_ERROR, exit_dch); } - if (args->pv.minor < ssl->options.minDowngrade) + if (args->pv.minor < ssl->options.minDowngrade) { + WOLFSSL_MSG("\tversion below minimum allowed, fatal error"); +#ifdef OPENSSL_EXTRA + SendAlert(ssl, alert_fatal, handshake_failure); +#endif ERROR_OUT(VERSION_ERROR, exit_dch); + } ret = HashInput(ssl, input + args->begin, helloSz); if (ret == 0) { diff --git a/src/wolfio.c b/src/wolfio.c index 4345d7064..5e634eab2 100644 --- a/src/wolfio.c +++ b/src/wolfio.c @@ -180,6 +180,12 @@ int BioReceive(WOLFSSL* ssl, char* buf, int sz, void* ctx) return recvd; } + /* If retry and read flags are set, return WANT_READ */ + if ((ssl->biord->flags & WOLFSSL_BIO_FLAG_READ) && + (ssl->biord->flags & WOLFSSL_BIO_FLAG_RETRY)) { + return WOLFSSL_CBIO_ERR_WANT_READ; + } + WOLFSSL_MSG("BIO general error"); return WOLFSSL_CBIO_ERR_GENERAL; } @@ -211,13 +217,20 @@ int BioSend(WOLFSSL* ssl, char *buf, int sz, void *ctx) } sent = wolfSSL_BIO_write(ssl->biowr, buf, sz); - if (sent < 0) { + if (sent <= 0) { if (ssl->biowr->type == WOLFSSL_BIO_SOCKET) { #ifdef USE_WOLFSSL_IO sent = TranslateIoError(sent); #endif return sent; } + + /* If retry and write flags are set, return WANT_WRITE */ + if ((ssl->biord->flags & WOLFSSL_BIO_FLAG_WRITE) && + (ssl->biord->flags & WOLFSSL_BIO_FLAG_RETRY)) { + return WOLFSSL_CBIO_ERR_WANT_WRITE; + } + return WOLFSSL_CBIO_ERR_GENERAL; } (void)ctx; diff --git a/tests/api.c b/tests/api.c index ad2c4849c..ab349ae50 100644 --- a/tests/api.c +++ b/tests/api.c @@ -1105,13 +1105,23 @@ static int test_cm_load_ca_file(const char* ca_cert_file) /* normal test */ ret = test_cm_load_ca_buffer(cert_buf, cert_sz, WOLFSSL_FILETYPE_PEM); - if (ret == 0) { + if (ret == WOLFSSL_SUCCESS) { /* test including null terminator in length */ - ret = test_cm_load_ca_buffer(cert_buf, cert_sz+1, WOLFSSL_FILETYPE_PEM); + byte* tmp = (byte*)realloc(cert_buf, cert_sz+1); + if (tmp == NULL) { + ret = MEMORY_E; + } + else { + cert_buf = tmp; + cert_buf[cert_sz] = '\0'; + ret = test_cm_load_ca_buffer(cert_buf, cert_sz+1, + WOLFSSL_FILETYPE_PEM); + } + } #if defined(WOLFSSL_PEM_TO_DER) - if (ret == 0) { + if (ret == WOLFSSL_SUCCESS) { /* test loading DER */ ret = wc_PemToDer(cert_buf, cert_sz, CA_TYPE, &pDer, NULL, NULL, NULL); if (ret == 0 && pDer != NULL) { @@ -1337,8 +1347,11 @@ static int test_wolfSSL_CertManagerLoadCABuffer(void) #ifdef NO_RSA AssertIntEQ(ret, ASN_UNKNOWN_OID_E); #else - #if !(WOLFSSL_LOAD_VERIFY_DEFAULT_FLAGS & WOLFSSL_LOAD_FLAG_DATE_ERR_OKAY) + #if !(WOLFSSL_LOAD_VERIFY_DEFAULT_FLAGS & WOLFSSL_LOAD_FLAG_DATE_ERR_OKAY) && \ + !defined(OPENSSL_COMPATIBLE_DEFAULTS) AssertIntEQ(ret, ASN_AFTER_DATE_E); + #else + AssertIntEQ(ret, WOLFSSL_SUCCESS); #endif #endif #endif @@ -1687,7 +1700,12 @@ static void test_wolfSSL_CTX_load_verify_locations_ex(void) WOLFSSL_LOAD_FLAG_NONE)); /* test expired CA */ - AssertTrue(WOLFSSL_SUCCESS != + AssertTrue( +#ifndef OPENSSL_COMPATIBLE_DEFAULTS + WOLFSSL_SUCCESS != +#else + WOLFSSL_SUCCESS == +#endif wolfSSL_CTX_load_verify_locations_ex(ctx, ca_expired_cert, NULL, WOLFSSL_LOAD_FLAG_NONE)); AssertTrue(WOLFSSL_SUCCESS == @@ -1731,7 +1749,12 @@ static void test_wolfSSL_CTX_load_verify_buffer_ex(void) XFCLOSE(fp); /* test expired CA failure */ - AssertTrue(WOLFSSL_SUCCESS != + AssertTrue( +#ifndef OPENSSL_COMPATIBLE_DEFAULTS + WOLFSSL_SUCCESS != +#else + WOLFSSL_SUCCESS == +#endif wolfSSL_CTX_load_verify_buffer_ex(ctx, ca_expired_cert, sizeof_ca_expired_cert, WOLFSSL_FILETYPE_ASN1, 0, WOLFSSL_LOAD_FLAG_NONE)); @@ -2033,7 +2056,7 @@ static void test_server_wolfSSL_new(void) /* invalid context */ AssertNull(ssl = wolfSSL_new(NULL)); -#if !defined(WOLFSSL_SESSION_EXPORT) && !defined(WOLFSSL_QT) +#if !defined(WOLFSSL_SESSION_EXPORT) && !defined(WOLFSSL_QT) && !defined(OPENSSL_EXTRA) AssertNull(ssl = wolfSSL_new(ctx_nocert)); #endif @@ -27216,6 +27239,26 @@ static void test_wolfSSL_X509_NAME(void) #endif /* defined(OPENSSL_EXTRA) && !defined(NO_DES3) */ } +static void test_wolfSSL_X509_NAME_hash(void) +{ +#if defined(OPENSSL_EXTRA) && !defined(NO_FILESYSTEM) && !defined(NO_RSA) && !defined(NO_SHA) + BIO* bio; + X509* x509 = NULL; + + printf(testingFmt, "wolfSSL_X509_NAME_hash"); + + AssertNotNull(bio = BIO_new(BIO_s_file())); + AssertIntGT(BIO_read_filename(bio, svrCertFile), 0); + AssertNotNull(PEM_read_bio_X509(bio, &x509, NULL, NULL)); + AssertIntEQ(X509_NAME_hash(X509_get_subject_name(x509)), 0xF6CF410E); + AssertIntEQ(X509_NAME_hash(X509_get_issuer_name(x509)), 0x677DD39A); + + X509_free(x509); + BIO_free(bio); + printf(resultFmt, passed); +#endif +} + #ifndef NO_BIO static void test_wolfSSL_X509_INFO(void) { @@ -29397,6 +29440,11 @@ static void test_wolfSSL_CTX_add_extra_chain_cert(void) char clientFile[] = "./certs/client-cert.pem"; SSL_CTX* ctx; X509* x509; + BIO *bio = NULL; + X509 *cert = NULL; + X509 *ca; + STACK_OF(X509) *chain = NULL; + STACK_OF(X509) *chain2 = NULL; printf(testingFmt, "wolfSSL_CTX_add_extra_chain_cert()"); @@ -29455,7 +29503,29 @@ static void test_wolfSSL_CTX_add_extra_chain_cert(void) AssertNull(SSL_CTX_get_default_passwd_cb(ctx)); AssertNull(SSL_CTX_get_default_passwd_cb_userdata(ctx)); #endif + SSL_CTX_free(ctx); +#ifndef NO_WOLFSSL_SERVER + AssertNotNull(ctx = SSL_CTX_new(wolfSSLv23_server_method())); +#else + AssertNotNull(ctx = SSL_CTX_new(wolfSSLv23_client_method())); +#endif + /* Test haproxy use case */ + AssertNotNull(bio = BIO_new_file(svrCertFile, "r")); + /* Read Certificate */ + AssertNotNull(cert = PEM_read_bio_X509_AUX(bio, NULL, NULL, NULL)); + AssertNotNull(ca = PEM_read_bio_X509(bio, NULL, NULL, NULL)); + AssertNotNull(chain = sk_X509_new_null()); + AssertIntEQ(sk_X509_push(chain, ca), 1); + AssertNotNull(chain2 = X509_chain_up_ref(chain)); + AssertNotNull(ca = sk_X509_shift(chain2)); + AssertIntEQ(SSL_CTX_use_certificate(ctx, cert), 1); + AssertIntEQ(SSL_CTX_add_extra_chain_cert(ctx, ca), 1); + + BIO_free(bio); + X509_free(cert); + sk_X509_pop_free(chain, X509_free); + sk_X509_pop_free(chain2, X509_free); SSL_CTX_free(ctx); printf(resultFmt, passed); #endif /* defined(OPENSSL_EXTRA) && !defined(NO_CERTS) && \ @@ -30634,6 +30704,78 @@ static void test_wolfSSL_X509_STORE_load_locations(void) #endif } +static void test_X509_STORE_get0_objects(void) +{ +#if defined(OPENSSL_ALL) && !defined(NO_FILESYSTEM) && !defined(NO_WOLFSSL_DIR) + X509_STORE *store; + X509_STORE *store_cpy; + SSL_CTX *ctx; + X509_OBJECT *obj; + STACK_OF(X509_OBJECT) *objs; + int i; + + printf(testingFmt, "wolfSSL_X509_STORE_get0_objects"); + + /* Setup store */ +#ifndef NO_WOLFSSL_SERVER + AssertNotNull(ctx = SSL_CTX_new(SSLv23_server_method())); +#else + AssertNotNull(ctx = SSL_CTX_new(SSLv23_client_method())); +#endif + AssertNotNull(store_cpy = X509_STORE_new()); + AssertNotNull(store = SSL_CTX_get_cert_store(ctx)); + AssertIntEQ(X509_STORE_load_locations(store, cliCertFile, NULL), WOLFSSL_SUCCESS); + AssertIntEQ(X509_STORE_load_locations(store, caCertFile, NULL), WOLFSSL_SUCCESS); + AssertIntEQ(X509_STORE_load_locations(store, svrCertFile, NULL), WOLFSSL_SUCCESS); +#ifdef HAVE_CRL + AssertIntEQ(X509_STORE_load_locations(store, NULL, crlPemDir), WOLFSSL_SUCCESS); +#endif + /* Store ready */ + + /* Similar to HaProxy ssl_set_cert_crl_file use case */ + AssertNotNull(objs = X509_STORE_get0_objects(store)); +#ifdef HAVE_CRL +#ifdef WOLFSSL_SIGNER_DER_CERT + AssertIntEQ(sk_X509_OBJECT_num(objs), 4); +#else + AssertIntEQ(sk_X509_OBJECT_num(objs), 1); +#endif +#else +#ifdef WOLFSSL_SIGNER_DER_CERT + AssertIntEQ(sk_X509_OBJECT_num(objs), 3); +#else + AssertIntEQ(sk_X509_OBJECT_num(objs), 0); +#endif +#endif + for (i = 0; i < sk_X509_OBJECT_num(objs); i++) { + obj = sk_X509_OBJECT_value(objs, i); + switch (X509_OBJECT_get_type(obj)) { + case X509_LU_X509: + AssertNotNull(X509_OBJECT_get0_X509(obj)); + AssertIntEQ(X509_STORE_add_cert(store_cpy, + X509_OBJECT_get0_X509(obj)), WOLFSSL_SUCCESS); + break; + case X509_LU_CRL: +#ifdef HAVE_CRL + AssertNotNull(X509_OBJECT_get0_X509_CRL(obj)); + AssertIntEQ(X509_STORE_add_crl(store_cpy, + X509_OBJECT_get0_X509_CRL(obj)), WOLFSSL_SUCCESS); + break; +#endif + case X509_LU_NONE: + default: + Fail(("X509_OBJECT_get_type should return x509 or crl " + "(when built with crl support)"), + ("Unrecognized X509_OBJECT type or none")); + } + } + + X509_STORE_free(store_cpy); + SSL_CTX_free(ctx); + printf(resultFmt, passed); +#endif +} + static void test_wolfSSL_BN(void) { #if defined(OPENSSL_EXTRA) && !defined(NO_ASN) @@ -38947,6 +39089,51 @@ static void test_wolfSSL_X509V3_EXT_get(void) { #endif } +static void test_wolfSSL_X509V3_EXT_nconf(void) +{ +#if defined (OPENSSL_ALL) + const char *ext_names[] = { + "subjectKeyIdentifier", + "authorityKeyIdentifier", + "subjectAltName", + "keyUsage", + }; + size_t ext_names_count = sizeof(ext_names)/sizeof(*ext_names); + int ext_nids[] = { + NID_subject_key_identifier, + NID_authority_key_identifier, + NID_subject_alt_name, + NID_key_usage, + }; + size_t ext_nids_count = sizeof(ext_nids)/sizeof(*ext_nids); + const char *ext_values[] = { + "hash", + "hash", + "DNS:example.com, IP:127.0.0.1", + "digitalSignature,keyEncipherment,dataEncipherment", + }; + size_t i; + + printf(testingFmt, "wolfSSL_X509V3_EXT_nconf()"); + + for (i = 0; i < ext_names_count; i++) { + X509_EXTENSION* ext = X509V3_EXT_nconf(NULL, NULL, ext_names[i], + ext_values[i]); + AssertNotNull(ext); + X509_EXTENSION_free(ext); + } + + for (i = 0; i < ext_nids_count; i++) { + X509_EXTENSION* ext = X509V3_EXT_nconf_nid(NULL, NULL, ext_nids[i], + ext_values[i]); + AssertNotNull(ext); + X509_EXTENSION_free(ext); + } + + printf(resultFmt, "passed"); +#endif +} + static void test_wolfSSL_X509V3_EXT(void) { #if !defined(NO_FILESYSTEM) && defined(OPENSSL_ALL) && !defined(NO_RSA) FILE* f; @@ -39434,11 +39621,12 @@ static void test_wolfSSL_i2d_PrivateKey(void) static void test_wolfSSL_OCSP_id_get0_info(void) { -#if defined(OPENSSL_ALL) && defined(HAVE_OCSP) && !defined(NO_FILESYSTEM) && \ - !defined(NO_RSA) +#if (defined(OPENSSL_ALL) || defined(WOLFSSL_HAPROXY)) && defined(HAVE_OCSP) && \ + !defined(NO_FILESYSTEM) || !defined(NO_RSA) X509* cert; X509* issuer; OCSP_CERTID* id; + OCSP_CERTID* id2; ASN1_STRING* name = NULL; ASN1_OBJECT* pmd = NULL; @@ -39455,6 +39643,8 @@ static void test_wolfSSL_OCSP_id_get0_info(void) id = OCSP_cert_to_id(NULL, cert, issuer); AssertNotNull(id); + id2 = OCSP_cert_to_id(NULL, cert, issuer); + AssertNotNull(id2); AssertIntEQ(OCSP_id_get0_info(NULL, NULL, NULL, NULL, NULL), 0); AssertIntEQ(OCSP_id_get0_info(NULL, NULL, NULL, NULL, id), 1); @@ -39470,10 +39660,19 @@ static void test_wolfSSL_OCSP_id_get0_info(void) /* compare serial number to one in cert, should be equal */ x509Int = X509_get_serialNumber(cert); AssertNotNull(x509Int); - AssertIntEQ(x509Int->dataMax, serial->dataMax); - AssertIntEQ(XMEMCMP(x509Int->data, serial->data, serial->dataMax), 0); + AssertIntEQ(x509Int->length, serial->length); + AssertIntEQ(XMEMCMP(x509Int->data, serial->data, serial->length), 0); + + /* test OCSP_id_cmp */ + AssertIntNE(OCSP_id_cmp(NULL, NULL), 0); + AssertIntNE(OCSP_id_cmp(id, NULL), 0); + AssertIntNE(OCSP_id_cmp(NULL, id2), 0); + AssertIntEQ(OCSP_id_cmp(id, id2), 0); + id->issuerHash[0] = ~id->issuerHash[0]; + AssertIntNE(OCSP_id_cmp(id, id2), 0); OCSP_CERTID_free(id); + OCSP_CERTID_free(id2); X509_free(cert); /* free's x509Int */ X509_free(issuer); @@ -39483,7 +39682,7 @@ static void test_wolfSSL_OCSP_id_get0_info(void) static void test_wolfSSL_i2d_OCSP_CERTID(void) { -#if defined(OPENSSL_ALL) && defined(HAVE_OCSP) +#if (defined(OPENSSL_ALL) || defined(WOLFSSL_HAPROXY)) && defined(HAVE_OCSP) WOLFSSL_OCSP_CERTID certId; byte* targetBuffer; byte* beginTargetBuffer; @@ -39536,6 +39735,21 @@ static void test_wolfSSL_i2d_OCSP_CERTID(void) #endif } +static void test_wolfSSL_OCSP_id_cmp(void) +{ +#if defined(OPENSSL_ALL) && defined(HAVE_OCSP) + OCSP_CERTID id1; + OCSP_CERTID id2; + printf(testingFmt, "wolfSSL_OCSP_id_cmp()"); + + XMEMSET(&id1, 0, sizeof(id1)); + XMEMSET(&id2, 0, sizeof(id2)); + AssertIntEQ(OCSP_id_cmp(&id1, &id2), 0); + + printf(resultFmt, passed); +#endif +} + static void test_wolfSSL_OCSP_SINGLERESP_get0_id(void) { #if defined(OPENSSL_ALL) && defined(HAVE_OCSP) @@ -43849,6 +44063,40 @@ static void test_SetTmpEC_DHE_Sz(void) #endif } +static void test_wolfSSL_CTX_get0_privatekey(void) +{ +#ifdef OPENSSL_ALL + WOLFSSL_CTX* ctx = NULL; + + printf(testingFmt, "wolfSSL_CTX_get0_privatekey()"); + +#ifndef NO_RSA + AssertNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_method())); + AssertNull(SSL_CTX_get0_privatekey(ctx)); + AssertTrue(wolfSSL_CTX_use_certificate_file(ctx, svrCertFile, + WOLFSSL_FILETYPE_PEM)); + AssertNull(SSL_CTX_get0_privatekey(ctx)); + AssertTrue(wolfSSL_CTX_use_PrivateKey_file(ctx, svrKeyFile, + WOLFSSL_FILETYPE_PEM)); + AssertNotNull(SSL_CTX_get0_privatekey(ctx)); + wolfSSL_CTX_free(ctx); +#endif +#ifdef HAVE_ECC + AssertNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_method())); + AssertNull(SSL_CTX_get0_privatekey(ctx)); + AssertTrue(wolfSSL_CTX_use_certificate_file(ctx, eccCertFile, + WOLFSSL_FILETYPE_PEM)); + AssertNull(SSL_CTX_get0_privatekey(ctx)); + AssertTrue(wolfSSL_CTX_use_PrivateKey_file(ctx, eccKeyFile, + WOLFSSL_FILETYPE_PEM)); + AssertNotNull(SSL_CTX_get0_privatekey(ctx)); + wolfSSL_CTX_free(ctx); +#endif + + printf(resultFmt, passed); +#endif +} + static void test_wolfSSL_dtls_set_mtu(void) { #if (defined(WOLFSSL_DTLS_MTU) || defined(WOLFSSL_SCTP)) && \ @@ -45088,6 +45336,7 @@ void ApiTest(void) test_wolfSSL_SetTmpDH_buffer(); test_wolfSSL_SetMinMaxDhKey_Sz(); test_SetTmpEC_DHE_Sz(); + test_wolfSSL_CTX_get0_privatekey(); test_wolfSSL_dtls_set_mtu(); test_wolfSSL_DH_get0_pqg(); #if !defined(NO_WOLFSSL_CLIENT) && !defined(NO_WOLFSSL_SERVER) && \ @@ -45143,6 +45392,7 @@ void ApiTest(void) /* compatibility tests */ test_wolfSSL_lhash(); test_wolfSSL_X509_NAME(); + test_wolfSSL_X509_NAME_hash(); #ifndef NO_BIO test_wolfSSL_X509_INFO(); #endif @@ -45218,6 +45468,7 @@ void ApiTest(void) test_wolfSSL_X509_STORE_CTX_get0_store(); test_wolfSSL_X509_STORE(); test_wolfSSL_X509_STORE_load_locations(); + test_X509_STORE_get0_objects(); test_wolfSSL_X509_load_crl_file(); test_wolfSSL_BN(); test_wolfSSL_CTX_get0_set1_param(); @@ -45333,6 +45584,7 @@ void ApiTest(void) test_wolfSSL_i2d_PrivateKey(); test_wolfSSL_OCSP_id_get0_info(); test_wolfSSL_i2d_OCSP_CERTID(); + test_wolfSSL_OCSP_id_cmp(); test_wolfSSL_OCSP_SINGLERESP_get0_id(); test_wolfSSL_OCSP_single_get0_status(); test_wolfSSL_OCSP_resp_count(); @@ -45417,6 +45669,7 @@ void ApiTest(void) #endif test_wolfSSL_RSA_verify(); test_wolfSSL_X509V3_EXT_get(); + test_wolfSSL_X509V3_EXT_nconf(); test_wolfSSL_X509V3_EXT(); test_wolfSSL_X509_get_ext(); test_wolfSSL_X509_get_ext_by_NID(); diff --git a/wolfssl/internal.h b/wolfssl/internal.h index 4f07d53a9..8a7e461bc 100644 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -1496,7 +1496,11 @@ enum Misc { MAX_WOLFSSL_FILE_SIZE = 1024ul * 1024ul * 4, /* 4 mb file size alloc limit */ #endif +#ifdef WOLFSSL_HAPROXY + MAX_X509_SIZE = 3072, /* max static x509 buffer size */ +#else MAX_X509_SIZE = 2048, /* max static x509 buffer size */ +#endif CERT_MIN_SIZE = 256, /* min PEM cert size with header/footer */ MAX_NTRU_PUB_KEY_SZ = 1027, /* NTRU max for now */ @@ -2799,6 +2803,9 @@ struct WOLFSSL_CTX { byte privateKeyLabel:1; int privateKeySz; int privateKeyDevId; +#ifdef OPENSSL_ALL + WOLFSSL_EVP_PKEY* privateKeyPKey; +#endif WOLFSSL_CERT_MANAGER* cm; /* our cert manager, ctx owns SSL will use */ #endif #ifdef KEEP_OUR_CERT @@ -3058,7 +3065,7 @@ struct WOLFSSL_CTX { WOLF_EVENT_QUEUE event_queue; #endif /* HAVE_WOLF_EVENT */ #ifdef HAVE_EXT_CACHE - WOLFSSL_SESSION*(*get_sess_cb)(WOLFSSL*, unsigned char*, int, int*); + WOLFSSL_SESSION*(*get_sess_cb)(WOLFSSL*, const unsigned char*, int, int*); int (*new_sess_cb)(WOLFSSL*, WOLFSSL_SESSION*); void (*rem_sess_cb)(WOLFSSL_CTX*, WOLFSSL_SESSION*); #endif @@ -3348,6 +3355,9 @@ struct WOLFSSL_SESSION { wolfSSL_Mutex refMutex; /* ref count mutex */ int refCount; /* reference count */ #endif +#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL) + byte peerVerifyRet; /* cert verify error */ +#endif #ifdef WOLFSSL_TLS13 word16 namedGroup; #endif @@ -3761,6 +3771,7 @@ typedef struct Arrays { #define STACK_TYPE_X509_INFO 11 #define STACK_TYPE_BY_DIR_entry 12 #define STACK_TYPE_BY_DIR_hash 13 +#define STACK_TYPE_X509_OBJ 14 struct WOLFSSL_STACK { unsigned long num; /* number of nodes in stack @@ -3788,6 +3799,7 @@ struct WOLFSSL_STACK { WOLFSSL_GENERAL_NAME* gn; WOLFSSL_BY_DIR_entry* dir_entry; WOLFSSL_BY_DIR_HASH* dir_hash; + WOLFSSL_X509_OBJECT* x509_obj; } data; void* heap; /* memory heap hint */ WOLFSSL_STACK* next; @@ -3865,7 +3877,7 @@ struct WOLFSSL_X509 { char certPolicies[MAX_CERTPOL_NB][MAX_CERTPOL_SZ]; int certPoliciesNb; #endif /* WOLFSSL_CERT_EXT */ -#if defined(OPENSSL_EXTRA) || defined(OPENSSL_ALL) +#if defined(OPENSSL_EXTRA_X509_SMALL) || defined(OPENSSL_EXTRA) wolfSSL_Mutex refMutex; /* ref count mutex */ int refCount; /* reference count */ #endif diff --git a/wolfssl/ocsp.h b/wolfssl/ocsp.h index acdad5120..81f2f638f 100644 --- a/wolfssl/ocsp.h +++ b/wolfssl/ocsp.h @@ -111,6 +111,7 @@ WOLFSSL_API int wolfSSL_i2d_OCSP_REQUEST_bio(WOLFSSL_BIO* out, WOLFSSL_API int wolfSSL_i2d_OCSP_CERTID(WOLFSSL_OCSP_CERTID *, unsigned char **); WOLFSSL_API const WOLFSSL_OCSP_CERTID* wolfSSL_OCSP_SINGLERESP_get0_id(const WOLFSSL_OCSP_SINGLERESP *single); +WOLFSSL_API int wolfSSL_OCSP_id_cmp(WOLFSSL_OCSP_CERTID *a, WOLFSSL_OCSP_CERTID *b); WOLFSSL_API int wolfSSL_OCSP_single_get0_status(WOLFSSL_OCSP_SINGLERESP *single, int *reason, WOLFSSL_ASN1_TIME **revtime, diff --git a/wolfssl/openssl/conf.h b/wolfssl/openssl/conf.h index a71bc07b5..9e233a568 100644 --- a/wolfssl/openssl/conf.h +++ b/wolfssl/openssl/conf.h @@ -75,6 +75,11 @@ WOLFSSL_API WOLFSSL_CONF_VALUE *wolfSSL_CONF_new_section(WOLFSSL_CONF *conf, WOLFSSL_API WOLFSSL_CONF_VALUE *wolfSSL_CONF_get_section(WOLFSSL_CONF *conf, const char *section); +WOLFSSL_API WOLFSSL_X509_EXTENSION* wolfSSL_X509V3_EXT_nconf_nid(WOLFSSL_CONF* conf, + WOLFSSL_X509V3_CTX *ctx, int nid, const char *value); +WOLFSSL_API WOLFSSL_X509_EXTENSION* wolfSSL_X509V3_EXT_nconf(WOLFSSL_CONF *conf, + WOLFSSL_X509V3_CTX *ctx, const char *sName, const char *value); + #define sk_CONF_VALUE_new wolfSSL_sk_CONF_VALUE_new #define sk_CONF_VALUE_free wolfSSL_sk_CONF_VALUE_free #define sk_CONF_VALUE_pop_free(a,b) wolfSSL_sk_CONF_VALUE_free(a) @@ -95,6 +100,8 @@ WOLFSSL_API WOLFSSL_CONF_VALUE *wolfSSL_CONF_get_section(WOLFSSL_CONF *conf, #define _CONF_new_section wolfSSL_CONF_new_section #define _CONF_get_section wolfSSL_CONF_get_section +#define X509V3_EXT_nconf_nid wolfSSL_X509V3_EXT_nconf_nid +#define X509V3_EXT_nconf wolfSSL_X509V3_EXT_nconf #define X509V3_conf_free wolfSSL_X509V3_conf_free #endif /* OPENSSL_EXTRA */ diff --git a/wolfssl/openssl/ocsp.h b/wolfssl/openssl/ocsp.h index bc70f72d9..b1e9166d8 100644 --- a/wolfssl/openssl/ocsp.h +++ b/wolfssl/openssl/ocsp.h @@ -79,6 +79,7 @@ #define i2d_OCSP_CERTID wolfSSL_i2d_OCSP_CERTID #define OCSP_SINGLERESP_get0_id wolfSSL_OCSP_SINGLERESP_get0_id +#define OCSP_id_cmp wolfSSL_OCSP_id_cmp #define OCSP_single_get0_status wolfSSL_OCSP_single_get0_status #define OCSP_resp_count wolfSSL_OCSP_resp_count #define OCSP_resp_get0 wolfSSL_OCSP_resp_get0 diff --git a/wolfssl/openssl/opensslv.h b/wolfssl/openssl/opensslv.h index 1a89b5915..b509793cf 100644 --- a/wolfssl/openssl/opensslv.h +++ b/wolfssl/openssl/opensslv.h @@ -35,9 +35,10 @@ #define OPENSSL_VERSION_NUMBER 0x10100000L #elif defined(WOLFSSL_QT) #define OPENSSL_VERSION_NUMBER 0x10101000L +#elif defined(WOLFSSL_HAPROXY) + #define OPENSSL_VERSION_NUMBER 0x1010000fL #elif defined(OPENSSL_ALL) || defined(HAVE_STUNNEL) || defined(HAVE_LIGHTY) || \ - defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY) || \ - defined(WOLFSSL_OPENSSH) || defined(WOLFSSL_OPENVPN) + defined(WOLFSSL_NGINX) || defined(WOLFSSL_OPENSSH) || defined(WOLFSSL_OPENVPN) /* version number can be increased for Lighty after compatibility for ECDH is added */ #define OPENSSL_VERSION_NUMBER 0x10001040L diff --git a/wolfssl/openssl/rsa.h b/wolfssl/openssl/rsa.h index fcbaa6c81..b418efdce 100644 --- a/wolfssl/openssl/rsa.h +++ b/wolfssl/openssl/rsa.h @@ -86,7 +86,7 @@ typedef struct WOLFSSL_RSA { #if defined(HAVE_EX_DATA) WOLFSSL_CRYPTO_EX_DATA ex_data; /* external data */ #endif -#if defined(OPENSSL_EXTRA) || defined(OPENSSL_ALL) +#if defined(OPENSSL_EXTRA_X509_SMALL) || defined(OPENSSL_EXTRA) wolfSSL_Mutex refMutex; /* ref count mutex */ int refCount; /* reference count */ #endif diff --git a/wolfssl/openssl/ssl.h b/wolfssl/openssl/ssl.h index e8f317a42..2cce7af2d 100644 --- a/wolfssl/openssl/ssl.h +++ b/wolfssl/openssl/ssl.h @@ -123,11 +123,15 @@ typedef WOLFSSL_GENERAL_NAME GENERAL_NAME; typedef WOLFSSL_COMP_METHOD COMP_METHOD; typedef WOLFSSL_COMP SSL_COMP; typedef WOLFSSL_X509_REVOKED X509_REVOKED; +typedef WOLFSSL_X509_LOOKUP_TYPE X509_LOOKUP_TYPE; typedef WOLFSSL_X509_OBJECT X509_OBJECT; typedef WOLFSSL_X509_STORE X509_STORE; typedef WOLFSSL_X509_STORE_CTX X509_STORE_CTX; typedef WOLFSSL_X509_VERIFY_PARAM X509_VERIFY_PARAM; +typedef int OSSL_HANDSHAKE_STATE; +#define TLS_ST_BEFORE 0 /* NULL_STATE from enum states */ + #define EVP_CIPHER_INFO EncryptedInfo #define STACK_OF(x) WOLFSSL_STACK @@ -440,19 +444,17 @@ typedef STACK_OF(ACCESS_DESCRIPTION) AUTHORITY_INFO_ACCESS; #define X509_REQ_get_pubkey wolfSSL_X509_get_pubkey #define X509_get_notBefore wolfSSL_X509_get_notBefore #define X509_get0_notBefore wolfSSL_X509_get_notBefore -#define X509_getm_notBefore wolfSSL_X509_get_notBefore +#define X509_getm_notBefore (ASN1_TIME*)wolfSSL_X509_get_notBefore #define X509_get_notAfter wolfSSL_X509_get_notAfter #define X509_get0_notAfter wolfSSL_X509_get_notAfter -#define X509_getm_notAfter wolfSSL_X509_get_notAfter +#define X509_getm_notAfter (ASN1_TIME*)wolfSSL_X509_get_notAfter #define X509_get_serialNumber wolfSSL_X509_get_serialNumber #define X509_get0_pubkey_bitstr wolfSSL_X509_get0_pubkey_bitstr #define X509_get_ex_new_index wolfSSL_X509_get_ex_new_index #define X509_get_ex_data wolfSSL_X509_get_ex_data #define X509_set_ex_data wolfSSL_X509_set_ex_data #define X509_get1_ocsp wolfSSL_X509_get1_ocsp -#ifndef WOLFSSL_HAPROXY #define X509_get_version wolfSSL_X509_get_version -#endif #define X509_get_signature_nid wolfSSL_X509_get_signature_nid #define X509_set_subject_name wolfSSL_X509_set_subject_name #define X509_set_issuer_name wolfSSL_X509_set_issuer_name @@ -500,6 +502,10 @@ typedef STACK_OF(ACCESS_DESCRIPTION) AUTHORITY_INFO_ACCESS; #define sk_X509_pop_free wolfSSL_sk_X509_pop_free #define sk_X509_dup wolfSSL_sk_dup #define sk_X509_free wolfSSL_sk_X509_free +#define X509_chain_up_ref wolfSSL_X509_chain_up_ref + +#define sk_X509_OBJECT_new wolfSSL_sk_X509_OBJECT_new +#define sk_X509_OBJECT_free wolfSSL_sk_X509_OBJECT_free #define sk_X509_EXTENSION_num wolfSSL_sk_X509_EXTENSION_num #define sk_X509_EXTENSION_value wolfSSL_sk_X509_EXTENSION_value @@ -535,6 +541,7 @@ typedef STACK_OF(ACCESS_DESCRIPTION) AUTHORITY_INFO_ACCESS; #define X509_NAME_add_entry_by_txt wolfSSL_X509_NAME_add_entry_by_txt #define X509_NAME_add_entry_by_NID wolfSSL_X509_NAME_add_entry_by_NID #define X509_NAME_delete_entry wolfSSL_X509_NAME_delete_entry +#define X509_NAME_hash wolfSSL_X509_NAME_hash #define X509_NAME_oneline wolfSSL_X509_NAME_oneline #define X509_NAME_get_index_by_NID wolfSSL_X509_NAME_get_index_by_NID #define X509_NAME_print_ex wolfSSL_X509_NAME_print_ex @@ -549,6 +556,7 @@ typedef STACK_OF(ACCESS_DESCRIPTION) AUTHORITY_INFO_ACCESS; #define sk_ACCESS_DESCRIPTION_value wolfSSL_sk_ACCESS_DESCRIPTION_value #define sk_X509_NAME_new wolfSSL_sk_X509_NAME_new +#define sk_X509_NAME_new_null() wolfSSL_sk_X509_NAME_new(NULL) #define sk_X509_NAME_push wolfSSL_sk_X509_NAME_push #define sk_X509_NAME_find wolfSSL_sk_X509_NAME_find #define sk_X509_NAME_set_cmp_func wolfSSL_sk_X509_NAME_set_cmp_func @@ -668,6 +676,9 @@ wolfSSL_X509_STORE_set_verify_cb((WOLFSSL_X509_STORE *)(s), (WOLFSSL_X509_STORE_ #define X509_OBJECT_free_contents wolfSSL_X509_OBJECT_free_contents +#define X509_OBJECT_get0_X509 wolfSSL_X509_OBJECT_get0_X509 +#define X509_OBJECT_get0_X509_CRL wolfSSL_X509_OBJECT_get0_X509_CRL + #define X509_check_purpose(...) 0 #define OCSP_parse_url wolfSSL_OCSP_parse_url @@ -787,6 +798,8 @@ wolfSSL_X509_STORE_set_verify_cb((WOLFSSL_X509_STORE *)(s), (WOLFSSL_X509_STORE_ #define ASN1_STRING_set_default_mask_asc(...) 1 #endif +#define ASN1_OCTET_STRING_free wolfSSL_ASN1_STRING_free + #define ASN1_PRINTABLE_type(...) V_ASN1_PRINTABLESTRING #define ASN1_UTCTIME_pr wolfSSL_ASN1_UTCTIME_pr @@ -899,6 +912,7 @@ wolfSSL_X509_STORE_set_verify_cb((WOLFSSL_X509_STORE *)(s), (WOLFSSL_X509_STORE_ #define ERR_error_string wolfSSL_ERR_error_string #define ERR_error_string_n wolfSSL_ERR_error_string_n #define ERR_reason_error_string wolfSSL_ERR_reason_error_string +#define ERR_func_error_string wolfSSL_ERR_func_error_string #define ERR_load_BIO_strings wolfSSL_ERR_load_BIO_strings #ifndef WOLFCRYPT_ONLY @@ -922,6 +936,7 @@ wolfSSL_X509_STORE_set_verify_cb((WOLFSSL_X509_STORE *)(s), (WOLFSSL_X509_STORE_ #define SSL_CTX_clear_options wolfSSL_CTX_clear_options #define SSL_CTX_check_private_key wolfSSL_CTX_check_private_key +#define SSL_CTX_get0_privatekey wolfSSL_CTX_get0_privatekey #define SSL_check_private_key wolfSSL_check_private_key #define SSL_CTX_set_mode wolfSSL_CTX_set_mode @@ -1098,12 +1113,16 @@ wolfSSL_X509_STORE_set_verify_cb((WOLFSSL_X509_STORE *)(s), (WOLFSSL_X509_STORE_ #define SSL_CTX_set_min_proto_version wolfSSL_CTX_set_min_proto_version #define SSL_CTX_set_max_proto_version wolfSSL_CTX_set_max_proto_version +#define SSL_set_min_proto_version wolfSSL_set_min_proto_version +#define SSL_set_max_proto_version wolfSSL_set_max_proto_version #define SSL_CTX_get_min_proto_version wolfSSL_CTX_get_min_proto_version #define SSL_get_tlsext_status_exts wolfSSL_get_tlsext_status_exts #define SSL_CTX_get_tlsext_ticket_keys wolfSSL_CTX_get_tlsext_ticket_keys #define SSL_CTX_set_tlsext_ticket_keys wolfSSL_CTX_set_tlsext_ticket_keys +#define SSL_CTX_get_tlsext_status_cb wolfSSL_CTX_get_tlsext_status_cb +#define SSL_CTX_set_tlsext_status_cb wolfSSL_CTX_set_tlsext_status_cb #define SSL_CTRL_CLEAR_NUM_RENEGOTIATIONS 11 #define SSL_CTRL_GET_TOTAL_RENEGOTIATIONS 12 @@ -1220,9 +1239,9 @@ wolfSSL_X509_STORE_set_verify_cb((WOLFSSL_X509_STORE *)(s), (WOLFSSL_X509_STORE_ #define SSL3_AL_FATAL 2 #define SSL_TLSEXT_ERR_OK 0 -#define SSL_TLSEXT_ERR_ALERT_FATAL alert_fatal -#define SSL_TLSEXT_ERR_ALERT_WARNING alert_warning -#define SSL_TLSEXT_ERR_NOACK alert_warning +#define SSL_TLSEXT_ERR_ALERT_WARNING warning_return +#define SSL_TLSEXT_ERR_ALERT_FATAL fatal_return +#define SSL_TLSEXT_ERR_NOACK noack_return #define TLSEXT_NAMETYPE_host_name WOLFSSL_SNI_HOST_NAME #define SSL_set_tlsext_host_name wolfSSL_set_tlsext_host_name @@ -1236,6 +1255,7 @@ wolfSSL_X509_STORE_set_verify_cb((WOLFSSL_X509_STORE *)(s), (WOLFSSL_X509_STORE_ #define PSK_MAX_IDENTITY_LEN 128 #define SSL_CTX_clear_options wolfSSL_CTX_clear_options +#define SSL_CTX_add_server_custom_ext(...) 0 #endif /* HAVE_STUNNEL || WOLFSSL_NGINX */ @@ -1395,8 +1415,9 @@ wolfSSL_X509_STORE_set_verify_cb((WOLFSSL_X509_STORE *)(s), (WOLFSSL_X509_STORE_ #define sk_X509_OBJECT_num wolfSSL_sk_X509_OBJECT_num #define sk_X509_OBJECT_value wolfSSL_sk_X509_OBJECT_value #define sk_X509_OBJECT_delete wolfSSL_sk_X509_OBJECT_delete +#define X509_OBJECT_new wolfSSL_X509_OBJECT_new #define X509_OBJECT_free wolfSSL_X509_OBJECT_free -#define X509_OBJECT_get_type(x) 0 +#define X509_OBJECT_get_type wolfSSL_X509_OBJECT_get_type #if defined(OPENSSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x10100000L #define OpenSSL_version(x) wolfSSL_OpenSSL_version(x) #else diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h index 105bb3163..49ff34686 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -547,6 +547,9 @@ struct WOLFSSL_X509_STORE { int isDynamic; WOLFSSL_X509_VERIFY_PARAM* param; /* certificate validation parameter */ #endif +#ifdef OPENSSL_ALL + WOLF_STACK_OF(WOLFSSL_X509_OBJECT)* objs; /* object stack cache */ +#endif #if defined(OPENSSL_ALL) || defined(WOLFSSL_QT) WOLFSSL_X509_STORE_CTX_verify_cb verify_cb; #endif @@ -600,8 +603,14 @@ typedef struct WOLFSSL_X509_REVOKED { WOLFSSL_ASN1_INTEGER* serialNumber; /* stunnel dereference */ } WOLFSSL_X509_REVOKED; +typedef enum { + WOLFSSL_X509_LU_NONE = 0, + WOLFSSL_X509_LU_X509, + WOLFSSL_X509_LU_CRL +} WOLFSSL_X509_LOOKUP_TYPE; typedef struct WOLFSSL_X509_OBJECT { + WOLFSSL_X509_LOOKUP_TYPE type; union { char* ptr; WOLFSSL_X509 *x509; @@ -707,6 +716,12 @@ enum AlertLevel { alert_fatal = 2 }; +enum SNICbReturn { + warning_return = alert_warning, + fatal_return = alert_fatal, + noack_return, +}; + /* WS_RETURN_CODE macro * Some OpenSSL APIs specify "0" as the return value when an error occurs. * However, some corresponding wolfSSL APIs return negative values. Such @@ -1256,6 +1271,7 @@ WOLFSSL_API char* wolfSSL_ERR_error_string(unsigned long,char*); WOLFSSL_API void wolfSSL_ERR_error_string_n(unsigned long e, char* buf, unsigned long sz); WOLFSSL_API const char* wolfSSL_ERR_reason_error_string(unsigned long); +WOLFSSL_API const char* wolfSSL_ERR_func_error_string(unsigned long); /* extras */ @@ -1367,10 +1383,12 @@ WOLFSSL_API WOLFSSL_SESSION* wolfSSL_get1_session(WOLFSSL* ssl); /* what's ref count */ WOLFSSL_API WOLFSSL_X509* wolfSSL_X509_new(void); -#if defined(OPENSSL_EXTRA_X509_SMALL) || defined(OPENSSL_ALL) +#if defined(OPENSSL_EXTRA_X509_SMALL) || defined(OPENSSL_EXTRA) WOLFSSL_API int wolfSSL_RSA_up_ref(WOLFSSL_RSA* rsa); WOLFSSL_API int wolfSSL_X509_up_ref(WOLFSSL_X509* x509); WOLFSSL_API int wolfSSL_EVP_PKEY_up_ref(WOLFSSL_EVP_PKEY* pkey); +WOLFSSL_API WOLF_STACK_OF(WOLFSSL_X509)* + wolfSSL_X509_chain_up_ref(WOLF_STACK_OF(WOLFSSL_X509)* chain); #endif WOLFSSL_API int wolfSSL_OCSP_parse_url(char* url, char** host, char** port, @@ -1545,6 +1563,7 @@ WOLFSSL_API void wolfSSL_X509_get0_signature(const WOLFSSL_ASN1_BIT_STRING **psi WOLFSSL_API int wolfSSL_X509_print(WOLFSSL_BIO* bio, WOLFSSL_X509* x509); WOLFSSL_ABI WOLFSSL_API char* wolfSSL_X509_NAME_oneline(WOLFSSL_X509_NAME*, char*, int); +WOLFSSL_API unsigned long wolfSSL_X509_NAME_hash(WOLFSSL_X509_NAME*); #if defined(OPENSSL_EXTRA) && defined(XSNPRINTF) WOLFSSL_API char* wolfSSL_X509_get_name_oneline(WOLFSSL_X509_NAME*, char*, int); #endif @@ -1905,7 +1924,7 @@ enum { SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS = 0x00100000, SSL_OP_NO_QUERY_MTU = 0x00200000, SSL_OP_COOKIE_EXCHANGE = 0x00400000, - SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION = 0x00800000, + WOLFSSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION = 0x00800000, SSL_OP_SINGLE_ECDH_USE = 0x01000000, SSL_OP_CIPHER_SERVER_PREFERENCE = 0x02000000, WOLFSSL_OP_NO_TLSv1_1 = 0x04000000, @@ -1938,6 +1957,7 @@ enum { #if !(!defined(WOLFSSL_TLS13) && defined(WOLFSSL_APACHE_HTTPD)) /* apache uses this to determine if TLS 1.3 is enabled */ #define SSL_OP_NO_TLSv1_3 WOLFSSL_OP_NO_TLSv1_3 #endif +#define SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION WOLFSSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION #define SSL_OP_NO_SSL_MASK (SSL_OP_NO_SSLv3 | SSL_OP_NO_TLSv1 | \ SSL_OP_NO_TLSv1_1 | SSL_OP_NO_TLSv1_2 | SSL_OP_NO_TLSv1_3) @@ -2001,28 +2021,29 @@ enum { BIO_NOCLOSE = 0, X509_FILETYPE_PEM = 8, - X509_LU_X509 = 9, - X509_LU_CRL = 12, + X509_LU_NONE = WOLFSSL_X509_LU_NONE, + X509_LU_X509 = WOLFSSL_X509_LU_X509, + X509_LU_CRL = WOLFSSL_X509_LU_CRL, X509_V_OK = 0, - X509_V_ERR_CRL_SIGNATURE_FAILURE = 13, + X509_V_ERR_CRL_SIGNATURE_FAILURE = 8, + X509_V_ERR_CERT_HAS_EXPIRED = 10, X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD = 14, X509_V_ERR_CRL_HAS_EXPIRED = 15, - X509_V_ERR_CERT_REVOKED = 16, X509_V_ERR_CERT_CHAIN_TOO_LONG = 17, X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT = 18, X509_V_ERR_CERT_NOT_YET_VALID = 19, X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD = 20, - X509_V_ERR_CERT_HAS_EXPIRED = 21, X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD = 22, - X509_V_ERR_CERT_REJECTED = 23, + X509_V_ERR_CERT_REVOKED = 23, + X509_V_ERR_CERT_REJECTED, /* Required for Nginx */ - X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT = 24, - X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN = 25, - X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY = 26, - X509_V_ERR_CERT_UNTRUSTED = 27, - X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE = 28, - X509_V_ERR_SUBJECT_ISSUER_MISMATCH = 29, + X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT, + X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN, + X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY, + X509_V_ERR_CERT_UNTRUSTED, + X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE, + X509_V_ERR_SUBJECT_ISSUER_MISMATCH, /* additional X509_V_ERR_* enums not used in wolfSSL */ X509_V_ERR_UNABLE_TO_GET_CRL, X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE, @@ -2159,6 +2180,7 @@ enum { /* ssl Constants */ WOLFSSL_FILETYPE_DEFAULT = 2, /* ASN1 */ WOLFSSL_FILETYPE_RAW = 3, /* NTRU raw key blob */ + WOLFSSL_VERIFY_DEFAULT = -1, WOLFSSL_VERIFY_NONE = 0, WOLFSSL_VERIFY_PEER = 1, WOLFSSL_VERIFY_FAIL_IF_NO_PEER_CERT = 2, @@ -2300,6 +2322,8 @@ WOLFSSL_API long wolfSSL_CTX_clear_options(WOLFSSL_CTX*, long); #if !defined(NO_CHECK_PRIVATE_KEY) WOLFSSL_API int wolfSSL_CTX_check_private_key(const WOLFSSL_CTX*); #endif +WOLFSSL_API WOLFSSL_EVP_PKEY* wolfSSL_CTX_get0_privatekey(const WOLFSSL_CTX*); + WOLFSSL_API void wolfSSL_ERR_free_strings(void); WOLFSSL_API void wolfSSL_ERR_remove_state(unsigned long); WOLFSSL_API int wolfSSL_clear(WOLFSSL* ssl); @@ -2376,7 +2400,7 @@ WOLFSSL_API int wolfSSL_CTX_set_ex_data_with_cleanup( wolfSSL_ex_data_cleanup_routine_t cleanup_routine); #endif WOLFSSL_API void wolfSSL_CTX_sess_set_get_cb(WOLFSSL_CTX*, - WOLFSSL_SESSION*(*f)(WOLFSSL*, unsigned char*, int, int*)); + WOLFSSL_SESSION*(*f)(WOLFSSL*, const unsigned char*, int, int*)); WOLFSSL_API void wolfSSL_CTX_sess_set_new_cb(WOLFSSL_CTX*, int (*f)(WOLFSSL*, WOLFSSL_SESSION*)); WOLFSSL_API void wolfSSL_CTX_sess_set_remove_cb(WOLFSSL_CTX*, @@ -3794,6 +3818,8 @@ WOLFSSL_API int wolfSSL_get_server_tmp_key(const WOLFSSL*, WOLFSSL_EVP_PKEY**); WOLFSSL_API int wolfSSL_CTX_set_min_proto_version(WOLFSSL_CTX*, int); WOLFSSL_API int wolfSSL_CTX_set_max_proto_version(WOLFSSL_CTX*, int); +WOLFSSL_API int wolfSSL_set_min_proto_version(WOLFSSL*, int); +WOLFSSL_API int wolfSSL_set_max_proto_version(WOLFSSL*, int); WOLFSSL_API int wolfSSL_CTX_get_min_proto_version(WOLFSSL_CTX*); WOLFSSL_API int wolfSSL_CTX_use_PrivateKey(WOLFSSL_CTX *ctx, WOLFSSL_EVP_PKEY *pkey); @@ -3977,6 +4003,10 @@ WOLFSSL_API int wolfSSL_CIPHER_get_bits(const WOLFSSL_CIPHER *c, int *alg_bits); WOLFSSL_API WOLFSSL_STACK* wolfSSL_sk_X509_new(void); WOLFSSL_API int wolfSSL_sk_X509_num(const WOLF_STACK_OF(WOLFSSL_X509) *s); +WOLFSSL_API WOLFSSL_STACK* wolfSSL_sk_X509_OBJECT_new(void); +WOLFSSL_API void wolfSSL_sk_X509_OBJECT_free(WOLFSSL_STACK* s); +WOLFSSL_API int wolfSSL_sk_X509_OBJECT_push(WOLFSSL_STACK* sk, WOLFSSL_X509_OBJECT* obj); + WOLFSSL_API WOLFSSL_X509_INFO *wolfSSL_X509_INFO_new(void); WOLFSSL_API void wolfSSL_X509_INFO_free(WOLFSSL_X509_INFO* info); @@ -4123,11 +4153,16 @@ WOLFSSL_API void wolfSSL_THREADID_current(WOLFSSL_CRYPTO_THREADID* id); WOLFSSL_API unsigned long wolfSSL_THREADID_hash( const WOLFSSL_CRYPTO_THREADID* id); +WOLFSSL_API WOLFSSL_X509_LOOKUP_TYPE wolfSSL_X509_OBJECT_get_type( + const WOLFSSL_X509_OBJECT*); WOLFSSL_API WOLF_STACK_OF(WOLFSSL_X509_OBJECT)* wolfSSL_X509_STORE_get0_objects(WOLFSSL_X509_STORE *); WOLFSSL_API WOLFSSL_X509_OBJECT* wolfSSL_sk_X509_OBJECT_delete(WOLF_STACK_OF(WOLFSSL_X509_OBJECT)* sk, int i); -WOLFSSL_API void wolfSSL_X509_OBJECT_free(WOLFSSL_X509_OBJECT *a); +WOLFSSL_API WOLFSSL_X509_OBJECT* wolfSSL_X509_OBJECT_new(void); +WOLFSSL_API void wolfSSL_X509_OBJECT_free(WOLFSSL_X509_OBJECT *obj); +WOLFSSL_API WOLFSSL_X509 *wolfSSL_X509_OBJECT_get0_X509(const WOLFSSL_X509_OBJECT *obj); +WOLFSSL_API WOLFSSL_X509_CRL *wolfSSL_X509_OBJECT_get0_X509_CRL(WOLFSSL_X509_OBJECT *obj); #endif /* OPENSSL_ALL || HAVE_STUNNEL || WOLFSSL_NGINX || WOLFSSL_HAPROXY || HAVE_LIGHTY */ #if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL) @@ -4266,8 +4301,9 @@ WOLFSSL_API int wolfSSL_CTX_set_tlsext_ticket_key_cb(WOLFSSL_CTX *, ticketCompat defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY) WOLFSSL_API int wolfSSL_CTX_get_extra_chain_certs(WOLFSSL_CTX* ctx, WOLF_STACK_OF(X509)** chain); -WOLFSSL_API int wolfSSL_CTX_set_tlsext_status_cb(WOLFSSL_CTX* ctx, - int(*)(WOLFSSL*, void*)); +typedef int(*tlsextStatusCb)(WOLFSSL*, void*); +WOLFSSL_API int wolfSSL_CTX_get_tlsext_status_cb(WOLFSSL_CTX* ctx, tlsextStatusCb* cb); +WOLFSSL_API int wolfSSL_CTX_set_tlsext_status_cb(WOLFSSL_CTX* ctx, tlsextStatusCb cb); WOLFSSL_API int wolfSSL_X509_STORE_CTX_get1_issuer(WOLFSSL_X509 **issuer, WOLFSSL_X509_STORE_CTX *ctx, WOLFSSL_X509 *x); diff --git a/wolfssl/test.h b/wolfssl/test.h index 084d88296..36bf1214d 100644 --- a/wolfssl/test.h +++ b/wolfssl/test.h @@ -2572,8 +2572,8 @@ static WC_INLINE int myVerify(int preverify, WOLFSSL_X509_STORE_CTX* store) #ifdef HAVE_EXT_CACHE -static WC_INLINE WOLFSSL_SESSION* mySessGetCb(WOLFSSL* ssl, unsigned char* id, - int id_len, int* copy) +static WC_INLINE WOLFSSL_SESSION* mySessGetCb(WOLFSSL* ssl, + const unsigned char* id, int id_len, int* copy) { (void)ssl; (void)id; diff --git a/wolfssl/wolfcrypt/asn.h b/wolfssl/wolfcrypt/asn.h index ed8242008..0a52208c6 100644 --- a/wolfssl/wolfcrypt/asn.h +++ b/wolfssl/wolfcrypt/asn.h @@ -316,7 +316,11 @@ enum Misc_ASN { MAX_DATE_SIZE = 32, ASN_GEN_TIME_SZ = 15, /* 7 numbers * 2 + Zulu tag */ #ifndef NO_RSA +#ifdef WOLFSSL_HAPROXY + MAX_ENCODED_SIG_SZ = 1024, +#else MAX_ENCODED_SIG_SZ = 512, +#endif #elif defined(HAVE_ECC) MAX_ENCODED_SIG_SZ = 140, #elif defined(HAVE_CURVE448)