From d9f7629296c88411c0fac26b7f711ec761cd4605 Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Wed, 20 Mar 2024 17:33:50 +0100 Subject: [PATCH 1/6] Add grpc support - Fix BIO_BIO type - Set retry flags correctly - Add CRL callback - Copy the alt names instead of trying to share a pointer - Allow calling wolfSSL_get_servername on client side (to get the requested name) - Return the chain in wolfSSL_X509_STORE_CTX_get_chain in the correct order - Peer first, top CA last - Fix leak in RebuildFullName - Add CopyString helper function - Implement - X509_CRL_dup - ASN1_UTCTIME_set - X509_STORE_CTX_get0_param - X509_STORE_get0_param - X509_STORE_set_verify_cb - X509_STORE_set_get_crl - X509_set1_notAfter - X509_set1_notBefore --- src/bio.c | 11 +- src/crl.c | 22 +- src/internal.c | 557 +++++++++++++++++++++------------------ src/ssl.c | 22 +- src/ssl_asn1.c | 28 +- src/tls.c | 5 +- src/x509.c | 40 ++- src/x509_str.c | 187 ++++++++----- tests/api.c | 201 ++++++++++++-- wolfcrypt/src/asn.c | 41 +++ wolfcrypt/src/misc.c | 19 ++ wolfssl/internal.h | 10 +- wolfssl/openssl/evp.h | 1 + wolfssl/openssl/ssl.h | 18 +- wolfssl/ssl.h | 27 +- wolfssl/wolfcrypt/asn.h | 1 + wolfssl/wolfcrypt/misc.h | 2 + 17 files changed, 805 insertions(+), 387 deletions(-) diff --git a/src/bio.c b/src/bio.c index 5369dc88bd..1d78b3aa54 100644 --- a/src/bio.c +++ b/src/bio.c @@ -77,6 +77,8 @@ static int wolfSSL_BIO_BIO_read(WOLFSSL_BIO* bio, void* buf, int len) if (buf == NULL || len == 0) return 0; + /* default no retry */ + bio->flags &= ~(WOLFSSL_BIO_FLAG_READ|WOLFSSL_BIO_FLAG_RETRY); sz1 = wolfSSL_BIO_nread(bio, &pt, len); if (sz1 > 0) { XMEMCPY(buf, pt, sz1); @@ -91,8 +93,10 @@ static int wolfSSL_BIO_BIO_read(WOLFSSL_BIO* bio, void* buf, int len) } } } - if (sz1 == 0) + if (sz1 == 0) { + bio->flags |= WOLFSSL_BIO_FLAG_READ|WOLFSSL_BIO_FLAG_RETRY; sz1 = -1; + } return sz1; } @@ -502,8 +506,11 @@ static int wolfSSL_BIO_BIO_write(WOLFSSL_BIO* bio, const void* data, if (bio == NULL || data == NULL || len == 0) return 0; + /* default no retry */ + bio->flags &= ~(WOLFSSL_BIO_FLAG_WRITE|WOLFSSL_BIO_FLAG_RETRY); sz1 = wolfSSL_BIO_nwrite(bio, &buf, len); if (sz1 == 0) { + bio->flags |= WOLFSSL_BIO_FLAG_WRITE|WOLFSSL_BIO_FLAG_RETRY; WOLFSSL_MSG("No room left to write"); return WOLFSSL_BIO_ERROR; } @@ -521,6 +528,8 @@ static int wolfSSL_BIO_BIO_write(WOLFSSL_BIO* bio, const void* data, if (sz2 > 0) { XMEMCPY(buf, data, sz2); sz1 += sz2; + if (len > sz2) + bio->flags |= WOLFSSL_BIO_FLAG_WRITE|WOLFSSL_BIO_FLAG_RETRY; } } diff --git a/src/crl.c b/src/crl.c index f273d24d67..9d21ea9266 100644 --- a/src/crl.c +++ b/src/crl.c @@ -504,7 +504,7 @@ int CheckCertCRL_ex(WOLFSSL_CRL* crl, byte* issuerHash, byte* serial, /* and try again checking Cert in the CRL list. */ /* When not set the folder or not use hash_dir, do nothing. */ if ((foundEntry == 0) && (ret != OCSP_WANT_READ)) { - if (crl->cm->x509_store_p != NULL) { + if (crl->cm != NULL && crl->cm->x509_store_p != NULL) { ret = LoadCertByIssuer(crl->cm->x509_store_p, (WOLFSSL_X509_NAME*)issuerName, X509_LU_CRL); if (ret == WOLFSSL_SUCCESS) { @@ -521,7 +521,7 @@ int CheckCertCRL_ex(WOLFSSL_CRL* crl, byte* issuerHash, byte* serial, ret = CRL_MISSING; } - if (crl->cm->cbMissingCRL) { + if (crl->cm != NULL && crl->cm->cbMissingCRL) { char url[256]; WOLFSSL_MSG("Issuing missing CRL callback"); @@ -685,8 +685,8 @@ static WOLFSSL_X509_CRL* wolfSSL_X509_crl_new(WOLFSSL_CERT_MANAGER* cm) { WOLFSSL_X509_CRL* ret; - ret = (WOLFSSL_X509_CRL*)XMALLOC(sizeof(WOLFSSL_X509_CRL), cm->heap, - DYNAMIC_TYPE_CRL); + ret = (WOLFSSL_X509_CRL*)XMALLOC(sizeof(WOLFSSL_X509_CRL), + cm != NULL ? cm->heap : NULL, DYNAMIC_TYPE_CRL); if (ret != NULL) { if (InitCRL(ret, cm) < 0) { WOLFSSL_MSG("Unable to initialize new CRL structure"); @@ -885,6 +885,20 @@ static int DupX509_CRL(WOLFSSL_X509_CRL *dupl, const WOLFSSL_X509_CRL* crl) return 0; } +WOLFSSL_X509_CRL* wolfSSL_X509_CRL_dup(const WOLFSSL_X509_CRL* crl) +{ + WOLFSSL_X509_CRL* ret; + + WOLFSSL_ENTER("wolfSSL_X509_CRL_dup"); + + ret = wolfSSL_X509_crl_new(crl->cm); + if (ret != NULL && DupX509_CRL(ret, crl) != 0) { + FreeCRL(ret, 1); + ret = NULL; + } + return ret; +} + /* returns WOLFSSL_SUCCESS on success. Does not take ownership of newcrl */ int wolfSSL_X509_STORE_add_crl(WOLFSSL_X509_STORE *store, WOLFSSL_X509_CRL *newcrl) { diff --git a/src/internal.c b/src/internal.c index 4d10cc803e..f509e68337 100644 --- a/src/internal.c +++ b/src/internal.c @@ -2460,22 +2460,21 @@ int InitSSL_Ctx(WOLFSSL_CTX* ctx, WOLFSSL_METHOD* method, void* heap) return MEMORY_E; } XMEMSET(ctx->param, 0, sizeof(WOLFSSL_X509_VERIFY_PARAM)); - /* WOLFSSL_X509_LOOKUP */ + /* WOLFSSL_X509_LOOKUP and param */ if ((ctx->x509_store.lookup.dirs = (WOLFSSL_BY_DIR*)XMALLOC(sizeof(WOLFSSL_BY_DIR), - heap, DYNAMIC_TYPE_OPENSSL)) == NULL) { - WOLFSSL_MSG("ctx-x509_store.lookup.dir memory allocation error"); - XFREE(ctx->param, heap, DYNAMIC_TYPE_OPENSSL); - ctx->param = NULL; + heap, DYNAMIC_TYPE_OPENSSL)) == NULL || + (ctx->x509_store.param = (WOLFSSL_X509_VERIFY_PARAM*)XMALLOC( + sizeof(WOLFSSL_X509_VERIFY_PARAM), + heap, DYNAMIC_TYPE_OPENSSL)) == NULL) { + WOLFSSL_MSG("ctx-x509_store.lookup.dir or ctx->x509_store.param memory " + "allocation error"); return MEMORY_E; } XMEMSET(ctx->x509_store.lookup.dirs, 0, sizeof(WOLFSSL_BY_DIR)); + XMEMSET(ctx->x509_store.param, 0, sizeof(WOLFSSL_X509_VERIFY_PARAM)); if (wc_InitMutex(&ctx->x509_store.lookup.dirs->lock) != 0) { WOLFSSL_MSG("Bad mutex init"); - XFREE(ctx->param, heap, DYNAMIC_TYPE_OPENSSL); - ctx->param = NULL; - XFREE(ctx->x509_store.lookup.dirs, heap, DYNAMIC_TYPE_OPENSSL); - ctx->x509_store.lookup.dirs = NULL; WOLFSSL_ERROR_VERBOSE(BAD_MUTEX_E); return BAD_MUTEX_E; } @@ -2729,6 +2728,11 @@ void SSL_CtxResourceFree(WOLFSSL_CTX* ctx) ctx->param = NULL; } + if (ctx->x509_store.param) { + XFREE(ctx->x509_store.param, heapAtCTXInit, DYNAMIC_TYPE_OPENSSL); + ctx->x509_store.param = NULL; + } + if (ctx->x509_store.lookup.dirs) { #if defined(OPENSSL_ALL) && !defined(NO_FILESYSTEM) && !defined(NO_WOLFSSL_DIR) if (ctx->x509_store.lookup.dirs->dir_entry) { @@ -12552,6 +12556,12 @@ static void AddSessionCertToChain(WOLFSSL_X509_CHAIN* chain, defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL) void CopyDecodedName(WOLFSSL_X509_NAME* name, DecodedCert* dCert, int nameType) { + if (name->dynamicName) { + XFREE(name->name, name->heap, DYNAMIC_TYPE_X509); + name->name = name->staticName; + name->dynamicName = 0; + } + if (nameType == SUBJECT) { XSTRNCPY(name->name, dCert->subject, ASN_NAME_MAX); name->name[ASN_NAME_MAX - 1] = '\0'; @@ -12576,52 +12586,37 @@ void CopyDecodedName(WOLFSSL_X509_NAME* name, DecodedCert* dCert, int nameType) } } - -#if (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)) && \ - !defined(IGNORE_NAME_CONSTRAINTS) -/* copies over additional alt names such as dirName - * returns 0 on success - */ -static int CopyAdditionalAltNames(DNS_entry** to, DNS_entry* from, int type, - void* heap) +static int CopyAltNames(DNS_entry** to, DNS_entry* from, int type, void* heap) { - DNS_entry* cur = from; + /* Copy from to the beginning of to */ + DNS_entry** prev_next = to; + DNS_entry* next; if (to == NULL) { return BAD_FUNC_ARG; } - while (cur != NULL) { - if (cur->type == type) { - DNS_entry* dnsEntry; - int strLen = cur->len; + next = *to; - dnsEntry = AltNameNew(heap); - if (dnsEntry == NULL) { - WOLFSSL_MSG("\tOut of Memory"); - return MEMORY_E; - } + for (; from != NULL; from = from->next) { + DNS_entry* dnsEntry; - dnsEntry->type = type; - dnsEntry->name = (char*)XMALLOC(strLen + 1, heap, - DYNAMIC_TYPE_ALTNAME); - if (dnsEntry->name == NULL) { - WOLFSSL_MSG("\tOut of Memory"); - XFREE(dnsEntry, heap, DYNAMIC_TYPE_ALTNAME); - return MEMORY_E; - } - dnsEntry->len = strLen; - XMEMCPY(dnsEntry->name, cur->name, strLen); - dnsEntry->name[strLen] = '\0'; + if (type != -1 && from->type != type) + continue; - dnsEntry->next = *to; - *to = dnsEntry; + dnsEntry = AltNameDup(from, heap); + if (dnsEntry == NULL) { + WOLFSSL_MSG("\tOut of Memory"); + return MEMORY_E; } - cur = cur->next; + + dnsEntry->next = next; + *prev_next = dnsEntry; + prev_next = &dnsEntry->next; } + return 0; } -#endif /* OPENSSL_EXTRA */ #ifdef WOLFSSL_CERT_REQ static int CopyREQAttributes(WOLFSSL_X509* x509, DecodedCert* dCert) @@ -12736,8 +12731,6 @@ static int CopyREQAttributes(WOLFSSL_X509* x509, DecodedCert* dCert) #endif /* WOLFSSL_CERT_REQ */ /* Copy parts X509 needs from Decoded cert, 0 on success */ -/* The same DecodedCert cannot be copied to WOLFSSL_X509 twice otherwise the - * altNames pointers could be free'd by second x509 still active by first */ int CopyDecodedToX509(WOLFSSL_X509* x509, DecodedCert* dCert) { int ret = 0; @@ -12908,19 +12901,21 @@ int CopyDecodedToX509(WOLFSSL_X509* x509, DecodedCert* dCert) } } - x509->altNames = dCert->altNames; - dCert->weOwnAltNames = 0; + /* add alt names from dCert to X509 */ + if (CopyAltNames(&x509->altNames, dCert->altNames, -1, x509->heap) != 0) { + return MEMORY_E; + } #if (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)) && \ !defined(IGNORE_NAME_CONSTRAINTS) /* add copies of email names from dCert to X509 */ - if (CopyAdditionalAltNames(&x509->altNames, dCert->altEmailNames, + if (CopyAltNames(&x509->altNames, dCert->altEmailNames, ASN_RFC822_TYPE, x509->heap) != 0) { return MEMORY_E; } #endif /* OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL */ #if defined(OPENSSL_EXTRA) && !defined(IGNORE_NAME_CONSTRAINTS) /* add copies of alternate directory names from dCert to X509 */ - if (CopyAdditionalAltNames(&x509->altNames, dCert->altDirNames, + if (CopyAltNames(&x509->altNames, dCert->altDirNames, ASN_DIR_TYPE, x509->heap) != 0) { return MEMORY_E; } @@ -13350,6 +13345,164 @@ void DoCertFatalAlert(WOLFSSL* ssl, int ret) ssl->options.isClosed = 1; } + +int SetupStoreCtxCallback(WOLFSSL_X509_STORE_CTX** store_pt, + WOLFSSL* ssl, WOLFSSL_CERT_MANAGER* cm, ProcPeerCertArgs* args, + int cert_err, void* heap, int* x509Free) +{ + WOLFSSL_X509_STORE_CTX* store = NULL; + char* domain = NULL; +#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL) + WOLFSSL_X509* x509 = NULL; +#endif + + *x509Free = 0; + + store = wolfSSL_X509_STORE_CTX_new_ex(heap); + if (store == NULL) + goto mem_error; + domain = (char*)XMALLOC(ASN_NAME_MAX, heap, DYNAMIC_TYPE_STRING); + if (domain == NULL) + goto mem_error; + + domain[0] = '\0'; + + /* build subject CN as string to return in store */ + if (args->dCertInit && args->dCert && args->dCert->subjectCN) { + int subjectCNLen = args->dCert->subjectCNLen; + if (subjectCNLen > ASN_NAME_MAX-1) + subjectCNLen = ASN_NAME_MAX-1; + if (subjectCNLen > 0) { + XMEMCPY(domain, args->dCert->subjectCN, subjectCNLen); + domain[subjectCNLen] = '\0'; + } + } + +#ifndef OPENSSL_COMPATIBLE_DEFAULTS + store->error = cert_err; +#else + store->error = GetX509Error(cert_err); +#endif + store->error_depth = args->certIdx; + store->discardSessionCerts = 0; + store->domain = domain; + if (ssl != NULL) { + if (ssl->verifyCbCtx != NULL) { + /* Use the WOLFSSL user context if set */ + store->userCtx = ssl->verifyCbCtx; + } + else { + /* Else use the WOLFSSL_CTX user context */ + store->userCtx = ssl->ctx->verifyCbCtx; + } + } + else { + store->userCtx = cm; + } + store->certs = args->certs; + store->totalCerts = args->totalCerts; +#if defined(HAVE_EX_DATA) && \ + (defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL)) + if (wolfSSL_CRYPTO_set_ex_data(&store->ex_data, 0, ssl) + != WOLFSSL_SUCCESS) { + WOLFSSL_MSG("Failed to store ssl context in WOLFSSL_X509_STORE_CTX"); + } +#endif + + if (ssl != NULL) { +#if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER) + store->store = SSL_STORE(ssl); +#if defined(OPENSSL_EXTRA) + store->depth = args->count; + /* Overwrite with non-default param values in SSL */ + if (ssl->param) { + if (ssl->param->check_time) + store->param->check_time = ssl->param->check_time; + + if (ssl->param->flags) + store->param->flags = ssl->param->flags; +#ifdef WOLFSSL_LOCAL_X509_STORE + else if (SSL_STORE(ssl) && SSL_STORE(ssl)->param && + SSL_STORE(ssl)->param->flags) + store->param->flags = SSL_STORE(ssl)->param->flags; +#endif + + + if (ssl->param->hostName[0]) + XMEMCPY(store->param->hostName, ssl->param->hostName, + WOLFSSL_HOST_NAME_MAX); + + } +#endif /* defined(OPENSSL_EXTRA) */ +#endif /* defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER)*/ +#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL) + #ifdef KEEP_PEER_CERT + if (args->certIdx == 0) { + FreeX509(&ssl->peerCert); + InitX509(&ssl->peerCert, 0, ssl->heap); + if (CopyDecodedToX509(&ssl->peerCert, args->dCert) == 0) + WOLFSSL_MSG("Unable to copy to ssl->peerCert"); + store->current_cert = &ssl->peerCert; /* use existing X509 */ + } + else + #endif + { + x509 = wolfSSL_X509_new_ex(heap); + if (x509 == NULL) + goto mem_error; + if (CopyDecodedToX509(x509, args->dCert) == 0) { + store->current_cert = x509; + *x509Free = 1; + } + } +#endif +#ifdef SESSION_CERTS + store->sesChain = &ssl->session->chain; +#endif + } + *store_pt = store; + return 0; +mem_error: + if (store != NULL) + wolfSSL_X509_STORE_CTX_free(store); +#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL) + if (x509 != NULL) + wolfSSL_X509_free(x509); +#endif + if (domain != NULL) + XFREE(domain, heap, DYNAMIC_TYPE_STRING); + return MEMORY_E; +} + +void CleanupStoreCtxCallback(WOLFSSL_X509_STORE_CTX* store, + WOLFSSL* ssl, void* heap, int x509Free) +{ + (void)ssl; + (void)x509Free; + +#if defined(SESSION_CERTS) && defined(OPENSSL_EXTRA) + wolfSSL_sk_X509_pop_free(store->chain, NULL); + store->chain = NULL; +#endif +#ifdef SESSION_CERTS + if ((ssl != NULL) && (store->discardSessionCerts)) { + WOLFSSL_MSG("Verify callback requested discard sess certs"); + ssl->session->chain.count = 0; + #ifdef WOLFSSL_ALT_CERT_CHAINS + ssl->session->altChain.count = 0; + #endif + } +#endif /* SESSION_CERTS */ + XFREE(store->domain, heap, DYNAMIC_TYPE_STRING); + store->domain = NULL; +#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL) + if (x509Free) + wolfSSL_X509_free(store->current_cert); + store->current_cert = NULL; +#endif + wolfSSL_X509_STORE_CTX_free(store); +} + /* WOLFSSL_ALWAYS_VERIFY_CB: Use verify callback for success or failure cases */ /* WOLFSSL_VERIFY_CB_ALL_CERTS: Issue callback for all intermediate certificates */ @@ -13358,10 +13511,10 @@ void DoCertFatalAlert(WOLFSSL* ssl, int ret) * store->error_depth member to determine index (0=peer, >1 intermediates) */ -int DoVerifyCallback(WOLFSSL_CERT_MANAGER* cm, WOLFSSL* ssl, int ret, +int DoVerifyCallback(WOLFSSL_CERT_MANAGER* cm, WOLFSSL* ssl, int cert_err, ProcPeerCertArgs* args) { - int verify_ok = 0, use_cb = 0; + int verify_ok = 0, use_cb = 0, ret = cert_err; void *heap; if (cm == NULL) { @@ -13371,12 +13524,12 @@ int DoVerifyCallback(WOLFSSL_CERT_MANAGER* cm, WOLFSSL* ssl, int ret, heap = (ssl != NULL) ? ssl->heap : cm->heap; /* Determine if verify was okay */ - if (ret == 0) { + if (cert_err == 0) { verify_ok = 1; } /* Determine if verify callback should be used */ - if (ret != 0) { + if (cert_err != 0) { if ((ssl != NULL) && (!ssl->options.verifyNone)) { use_cb = 1; /* always report errors */ } @@ -13402,7 +13555,7 @@ int DoVerifyCallback(WOLFSSL_CERT_MANAGER* cm, WOLFSSL* ssl, int ret, /* If altNames names is present, then subject common name is ignored */ if (args->dCert->altNames != NULL) { if (CheckForAltNames(args->dCert, ssl->param->hostName, NULL) != 1) { - if (ret == 0) { + if (cert_err == 0) { ret = DOMAIN_NAME_MISMATCH; WOLFSSL_ERROR_VERBOSE(ret); } @@ -13414,7 +13567,7 @@ int DoVerifyCallback(WOLFSSL_CERT_MANAGER* cm, WOLFSSL* ssl, int ret, if (MatchDomainName(args->dCert->subjectCN, args->dCert->subjectCNLen, ssl->param->hostName) == 0) { - if (ret == 0) { + if (cert_err == 0) { ret = DOMAIN_NAME_MISMATCH; WOLFSSL_ERROR_VERBOSE(ret); } @@ -13423,7 +13576,7 @@ int DoVerifyCallback(WOLFSSL_CERT_MANAGER* cm, WOLFSSL* ssl, int ret, } #else else { - if (ret == 0) { + if (cert_err == 0) { ret = DOMAIN_NAME_MISMATCH; WOLFSSL_ERROR_VERBOSE(ret); } @@ -13435,7 +13588,7 @@ int DoVerifyCallback(WOLFSSL_CERT_MANAGER* cm, WOLFSSL* ssl, int ret, if ((args->dCertInit != 0) && (args->dCert != NULL) && (ssl != NULL) && (ssl->param != NULL) && (XSTRLEN(ssl->param->ipasc) > 0)) { if (CheckIPAddr(args->dCert, ssl->param->ipasc) != 0) { - if (ret == 0) { + if (cert_err == 0) { ret = IPADDR_MISMATCH; WOLFSSL_ERROR_VERBOSE(ret); } @@ -13447,6 +13600,10 @@ int DoVerifyCallback(WOLFSSL_CERT_MANAGER* cm, WOLFSSL* ssl, int ret, if ((use_cb && (ssl != NULL) && ((ssl->verifyCallback != NULL) #ifdef OPENSSL_ALL || (ssl->ctx->verifyCertCb != NULL) + #endif + #if defined(WOLFSSL_LOCAL_X509_STORE) && \ + (defined(OPENSSL_ALL) || defined(WOLFSSL_QT)) + || (SSL_STORE(ssl) != NULL && SSL_STORE(ssl)->verify_cb != NULL) #endif )) #ifndef NO_WOLFSSL_CM_VERIFY @@ -13454,157 +13611,20 @@ int DoVerifyCallback(WOLFSSL_CERT_MANAGER* cm, WOLFSSL* ssl, int ret, #endif ) { int verifyFail = 0; - #ifdef WOLFSSL_SMALL_STACK - WOLFSSL_X509_STORE_CTX* store; - #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL) - WOLFSSL_X509* x509; - #endif - char* domain = NULL; - #else - WOLFSSL_X509_STORE_CTX store[1]; - #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL) - WOLFSSL_X509 x509[1]; - #endif - char domain[ASN_NAME_MAX]; - #endif - #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL) + WOLFSSL_X509_STORE_CTX* store = NULL; int x509Free = 0; - #endif + int setupRet = SetupStoreCtxCallback(&store, ssl, cm, args, cert_err, + heap, &x509Free); - #ifdef WOLFSSL_SMALL_STACK - store = (WOLFSSL_X509_STORE_CTX*)XMALLOC( - sizeof(WOLFSSL_X509_STORE_CTX), heap, DYNAMIC_TYPE_X509_STORE); - if (store == NULL) { - return MEMORY_E; - } - #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL) - x509 = (WOLFSSL_X509*)XMALLOC(sizeof(WOLFSSL_X509), heap, - DYNAMIC_TYPE_X509); - if (x509 == NULL) { - XFREE(store, heap, DYNAMIC_TYPE_X509_STORE); - return MEMORY_E; - } - #endif - domain = (char*)XMALLOC(ASN_NAME_MAX, heap, DYNAMIC_TYPE_STRING); - if (domain == NULL) { - XFREE(store, heap, DYNAMIC_TYPE_X509_STORE); - #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL) - XFREE(x509, heap, DYNAMIC_TYPE_X509); - #endif - return MEMORY_E; - } - #endif /* WOLFSSL_SMALL_STACK */ - - XMEMSET(store, 0, sizeof(WOLFSSL_X509_STORE_CTX)); - #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL) - XMEMSET(x509, 0, sizeof(WOLFSSL_X509)); - #endif - domain[0] = '\0'; - - /* build subject CN as string to return in store */ - if (args->dCertInit && args->dCert && args->dCert->subjectCN) { - int subjectCNLen = args->dCert->subjectCNLen; - if (subjectCNLen > ASN_NAME_MAX-1) - subjectCNLen = ASN_NAME_MAX-1; - if (subjectCNLen > 0) { - XMEMCPY(domain, args->dCert->subjectCN, subjectCNLen); - domain[subjectCNLen] = '\0'; - } - } - -#ifndef OPENSSL_COMPATIBLE_DEFAULTS - store->error = ret; -#else - store->error = GetX509Error(ret); -#endif - store->error_depth = args->certIdx; - store->discardSessionCerts = 0; - store->domain = domain; - if (ssl != NULL) { - if (ssl->verifyCbCtx != NULL) { - /* Use the WOLFSSL user context if set */ - store->userCtx = ssl->verifyCbCtx; - } - else { - /* Else use the WOLFSSL_CTX user context */ - store->userCtx = ssl->ctx->verifyCbCtx; - } - } - else { - store->userCtx = cm; - } - store->certs = args->certs; - store->totalCerts = args->totalCerts; - #if defined(HAVE_EX_DATA) && \ - (defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL)) - if (wolfSSL_CRYPTO_set_ex_data(&store->ex_data, 0, ssl) - != WOLFSSL_SUCCESS) { - WOLFSSL_MSG("Failed to store ssl context in WOLFSSL_X509_STORE_CTX"); - } - #endif - - if (ssl != NULL) { - #if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER) - store->store = SSL_STORE(ssl); - #if defined(OPENSSL_EXTRA) - store->depth = args->count; - store->param = (WOLFSSL_X509_VERIFY_PARAM*)XMALLOC( - sizeof(WOLFSSL_X509_VERIFY_PARAM), - heap, DYNAMIC_TYPE_OPENSSL); - if (store->param == NULL) { - #ifdef WOLFSSL_SMALL_STACK - XFREE(domain, heap, DYNAMIC_TYPE_STRING); - #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL) - XFREE(x509, heap, DYNAMIC_TYPE_X509); - #endif - XFREE(store, heap, DYNAMIC_TYPE_X509_STORE); - #endif - return MEMORY_E; - } - XMEMSET(store->param, 0, sizeof(WOLFSSL_X509_VERIFY_PARAM)); - /* Overwrite with non-default param values in SSL */ - if (ssl->param) { - if (ssl->param->check_time) - store->param->check_time = ssl->param->check_time; - - if (ssl->param->flags) - store->param->flags = ssl->param->flags; - - if (ssl->param->hostName[0]) - XMEMCPY(store->param->hostName, ssl->param->hostName, - WOLFSSL_HOST_NAME_MAX); + if (setupRet != 0) + return setupRet; - } - #endif /* defined(OPENSSL_EXTRA) */ - #endif /* defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER)*/ - #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL) - #ifdef KEEP_PEER_CERT - if (args->certIdx == 0) { - store->current_cert = &ssl->peerCert; /* use existing X509 */ - } - else - #endif - { - InitX509(x509, 0, heap); - if (CopyDecodedToX509(x509, args->dCert) == 0) { - store->current_cert = x509; - x509Free = 1; - } - else { - FreeX509(x509); - } - } - #endif - #ifdef SESSION_CERTS - store->sesChain = &ssl->session->chain; - #endif - } #ifndef NO_WOLFSSL_CM_VERIFY /* non-zero return code indicates failure override */ if (cm->verifyCallback != NULL) { store->userCtx = cm; if (cm->verifyCallback(verify_ok, store)) { - if (ret != 0) { + if (cert_err != 0) { WOLFSSL_MSG("Verify CM callback overriding error!"); ret = 0; } @@ -13620,7 +13640,7 @@ int DoVerifyCallback(WOLFSSL_CERT_MANAGER* cm, WOLFSSL* ssl, int ret, /* non-zero return code indicates failure override */ if (ssl->ctx->verifyCertCb) { if (ssl->ctx->verifyCertCb(store, ssl->ctx->verifyCertCbArg)) { - if (ret != 0) { + if (cert_err != 0) { WOLFSSL_MSG("Verify Cert callback overriding error!"); ret = 0; } @@ -13630,11 +13650,10 @@ int DoVerifyCallback(WOLFSSL_CERT_MANAGER* cm, WOLFSSL* ssl, int ret, } } #endif - /* non-zero return code indicates failure override */ if (ssl->verifyCallback) { if (ssl->verifyCallback(verify_ok, store)) { - if (ret != 0) { + if (cert_err != 0) { WOLFSSL_MSG("Verify callback overriding error!"); ret = 0; } @@ -13643,11 +13662,25 @@ int DoVerifyCallback(WOLFSSL_CERT_MANAGER* cm, WOLFSSL* ssl, int ret, verifyFail = 1; } } +#if defined(WOLFSSL_LOCAL_X509_STORE) && \ + (defined(OPENSSL_ALL) || defined(WOLFSSL_QT)) + if (SSL_STORE(ssl) != NULL && SSL_STORE(ssl)->verify_cb != NULL) { + if (SSL_STORE(ssl)->verify_cb(verify_ok, store)) { + if (cert_err != 0) { + WOLFSSL_MSG("Store Verify callback overriding error!"); + ret = 0; + } + } + else { + verifyFail = 1; + } + } +#endif } if (verifyFail) { /* induce error if one not present */ - if (ret == 0) { + if (cert_err == 0) { ret = VERIFY_CERT_ERROR; WOLFSSL_ERROR_VERBOSE(ret); } @@ -13655,36 +13688,7 @@ int DoVerifyCallback(WOLFSSL_CERT_MANAGER* cm, WOLFSSL* ssl, int ret, /* mark as verify error */ args->verifyErr = 1; } - #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL) - if (x509Free) { - FreeX509(x509); - } - #endif - #if defined(SESSION_CERTS) && defined(OPENSSL_EXTRA) - wolfSSL_sk_X509_pop_free(store->chain, NULL); - store->chain = NULL; - #endif - #ifdef SESSION_CERTS - if ((ssl != NULL) && (store->discardSessionCerts)) { - WOLFSSL_MSG("Verify callback requested discard sess certs"); - ssl->session->chain.count = 0; - #ifdef WOLFSSL_ALT_CERT_CHAINS - ssl->session->altChain.count = 0; - #endif - } - #endif /* SESSION_CERTS */ -#ifdef OPENSSL_EXTRA - if ((ssl != NULL) && (store->param)) { - XFREE(store->param, heap, DYNAMIC_TYPE_OPENSSL); - } -#endif - #ifdef WOLFSSL_SMALL_STACK - XFREE(domain, heap, DYNAMIC_TYPE_STRING); - #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL) - XFREE(x509, heap, DYNAMIC_TYPE_X509); - #endif - XFREE(store, heap, DYNAMIC_TYPE_X509_STORE); - #endif + CleanupStoreCtxCallback(store, ssl, heap, x509Free); } (void)heap; @@ -13692,6 +13696,50 @@ int DoVerifyCallback(WOLFSSL_CERT_MANAGER* cm, WOLFSSL* ssl, int ret, return ret; } +#ifdef HAVE_CRL +void DoCrlCallback(WOLFSSL_CERT_MANAGER* cm, WOLFSSL* ssl, + ProcPeerCertArgs* args, int* outRet) +{ +#if defined(WOLFSSL_LOCAL_X509_STORE) && \ + (defined(OPENSSL_ALL) || defined(WOLFSSL_QT)) + int ret = 0; + void* heap = (ssl != NULL) ? ssl->heap : cm->heap; + WOLFSSL_X509_STORE* cert_store = (ssl != NULL) ? SSL_STORE(ssl) : NULL; + + if (cert_store != NULL && cert_store->get_crl_cb != NULL) { + WOLFSSL_CRL* userCrl = NULL; + WOLFSSL_X509_STORE_CTX* store = NULL; + int x509Free = 0; + + ret = SetupStoreCtxCallback(&store, ssl, cm, args, 0, heap, + &x509Free); + if (ret != 0) { + *outRet = ret; + return; + } + + ret = cert_store->get_crl_cb(store, &userCrl, store->current_cert); + if (ret == 1 && userCrl != NULL) { + /* Point to current cm to be able to verify CRL */ + userCrl->cm = SSL_CM(ssl); + *outRet = CheckCertCRL(userCrl, args->dCert); + } + else + *outRet = CRL_MISSING; + + if (userCrl != NULL) + wolfSSL_X509_CRL_free(userCrl); + CleanupStoreCtxCallback(store, ssl, heap, x509Free); + } +#else + (void)cm; + (void)ssl; + (void)args; + (void)outRet; +#endif +} +#endif + static void FreeProcPeerCertArgs(WOLFSSL* ssl, void* pArgs) { ProcPeerCertArgs* args = (ProcPeerCertArgs*)pArgs; @@ -14224,10 +14272,12 @@ static int ProcessPeerCertCheckKey(WOLFSSL* ssl, ProcPeerCertArgs* args) } #ifdef HAVE_CRL -static int ProcessPeerCertsChainCRLCheck(WOLFSSL_CERT_MANAGER* cm, Signer* ca) +static int ProcessPeerCertsChainCRLCheck(WOLFSSL* ssl, ProcPeerCertArgs* args) { Signer* prev = NULL; int ret = 0; + WOLFSSL_CERT_MANAGER* cm = SSL_CM(ssl); + Signer* ca = args->dCert->ca; /* End loop if no more issuers found or if we have * found a self signed cert (ca == prev) */ for (; ret == 0 && ca != NULL && ca != prev; @@ -14235,7 +14285,12 @@ static int ProcessPeerCertsChainCRLCheck(WOLFSSL_CERT_MANAGER* cm, Signer* ca) ret = CheckCertCRL_ex(cm->crl, ca->issuerNameHash, NULL, 0, ca->serialHash, NULL, 0, NULL); if (ret != 0) + DoCrlCallback(cm, ssl, args, &ret); + if (ret != 0){ + WOLFSSL_ERROR_VERBOSE(ret); + WOLFSSL_MSG("\tCRL check not ok"); break; + } } return ret; } @@ -14733,14 +14788,16 @@ int ProcessPeerCerts(WOLFSSL* ssl, byte* input, word32* inOutIdx, goto exit_ppc; } #endif + if (ret != 0) + DoCrlCallback(SSL_CM(ssl), ssl, args, &ret); if (ret != 0) { WOLFSSL_ERROR_VERBOSE(ret); WOLFSSL_MSG("\tCRL check not ok"); } if (ret == 0 && args->certIdx == args->totalCerts-1) { - ret = ProcessPeerCertsChainCRLCheck( - SSL_CM(ssl), args->dCert->ca); + ret = ProcessPeerCertsChainCRLCheck(ssl, + args); if (ret != 0) { WOLFSSL_ERROR_VERBOSE(ret); WOLFSSL_MSG("\tCRL chain check not ok"); @@ -15177,6 +15234,8 @@ int ProcessPeerCerts(WOLFSSL* ssl, byte* input, word32* inOutIdx, goto exit_ppc; } #endif + if (ret != 0) + DoCrlCallback(SSL_CM(ssl), ssl, args, &ret); if (ret != 0) { WOLFSSL_MSG("\tCRL check not ok"); args->fatal = 0; @@ -15195,8 +15254,7 @@ int ProcessPeerCerts(WOLFSSL* ssl, byte* input, word32* inOutIdx, SSL_CM(ssl)->crlCheckAll && args->totalCerts == 1) { /* Check the entire cert chain */ if (args->dCert->ca != NULL) { - ret = ProcessPeerCertsChainCRLCheck(SSL_CM(ssl), - args->dCert->ca); + ret = ProcessPeerCertsChainCRLCheck(ssl, args); if (ret != 0) { WOLFSSL_ERROR_VERBOSE(ret); WOLFSSL_MSG("\tCRL chain check not ok"); @@ -15216,26 +15274,9 @@ int ProcessPeerCerts(WOLFSSL* ssl, byte* input, word32* inOutIdx, if (args->fatal == 0) { int copyRet = 0; - #ifdef WOLFSSL_POST_HANDSHAKE_AUTH - if (ssl->options.handShakeDone) { - FreeX509(&ssl->peerCert); - InitX509(&ssl->peerCert, 0, ssl->heap); - } - else - #endif - #ifdef HAVE_SECURE_RENEGOTIATION - if (ssl->secure_renegotiation && - ssl->secure_renegotiation->enabled) { - /* free old peer cert */ - FreeX509(&ssl->peerCert); - InitX509(&ssl->peerCert, 0, ssl->heap); - } - else - #endif - { - } - - /* set X509 format for peer cert */ + /* free old peer cert */ + FreeX509(&ssl->peerCert); + InitX509(&ssl->peerCert, 0, ssl->heap); copyRet = CopyDecodedToX509(&ssl->peerCert, args->dCert); if (copyRet == MEMORY_E) { args->fatal = 1; diff --git a/src/ssl.c b/src/ssl.c index 993c727df5..4a6f54fde7 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -3062,7 +3062,7 @@ word16 wolfSSL_SNI_GetRequest(WOLFSSL* ssl, byte type, void** data) *data = NULL; if (ssl && ssl->extensions) - return TLSX_SNI_GetRequest(ssl->extensions, type, data); + return TLSX_SNI_GetRequest(ssl->extensions, type, data, 0); return 0; } @@ -17745,7 +17745,7 @@ WOLFSSL_X509* wolfSSL_get_chain_X509(WOLFSSL_X509_CHAIN* chain, int idx) #endif WOLFSSL_ENTER("wolfSSL_get_chain_X509"); - if (chain != NULL) { + if (chain != NULL && idx < MAX_CHAIN_DEPTH) { #ifdef WOLFSSL_SMALL_STACK cert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), NULL, DYNAMIC_TYPE_DCERT); @@ -20025,17 +20025,17 @@ int wolfSSL_set_tlsext_host_name(WOLFSSL* ssl, const char* host_name) return ret; } - -#ifndef NO_WOLFSSL_SERVER +/* May be called by server to get the requested accepted name and by the client + * to get the requested name. */ const char * wolfSSL_get_servername(WOLFSSL* ssl, byte type) { void * serverName = NULL; if (ssl == NULL) return NULL; - TLSX_SNI_GetRequest(ssl->extensions, type, &serverName); + TLSX_SNI_GetRequest(ssl->extensions, type, &serverName, + !wolfSSL_is_server(ssl)); return (const char *)serverName; } -#endif /* NO_WOLFSSL_SERVER */ #endif /* HAVE_SNI */ WOLFSSL_CTX* wolfSSL_set_SSL_CTX(WOLFSSL* ssl, WOLFSSL_CTX* ctx) @@ -20063,6 +20063,13 @@ WOLFSSL_CTX* wolfSSL_set_SSL_CTX(WOLFSSL* ssl, WOLFSSL_CTX* ctx) if (ssl->ctx == ctx) return ssl->ctx; + if (ctx->suites == NULL) { + /* suites */ + if (AllocateCtxSuites(ctx) != 0) + return NULL; + InitSSL_CTX_Suites(ctx); + } + wolfSSL_RefInc(&ctx->ref, &ret); #ifdef WOLFSSL_REFCNT_ERROR_RETURN if (ret != 0) { @@ -20988,8 +20995,9 @@ long wolfSSL_CTX_get_tlsext_ticket_keys(WOLFSSL_CTX *ctx, * correct length. */ long wolfSSL_CTX_set_tlsext_ticket_keys(WOLFSSL_CTX *ctx, - unsigned char *keys, int keylen) + const void *keys_vp, int keylen) { + const byte* keys = (const byte*)keys_vp; if (ctx == NULL || keys == NULL) { return WOLFSSL_FAILURE; } diff --git a/src/ssl_asn1.c b/src/ssl_asn1.c index eecf46748c..8c3e7c1cd3 100644 --- a/src/ssl_asn1.c +++ b/src/ssl_asn1.c @@ -2997,7 +2997,7 @@ void wolfSSL_ASN1_GENERALIZEDTIME_free(WOLFSSL_ASN1_TIME* asn1Time) { WOLFSSL_ENTER("wolfSSL_ASN1_GENERALIZEDTIME_free"); if (asn1Time != NULL) { - XMEMSET(asn1Time->data, 0, sizeof(asn1Time->data)); + XFREE(asn1Time, NULL, DYNAMIC_TYPE_OPENSSL); } } @@ -3538,6 +3538,32 @@ WOLFSSL_ASN1_TIME* wolfSSL_ASN1_TIME_to_generalizedtime(WOLFSSL_ASN1_TIME *t, return ret; } +WOLFSSL_ASN1_TIME* wolfSSL_ASN1_UTCTIME_set(WOLFSSL_ASN1_TIME *s, time_t t) +{ + WOLFSSL_ASN1_TIME* ret = s; + + WOLFSSL_ENTER("wolfSSL_ASN1_UTCTIME_set"); + + if (ret == NULL) { + ret = wolfSSL_ASN1_TIME_new(); + if (ret == NULL) + return NULL; + } + + ret->length = GetFormattedTime(&t, ret->data, sizeof(ret->data)); + if (ret->length + 1 != ASN_UTC_TIME_SIZE) { + /* Either snprintf error or t can't be represented in UTC format */ + if (ret != s) + wolfSSL_ASN1_TIME_free(ret); + ret = NULL; + } + else { + ret->type = V_ASN1_UTCTIME; + } + + return ret; +} + #endif /* OPENSSL_EXTRA */ #if defined(WOLFSSL_MYSQL_COMPATIBLE) || defined(OPENSSL_EXTRA) diff --git a/src/tls.c b/src/tls.c index 5a8380425e..1a347a7579 100644 --- a/src/tls.c +++ b/src/tls.c @@ -2407,12 +2407,13 @@ int TLSX_UseSNI(TLSX** extensions, byte type, const void* data, word16 size, #ifndef NO_WOLFSSL_SERVER /** Tells the SNI requested by the client. */ -word16 TLSX_SNI_GetRequest(TLSX* extensions, byte type, void** data) +word16 TLSX_SNI_GetRequest(TLSX* extensions, byte type, void** data, + byte ignoreStatus) { TLSX* extension = TLSX_Find(extensions, TLSX_SERVER_NAME); SNI* sni = TLSX_SNI_Find(extension ? (SNI*)extension->data : NULL, type); - if (sni && sni->status != WOLFSSL_SNI_NO_MATCH) { + if (sni && (ignoreStatus || sni->status != WOLFSSL_SNI_NO_MATCH)) { switch (sni->type) { case WOLFSSL_SNI_HOST_NAME: if (data) { diff --git a/src/x509.c b/src/x509.c index 42e34153ad..d85d8db968 100644 --- a/src/x509.c +++ b/src/x509.c @@ -12094,7 +12094,6 @@ WOLFSSL_ASN1_OBJECT* wolfSSL_X509_NAME_ENTRY_get_object( static int RebuildFullName(WOLFSSL_X509_NAME* name) { int totalLen = 0, i, idx, entryCount = 0; - char* fullName; if (name == NULL) return BAD_FUNC_ARG; @@ -12114,23 +12113,26 @@ WOLFSSL_ASN1_OBJECT* wolfSSL_X509_NAME_ENTRY_get_object( } } - fullName = (char*)XMALLOC(totalLen + 1, name->heap, DYNAMIC_TYPE_X509); - if (fullName == NULL) - return MEMORY_E; + if (name->dynamicName) { + XFREE(name->name, name->heap, DYNAMIC_TYPE_X509); + name->name = name->staticName; + name->dynamicName = 0; + } + + if (totalLen >= ASN_NAME_MAX) { + name->name = (char*)XMALLOC(totalLen + 1, name->heap, + DYNAMIC_TYPE_X509); + if (name->name == NULL) + return MEMORY_E; + name->dynamicName = 1; + } idx = 0; - entryCount = AddAllEntry(name, fullName, totalLen, &idx); - if (entryCount < 0) { - XFREE(fullName, name->heap, DYNAMIC_TYPE_X509); + entryCount = AddAllEntry(name, name->name, totalLen, &idx); + if (entryCount < 0) return entryCount; - } - if (name->dynamicName) { - XFREE(name->name, name->heap, DYNAMIC_TYPE_X509); - } - fullName[idx] = '\0'; - name->name = fullName; - name->dynamicName = 1; + name->name[idx] = '\0'; name->sz = idx + 1; /* size includes null terminator */ name->entrySz = entryCount; @@ -13899,6 +13901,16 @@ int wolfSSL_X509_set_notBefore(WOLFSSL_X509* x509, const WOLFSSL_ASN1_TIME* t) return WOLFSSL_SUCCESS; } +int wolfSSL_X509_set1_notAfter(WOLFSSL_X509* x509, const WOLFSSL_ASN1_TIME *t) +{ + return wolfSSL_X509_set_notAfter(x509, t); +} + +int wolfSSL_X509_set1_notBefore(WOLFSSL_X509* x509, const WOLFSSL_ASN1_TIME *t) +{ + return wolfSSL_X509_set_notBefore(x509, t); +} + int wolfSSL_X509_set_serialNumber(WOLFSSL_X509* x509, WOLFSSL_ASN1_INTEGER* s) { WOLFSSL_ENTER("wolfSSL_X509_set_serialNumber"); diff --git a/src/x509_str.c b/src/x509_str.c index a38f93b205..ed070e0901 100644 --- a/src/x509_str.c +++ b/src/x509_str.c @@ -40,27 +40,59 @@ * START OF X509_STORE_CTX APIs ******************************************************************************/ -#ifdef OPENSSL_EXTRA - -WOLFSSL_X509_STORE_CTX* wolfSSL_X509_STORE_CTX_new(void) +/* This API is necessary outside of OPENSSL_EXTRA because it is used in + * SetupStoreCtxCallback */ +WOLFSSL_X509_STORE_CTX* wolfSSL_X509_STORE_CTX_new_ex(void* heap) { WOLFSSL_X509_STORE_CTX* ctx; - WOLFSSL_ENTER("wolfSSL_X509_STORE_CTX_new"); + WOLFSSL_ENTER("wolfSSL_X509_STORE_CTX_new_ex"); - ctx = (WOLFSSL_X509_STORE_CTX*)XMALLOC(sizeof(WOLFSSL_X509_STORE_CTX), NULL, + ctx = (WOLFSSL_X509_STORE_CTX*)XMALLOC(sizeof(WOLFSSL_X509_STORE_CTX), heap, DYNAMIC_TYPE_X509_CTX); if (ctx != NULL) { - ctx->param = NULL; + XMEMSET(ctx, 0, sizeof(WOLFSSL_X509_STORE_CTX)); + ctx->heap = heap; +#ifdef OPENSSL_EXTRA if (wolfSSL_X509_STORE_CTX_init(ctx, NULL, NULL, NULL) != WOLFSSL_SUCCESS) { - XFREE(ctx, NULL, DYNAMIC_TYPE_X509_CTX); + XFREE(ctx, heap, DYNAMIC_TYPE_X509_CTX); ctx = NULL; } +#endif } return ctx; } +/* This API is necessary outside of OPENSSL_EXTRA because it is used in + * SetupStoreCtxCallback */ +/* free's extra data */ +void wolfSSL_X509_STORE_CTX_free(WOLFSSL_X509_STORE_CTX* ctx) +{ + WOLFSSL_ENTER("wolfSSL_X509_STORE_CTX_free"); + if (ctx != NULL) { +#ifdef HAVE_EX_DATA_CLEANUP_HOOKS + wolfSSL_CRYPTO_cleanup_ex_data(&ctx->ex_data); +#endif + +#ifdef OPENSSL_EXTRA + if (ctx->param != NULL) { + XFREE(ctx->param, ctx->heap, DYNAMIC_TYPE_OPENSSL); + ctx->param = NULL; + } +#endif + + XFREE(ctx, ctx->heap, DYNAMIC_TYPE_X509_CTX); + } +} + +#ifdef OPENSSL_EXTRA + +WOLFSSL_X509_STORE_CTX* wolfSSL_X509_STORE_CTX_new(void) +{ + WOLFSSL_ENTER("wolfSSL_X509_STORE_CTX_new"); + return wolfSSL_X509_STORE_CTX_new_ex(NULL); +} int wolfSSL_X509_STORE_CTX_init(WOLFSSL_X509_STORE_CTX* ctx, WOLFSSL_X509_STORE* store, WOLFSSL_X509* x509, @@ -134,11 +166,12 @@ int wolfSSL_X509_STORE_CTX_init(WOLFSSL_X509_STORE_CTX* ctx, if (ctx->param == NULL) { ctx->param = (WOLFSSL_X509_VERIFY_PARAM*)XMALLOC( sizeof(WOLFSSL_X509_VERIFY_PARAM), - NULL, DYNAMIC_TYPE_OPENSSL); + ctx->heap, DYNAMIC_TYPE_OPENSSL); if (ctx->param == NULL){ WOLFSSL_MSG("wolfSSL_X509_STORE_CTX_init failed"); return WOLFSSL_FAILURE; } + XMEMSET(ctx->param, 0, sizeof(*ctx->param)); } return WOLFSSL_SUCCESS; @@ -146,25 +179,6 @@ int wolfSSL_X509_STORE_CTX_init(WOLFSSL_X509_STORE_CTX* ctx, return WOLFSSL_FAILURE; } - -/* free's extra data */ -void wolfSSL_X509_STORE_CTX_free(WOLFSSL_X509_STORE_CTX* ctx) -{ - WOLFSSL_ENTER("wolfSSL_X509_STORE_CTX_free"); - if (ctx != NULL) { -#ifdef HAVE_EX_DATA_CLEANUP_HOOKS - wolfSSL_CRYPTO_cleanup_ex_data(&ctx->ex_data); -#endif - - if (ctx->param != NULL) { - XFREE(ctx->param, NULL, DYNAMIC_TYPE_OPENSSL); - ctx->param = NULL; - } - - XFREE(ctx, NULL, DYNAMIC_TYPE_X509_CTX); - } -} - /* Its recommended to use a full free -> init cycle of all the objects * because wolfSSL_X509_STORE_CTX_init may modify the store too which doesn't * get reset here. */ @@ -173,7 +187,7 @@ void wolfSSL_X509_STORE_CTX_cleanup(WOLFSSL_X509_STORE_CTX* ctx) if (ctx != NULL) { if (ctx->param != NULL) { - XFREE(ctx->param, NULL, DYNAMIC_TYPE_OPENSSL); + XFREE(ctx->param, ctx->heap, DYNAMIC_TYPE_OPENSSL); ctx->param = NULL; } @@ -212,6 +226,8 @@ int GetX509Error(int e) return WOLFSSL_X509_V_ERR_CERT_SIGNATURE_FAILURE; case CRL_CERT_REVOKED: return WOLFSSL_X509_V_ERR_CERT_REVOKED; + case CRL_MISSING: + return X509_V_ERR_UNABLE_TO_GET_CRL; case 0: case 1: return 0; @@ -504,39 +520,19 @@ WOLFSSL_STACK* wolfSSL_X509_STORE_CTX_get_chain(WOLFSSL_X509_STORE_CTX* ctx) /* if chain is null but sesChain is available then populate stack */ if (ctx->chain == NULL && ctx->sesChain != NULL) { int i; + int error = 0; WOLFSSL_X509_CHAIN* c = ctx->sesChain; - WOLFSSL_STACK* sk = (WOLFSSL_STACK*)XMALLOC(sizeof(WOLFSSL_STACK), - NULL, DYNAMIC_TYPE_X509); + WOLFSSL_STACK* sk = wolfSSL_sk_new_node(ctx->heap); - if (sk == NULL) { + if (sk == NULL) return NULL; - } - - XMEMSET(sk, 0, sizeof(WOLFSSL_STACK)); - - for (i = 0; i < c->count && i < MAX_CHAIN_DEPTH; i++) { - WOLFSSL_X509* x509 = wolfSSL_get_chain_X509(c, i); - - if (x509 == NULL) { - WOLFSSL_MSG("Unable to get x509 from chain"); - wolfSSL_sk_X509_pop_free(sk, NULL); - return NULL; - } - - if (wolfSSL_sk_X509_push(sk, x509) != WOLFSSL_SUCCESS) { - WOLFSSL_MSG("Unable to load x509 into stack"); - wolfSSL_sk_X509_pop_free(sk, NULL); - wolfSSL_X509_free(x509); - return NULL; - } - } #if defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY) || defined(OPENSSL_EXTRA) /* add CA used to verify top of chain to the list */ if (c->count > 0) { WOLFSSL_X509* x509 = wolfSSL_get_chain_X509(c, c->count - 1); + WOLFSSL_X509* issuer = NULL; if (x509 != NULL) { - WOLFSSL_X509* issuer = NULL; if (wolfSSL_X509_STORE_CTX_get1_issuer(&issuer, ctx, x509) == WOLFSSL_SUCCESS) { /* check that the certificate being looked up is not self @@ -545,24 +541,47 @@ WOLFSSL_STACK* wolfSSL_X509_STORE_CTX_get_chain(WOLFSSL_X509_STORE_CTX* ctx) &x509->subject) != 0) { if (wolfSSL_sk_X509_push(sk, issuer) != WOLFSSL_SUCCESS) { WOLFSSL_MSG("Unable to load CA x509 into stack"); - wolfSSL_sk_X509_pop_free(sk, NULL); - wolfSSL_X509_free(issuer); - return NULL; + error = 1; } } else { WOLFSSL_MSG("Certificate is self signed"); - if (issuer != NULL) - wolfSSL_X509_free(issuer); + wolfSSL_X509_free(issuer); } } else { - wolfSSL_X509_free(x509); WOLFSSL_MSG("Could not find CA for certificate"); } } + wolfSSL_X509_free(x509); + if (error) { + wolfSSL_sk_X509_pop_free(sk, NULL); + wolfSSL_X509_free(issuer); + return NULL; + } } #endif + + for (i = c->count - 1; i >= 0; i--) { + WOLFSSL_X509* x509 = wolfSSL_get_chain_X509(c, i); + + if (x509 == NULL) { + WOLFSSL_MSG("Unable to get x509 from chain"); + error = 1; + break; + } + + if (wolfSSL_sk_X509_push(sk, x509) != WOLFSSL_SUCCESS) { + WOLFSSL_MSG("Unable to load x509 into stack"); + wolfSSL_X509_free(x509); + error = 1; + break; + } + } + if (error) { + wolfSSL_sk_X509_pop_free(sk, NULL); + return NULL; + } ctx->chain = sk; } #endif /* SESSION_CERTS */ @@ -611,6 +630,14 @@ int wolfSSL_X509_STORE_get_by_subject(WOLFSSL_X509_STORE_CTX* ctx, int idx, } #endif +WOLFSSL_X509_VERIFY_PARAM *wolfSSL_X509_STORE_CTX_get0_param( + WOLFSSL_X509_STORE_CTX *ctx) +{ + if (ctx == NULL) + return NULL; + + return ctx->param; +} #endif /* OPENSSL_EXTRA */ @@ -935,14 +962,33 @@ int wolfSSL_X509_STORE_set_ex_data_with_cleanup( #ifdef OPENSSL_EXTRA #if defined(WOLFSSL_QT) || defined(OPENSSL_ALL) - void wolfSSL_X509_STORE_set_verify_cb(WOLFSSL_X509_STORE *st, - WOLFSSL_X509_STORE_CTX_verify_cb verify_cb) - { - WOLFSSL_ENTER("wolfSSL_X509_STORE_set_verify_cb"); - if (st != NULL) { - st->verify_cb = verify_cb; - } +void wolfSSL_X509_STORE_set_verify_cb(WOLFSSL_X509_STORE *st, + WOLFSSL_X509_STORE_CTX_verify_cb verify_cb) +{ + WOLFSSL_ENTER("wolfSSL_X509_STORE_set_verify_cb"); + if (st != NULL) { + st->verify_cb = verify_cb; } +} + +void wolfSSL_X509_STORE_set_get_crl(WOLFSSL_X509_STORE *st, + WOLFSSL_X509_STORE_CTX_get_crl_cb get_cb) +{ + WOLFSSL_ENTER("wolfSSL_X509_STORE_set_get_crl"); + if (st != NULL) { + st->get_crl_cb = get_cb; + } +} + +#ifndef NO_WOLFSSL_STUB +void wolfSSL_X509_STORE_set_check_crl(WOLFSSL_X509_STORE *st, + WOLFSSL_X509_STORE_CTX_check_crl_cb check_crl) +{ + (void)st; + (void)check_crl; + WOLFSSL_STUB("wolfSSL_X509_STORE_set_check_crl (not implemented)"); +} +#endif #endif /* WOLFSSL_QT || OPENSSL_ALL */ WOLFSSL_X509_LOOKUP* wolfSSL_X509_STORE_add_lookup(WOLFSSL_X509_STORE* store, @@ -1328,6 +1374,17 @@ WOLF_STACK_OF(WOLFSSL_X509_OBJECT)* wolfSSL_X509_STORE_get0_objects( } #endif /* OPENSSL_ALL */ +#if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER) || \ + defined(WOLFSSL_WPAS_SMALL) +WOLFSSL_X509_VERIFY_PARAM *wolfSSL_X509_STORE_get0_param( + const WOLFSSL_X509_STORE *ctx) +{ + if (ctx == NULL) + return NULL; + return ctx->param; +} +#endif + /******************************************************************************* * END OF X509_STORE APIs ******************************************************************************/ diff --git a/tests/api.c b/tests/api.c index 7d2be356b6..38f75e93de 100644 --- a/tests/api.c +++ b/tests/api.c @@ -32408,20 +32408,11 @@ static int test_wolfSSL_ASN1_GENERALIZEDTIME_free(void) EXPECT_DECLS; #if defined(OPENSSL_EXTRA) WOLFSSL_ASN1_GENERALIZEDTIME* asn1_gtime = NULL; - unsigned char nullstr[32]; - XMEMSET(nullstr, 0, 32); - ExpectNotNull(asn1_gtime = (WOLFSSL_ASN1_GENERALIZEDTIME*)XMALLOC( - sizeof(WOLFSSL_ASN1_GENERALIZEDTIME), NULL, DYNAMIC_TYPE_TMP_BUFFER)); - if (asn1_gtime != NULL) { - XMEMCPY(asn1_gtime->data,"20180504123500Z",ASN_GENERALIZED_TIME_SIZE); - - wolfSSL_ASN1_GENERALIZEDTIME_free(asn1_gtime); - ExpectIntEQ(0, XMEMCMP(asn1_gtime->data, nullstr, 32)); - - XFREE(asn1_gtime, NULL, DYNAMIC_TYPE_TMP_BUFFER); - } - wolfSSL_ASN1_GENERALIZEDTIME_free(NULL); + ExpectNotNull(asn1_gtime = ASN1_GENERALIZEDTIME_new()); + if (asn1_gtime != NULL) + XMEMCPY(asn1_gtime->data, "20180504123500Z", ASN_GENERALIZED_TIME_SIZE); + ASN1_GENERALIZEDTIME_free(asn1_gtime); #endif /* OPENSSL_EXTRA */ return EXPECT_RESULT(); } @@ -32430,7 +32421,7 @@ static int test_wolfSSL_ASN1_GENERALIZEDTIME_print(void) { EXPECT_DECLS; #if defined(OPENSSL_EXTRA) && !defined(NO_BIO) - WOLFSSL_ASN1_GENERALIZEDTIME gtime; + WOLFSSL_ASN1_GENERALIZEDTIME* gtime = NULL; BIO* bio = NULL; unsigned char buf[24]; int i; @@ -32438,19 +32429,17 @@ static int test_wolfSSL_ASN1_GENERALIZEDTIME_print(void) ExpectNotNull(bio = BIO_new(BIO_s_mem())); BIO_set_write_buf_size(bio, 24); - XMEMSET(>ime, 0, sizeof(WOLFSSL_ASN1_GENERALIZEDTIME)); - XMEMCPY(gtime.data, "20180504123500Z", ASN_GENERALIZED_TIME_SIZE); - gtime.length = ASN_GENERALIZED_TIME_SIZE; + ExpectNotNull(gtime = ASN1_GENERALIZEDTIME_new()); /* Type not set. */ - ExpectIntEQ(wolfSSL_ASN1_GENERALIZEDTIME_print(bio, >ime), 0); - gtime.type = V_ASN1_GENERALIZEDTIME; + ExpectIntEQ(wolfSSL_ASN1_GENERALIZEDTIME_print(bio, gtime), 0); + ExpectIntEQ(wolfSSL_ASN1_TIME_set_string(gtime, "20180504123500Z"), 1); /* Invalid parameters testing. */ ExpectIntEQ(wolfSSL_ASN1_GENERALIZEDTIME_print(NULL, NULL), BAD_FUNC_ARG); ExpectIntEQ(wolfSSL_ASN1_GENERALIZEDTIME_print(bio, NULL), BAD_FUNC_ARG); - ExpectIntEQ(wolfSSL_ASN1_GENERALIZEDTIME_print(NULL, >ime), BAD_FUNC_ARG); + ExpectIntEQ(wolfSSL_ASN1_GENERALIZEDTIME_print(NULL, gtime), BAD_FUNC_ARG); - ExpectIntEQ(wolfSSL_ASN1_GENERALIZEDTIME_print(bio, >ime), 1); + ExpectIntEQ(wolfSSL_ASN1_GENERALIZEDTIME_print(bio, gtime), 1); ExpectIntEQ(BIO_read(bio, buf, sizeof(buf)), 20); ExpectIntEQ(XMEMCMP(buf, "May 04 12:35:00 2018", 20), 0); @@ -32461,14 +32450,14 @@ static int test_wolfSSL_ASN1_GENERALIZEDTIME_print(void) ExpectIntEQ(BIO_set_write_buf_size(bio, 1), 1); /* Ensure there is 0 bytes available to write into. */ ExpectIntEQ(BIO_write(bio, buf, 1), 1); - ExpectIntEQ(wolfSSL_ASN1_GENERALIZEDTIME_print(bio, >ime), 0); + ExpectIntEQ(wolfSSL_ASN1_GENERALIZEDTIME_print(bio, gtime), 0); for (i = 1; i < 20; i++) { ExpectIntEQ(BIO_set_write_buf_size(bio, i), 1); - ExpectIntEQ(wolfSSL_ASN1_GENERALIZEDTIME_print(bio, >ime), 0); + ExpectIntEQ(wolfSSL_ASN1_GENERALIZEDTIME_print(bio, gtime), 0); } BIO_free(bio); - wolfSSL_ASN1_GENERALIZEDTIME_free(>ime); + wolfSSL_ASN1_GENERALIZEDTIME_free(gtime); #endif /* OPENSSL_EXTRA */ return EXPECT_RESULT(); } @@ -41651,6 +41640,13 @@ static int test_wolfSSL_X509_sign(void) #endif #endif /* WOLFSSL_ALT_NAMES */ + { + ASN1_UTCTIME* infinite_past = NULL; + ExpectNotNull(infinite_past = ASN1_UTCTIME_set(NULL, 0)); + ExpectIntEQ(X509_set1_notBefore(x509, infinite_past), 1); + ASN1_UTCTIME_free(infinite_past); + } + /* test valid sign case */ ExpectIntGT(ret = X509_sign(x509, priv, EVP_sha256()), 0); @@ -55183,7 +55179,8 @@ static int test_X509_LOOKUP_add_dir(void) /* Now we SHOULD get CRL_MISSING, because we looked for PEM * in dir containing only ASN1/DER. */ ExpectIntEQ(X509_verify_cert(storeCtx), WOLFSSL_FAILURE); - ExpectIntEQ(X509_STORE_CTX_get_error(storeCtx), CRL_MISSING); + ExpectIntEQ(X509_STORE_CTX_get_error(storeCtx), + X509_V_ERR_UNABLE_TO_GET_CRL); X509_CRL_free(crl); X509_STORE_free(store); @@ -58647,6 +58644,155 @@ static int test_wolfSSL_X509_STORE_get1_certs(void) #endif /* OPENSSL_EXTRA && WOLFSSL_SIGNER_DER_CERT && !NO_FILESYSTEM */ return EXPECT_RESULT(); } + +#if defined(HAVE_SSL_MEMIO_TESTS_DEPENDENCIES) && \ + defined(WOLFSSL_LOCAL_X509_STORE) && \ + (defined(OPENSSL_ALL) || defined(WOLFSSL_QT)) && defined(HAVE_CRL) +static int test_wolfSSL_X509_STORE_set_get_crl_provider(X509_STORE_CTX* ctx, + X509_CRL** crl_out, X509* cert) { + X509_CRL *crl = NULL; + XFILE fp = XBADFILE; + char* cert_issuer = X509_NAME_oneline(X509_get_issuer_name(cert), NULL, 0); + int ret = 0; + + (void)ctx; + + if (cert_issuer == NULL) + return 0; + + if ((fp = XFOPEN("certs/crl/crl.pem", "rb")) != XBADFILE) { + PEM_read_X509_CRL(fp, &crl, NULL, NULL); + XFCLOSE(fp); + if (crl != NULL) { + char* crl_issuer = X509_NAME_oneline( + X509_CRL_get_issuer(crl), NULL, 0); + if (XSTRCMP(cert_issuer, crl_issuer) == 0) { + *crl_out = X509_CRL_dup(crl); + if (*crl_out != NULL) + ret = 1; + } + OPENSSL_free(crl_issuer); + } + } + + X509_CRL_free(crl); + OPENSSL_free(cert_issuer); + return ret; +} + +static int test_wolfSSL_X509_STORE_set_get_crl_provider2(X509_STORE_CTX* ctx, + X509_CRL** crl_out, X509* cert) { + (void)ctx; + (void)cert; + *crl_out = NULL; + return 1; +} + +#ifndef NO_WOLFSSL_STUB +static int test_wolfSSL_X509_STORE_set_get_crl_check(X509_STORE_CTX* ctx, + X509_CRL* crl) { + (void)ctx; + (void)crl; + return 1; +} +#endif + +static int test_wolfSSL_X509_STORE_set_get_crl_verify(int ok, + X509_STORE_CTX* ctx) { + int cert_error = X509_STORE_CTX_get_error(ctx); + X509_VERIFY_PARAM* param = X509_STORE_CTX_get0_param(ctx); + int flags = X509_VERIFY_PARAM_get_flags(param); + if ((flags & (X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL)) != + (X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL)) { + /* Make sure the flags are set */ + return 0; + } + /* Ignore CRL missing error */ +#ifndef OPENSSL_COMPATIBLE_DEFAULTS + if (cert_error == CRL_MISSING) +#else + if (cert_error == X509_V_ERR_UNABLE_TO_GET_CRL) +#endif + return 1; + return ok; +} + +static int test_wolfSSL_X509_STORE_set_get_crl_ctx_ready(WOLFSSL_CTX* ctx) +{ + EXPECT_DECLS; + X509_STORE* cert_store = NULL; + + ExpectIntEQ(wolfSSL_CTX_EnableCRL(ctx, WOLFSSL_CRL_CHECKALL), + WOLFSSL_SUCCESS); + ExpectNotNull(cert_store = SSL_CTX_get_cert_store(ctx)); + X509_STORE_set_get_crl(cert_store, + test_wolfSSL_X509_STORE_set_get_crl_provider); +#ifndef NO_WOLFSSL_STUB + X509_STORE_set_check_crl(cert_store, + test_wolfSSL_X509_STORE_set_get_crl_check); +#endif + + return EXPECT_RESULT(); +} + +static int test_wolfSSL_X509_STORE_set_get_crl_ctx_ready2(WOLFSSL_CTX* ctx) +{ + EXPECT_DECLS; + X509_STORE* cert_store = NULL; + X509_VERIFY_PARAM* param = NULL; + + SSL_CTX_set_verify(ctx, WOLFSSL_VERIFY_PEER, NULL); + ExpectIntEQ(wolfSSL_CTX_EnableCRL(ctx, WOLFSSL_CRL_CHECKALL), + WOLFSSL_SUCCESS); + ExpectNotNull(cert_store = SSL_CTX_get_cert_store(ctx)); + X509_STORE_set_get_crl(cert_store, + test_wolfSSL_X509_STORE_set_get_crl_provider2); +#ifndef NO_WOLFSSL_STUB + X509_STORE_set_check_crl(cert_store, + test_wolfSSL_X509_STORE_set_get_crl_check); +#endif + X509_STORE_set_verify_cb(cert_store, + test_wolfSSL_X509_STORE_set_get_crl_verify); + ExpectNotNull(param = X509_STORE_get0_param(cert_store)); + ExpectIntEQ(X509_VERIFY_PARAM_set_flags( + param, X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL), 1); + ExpectIntEQ(X509_STORE_set_flags(cert_store, + X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL), 1); + + return EXPECT_RESULT(); +} +#endif + +/* This test mimics the usage of the CRL provider in gRPC */ +static int test_wolfSSL_X509_STORE_set_get_crl(void) +{ + EXPECT_DECLS; +#if defined(HAVE_SSL_MEMIO_TESTS_DEPENDENCIES) && \ + defined(WOLFSSL_LOCAL_X509_STORE) && \ + (defined(OPENSSL_ALL) || defined(WOLFSSL_QT)) && defined(HAVE_CRL) + test_ssl_cbf func_cb_client; + test_ssl_cbf func_cb_server; + + XMEMSET(&func_cb_client, 0, sizeof(func_cb_client)); + XMEMSET(&func_cb_server, 0, sizeof(func_cb_server)); + + func_cb_client.ctx_ready = test_wolfSSL_X509_STORE_set_get_crl_ctx_ready; + + ExpectIntEQ(test_wolfSSL_client_server_nofail_memio(&func_cb_client, + &func_cb_server, NULL), TEST_SUCCESS); + + XMEMSET(&func_cb_client, 0, sizeof(func_cb_client)); + XMEMSET(&func_cb_server, 0, sizeof(func_cb_server)); + + func_cb_client.ctx_ready = test_wolfSSL_X509_STORE_set_get_crl_ctx_ready2; + + ExpectIntEQ(test_wolfSSL_client_server_nofail_memio(&func_cb_client, + &func_cb_server, NULL), TEST_SUCCESS); +#endif + return EXPECT_RESULT(); +} + + static int test_wolfSSL_dup_CA_list(void) { int res = TEST_SKIPPED; @@ -70724,11 +70870,7 @@ static int test_revoked_loaded_int_cert(void) ExpectIntEQ(test_wolfSSL_client_server_nofail_memio(&client_cbf, &server_cbf, NULL), TEST_FAIL); -#ifndef WOLFSSL_HAPROXY ExpectIntEQ(client_cbf.last_err, CRL_CERT_REVOKED); -#else - ExpectIntEQ(client_cbf.last_err, WOLFSSL_X509_V_ERR_CERT_REVOKED); -#endif ExpectIntEQ(server_cbf.last_err, FATAL_ERROR); if (!EXPECT_SUCCESS()) @@ -72647,6 +72789,7 @@ TEST_CASE testCases[] = { TEST_DECL(test_X509_STORE_get0_objects), TEST_DECL(test_wolfSSL_X509_load_crl_file), TEST_DECL(test_wolfSSL_X509_STORE_get1_certs), + TEST_DECL(test_wolfSSL_X509_STORE_set_get_crl), TEST_DECL(test_wolfSSL_X509_NAME_ENTRY_get_object), TEST_DECL(test_wolfSSL_X509_cmp_time), TEST_DECL(test_wolfSSL_X509_time_adj), diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index a2ed849e16..b444af94cb 100644 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -11408,6 +11408,47 @@ DNS_entry* AltNameNew(void* heap) return ret; } +DNS_entry* AltNameDup(DNS_entry* from, void* heap) +{ + DNS_entry* ret; + + ret = AltNameNew(heap); + if (ret == NULL) { + WOLFSSL_MSG("\tOut of Memory"); + return NULL; + } + + ret->type = from->type; + ret->len = from->len; + + + ret->name = CopyString(from->name, from->len, heap, DYNAMIC_TYPE_ALTNAME); +#if defined(OPENSSL_ALL) || defined(WOLFSSL_IP_ALT_NAME) + ret->ipString = CopyString(from->ipString, 0, heap, DYNAMIC_TYPE_ALTNAME); +#endif +#ifdef OPENSSL_ALL + ret->ridString = CopyString(from->ridString, 0, heap, DYNAMIC_TYPE_ALTNAME); +#endif + if (ret->name == NULL +#if defined(OPENSSL_ALL) || defined(WOLFSSL_IP_ALT_NAME) + || (from->ipString != NULL && ret->ipString == NULL) +#endif +#ifdef OPENSSL_ALL + || (from->ridString != NULL && ret->ridString == NULL) +#endif + ) { + WOLFSSL_MSG("\tOut of Memory"); + FreeAltNames(ret, heap); + return NULL; + } + +#ifdef WOLFSSL_FPKI + ret->oidSum = from->oidSum; +#endif + + return ret; +} + #ifndef IGNORE_NAME_CONSTRAINTS diff --git a/wolfcrypt/src/misc.c b/wolfcrypt/src/misc.c index af5f09abb7..a0f53cfddc 100644 --- a/wolfcrypt/src/misc.c +++ b/wolfcrypt/src/misc.c @@ -1001,6 +1001,25 @@ WC_MISC_STATIC WC_INLINE word32 HashObject(const byte* o, word32 len, #endif /* WOLFCRYPT_ONLY && !NO_HASH_WRAPPER && * (!NO_SESSION_CACHE || HAVE_SESSION_TICKET) */ +WC_MISC_STATIC WC_INLINE char* CopyString(const char* src, int srcLen, + void* heap, int type) { + char* dst = NULL; + + if (src == NULL) + return NULL; + + if (srcLen <= 0) + srcLen = (int)XSTRLEN(src); + + dst = (char*)XMALLOC(srcLen + 1, heap, type); + if (dst != NULL) { + XMEMCPY(dst, src, srcLen); + dst[srcLen] = '\0'; + } + + return dst; +} + #endif /* !WOLFSSL_MISC_INCLUDED && !NO_INLINE */ #endif /* WOLF_CRYPT_MISC_C */ diff --git a/wolfssl/internal.h b/wolfssl/internal.h index 34bfc53047..bd19a7f2f7 100644 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -2689,6 +2689,14 @@ typedef struct ProcPeerCertArgs { } ProcPeerCertArgs; WOLFSSL_LOCAL int DoVerifyCallback(WOLFSSL_CERT_MANAGER* cm, WOLFSSL* ssl, int ret, ProcPeerCertArgs* args); +WOLFSSL_LOCAL void DoCrlCallback(WOLFSSL_CERT_MANAGER* cm, WOLFSSL* ssl, + ProcPeerCertArgs* args, int* outRet); + +WOLFSSL_LOCAL int SetupStoreCtxCallback(WOLFSSL_X509_STORE_CTX** store_pt, + WOLFSSL* ssl, WOLFSSL_CERT_MANAGER* cm, ProcPeerCertArgs* args, + int cert_err, void* heap, int* x509Free); +WOLFSSL_LOCAL void CleanupStoreCtxCallback(WOLFSSL_X509_STORE_CTX* store, + WOLFSSL* ssl, void* heap, int x509Free); #endif /* !defined(NO_WOLFSSL_CLIENT) || !defined(WOLFSSL_NO_CLIENT_AUTH) */ #endif /* !defined NO_CERTS */ @@ -3050,7 +3058,7 @@ WOLFSSL_LOCAL int TLSX_UseSNI(TLSX** extensions, byte type, const void* data, word16 size, void* heap); WOLFSSL_LOCAL byte TLSX_SNI_Status(TLSX* extensions, byte type); WOLFSSL_LOCAL word16 TLSX_SNI_GetRequest(TLSX* extensions, byte type, - void** data); + void** data, byte ignoreStatus); #ifndef NO_WOLFSSL_SERVER WOLFSSL_LOCAL void TLSX_SNI_SetOptions(TLSX* extensions, byte type, diff --git a/wolfssl/openssl/evp.h b/wolfssl/openssl/evp.h index bdeabf2556..346cefc65d 100644 --- a/wolfssl/openssl/evp.h +++ b/wolfssl/openssl/evp.h @@ -401,6 +401,7 @@ typedef union { #define NID_X9_62_id_ecPublicKey EVP_PKEY_EC #define NID_rsaEncryption EVP_PKEY_RSA +#define NID_rsa EVP_PKEY_RSA #define NID_dsa EVP_PKEY_DSA #define EVP_PKEY_OP_SIGN (1 << 3) diff --git a/wolfssl/openssl/ssl.h b/wolfssl/openssl/ssl.h index 39abccb260..edf7e379b6 100644 --- a/wolfssl/openssl/ssl.h +++ b/wolfssl/openssl/ssl.h @@ -501,6 +501,8 @@ typedef STACK_OF(ACCESS_DESCRIPTION) AUTHORITY_INFO_ACCESS; #define X509_set_pubkey wolfSSL_X509_set_pubkey #define X509_set_notAfter wolfSSL_X509_set_notAfter #define X509_set_notBefore wolfSSL_X509_set_notBefore +#define X509_set1_notAfter wolfSSL_X509_set1_notAfter +#define X509_set1_notBefore wolfSSL_X509_set1_notBefore #define X509_set_serialNumber wolfSSL_X509_set_serialNumber #define X509_set_version wolfSSL_X509_set_version #define X509_REQ_set_version wolfSSL_X509_set_version @@ -635,6 +637,9 @@ typedef WOLFSSL_X509_NAME_ENTRY X509_NAME_ENTRY; #define X509_V_FLAG_CRL_CHECK WOLFSSL_CRL_CHECK #define X509_V_FLAG_CRL_CHECK_ALL WOLFSSL_CRL_CHECKALL +#define X509_V_FLAG_PARTIAL_CHAIN 0 +#define X509_V_FLAG_TRUSTED_FIRST 0 + #define X509_V_FLAG_USE_CHECK_TIME WOLFSSL_USE_CHECK_TIME #define X509_V_FLAG_NO_CHECK_TIME WOLFSSL_NO_CHECK_TIME #define X509_CHECK_FLAG_ALWAYS_CHECK_SUBJECT WOLFSSL_ALWAYS_CHECK_SUBJECT @@ -675,10 +680,13 @@ typedef WOLFSSL_X509_NAME_ENTRY X509_NAME_ENTRY; wolfSSL_X509_STORE_set_verify_cb((WOLFSSL_X509_STORE *)(s), (WOLFSSL_X509_STORE_CTX_verify_cb)(c)) #define X509_STORE_set_verify_cb_func(s, c) \ wolfSSL_X509_STORE_set_verify_cb((WOLFSSL_X509_STORE *)(s), (WOLFSSL_X509_STORE_CTX_verify_cb)(c)) +#define X509_STORE_set_get_crl wolfSSL_X509_STORE_set_get_crl +#define X509_STORE_set_check_crl wolfSSL_X509_STORE_set_check_crl #define X509_STORE_new wolfSSL_X509_STORE_new #define X509_STORE_free wolfSSL_X509_STORE_free +#define X509_STORE_up_ref wolfSSL_X509_STORE_up_ref #define X509_STORE_add_lookup wolfSSL_X509_STORE_add_lookup #define X509_STORE_add_cert wolfSSL_X509_STORE_add_cert #define X509_STORE_add_crl wolfSSL_X509_STORE_add_crl @@ -687,8 +695,10 @@ wolfSSL_X509_STORE_set_verify_cb((WOLFSSL_X509_STORE *)(s), (WOLFSSL_X509_STORE_ #define X509_STORE_get_by_subject wolfSSL_X509_STORE_get_by_subject #define X509_STORE_set_ex_data wolfSSL_X509_STORE_set_ex_data #define X509_STORE_get_ex_data wolfSSL_X509_STORE_get_ex_data +#define X509_STORE_get0_param wolfSSL_X509_STORE_get0_param #define X509_STORE_CTX_get1_issuer wolfSSL_X509_STORE_CTX_get1_issuer #define X509_STORE_CTX_set_time wolfSSL_X509_STORE_CTX_set_time +#define X509_STORE_CTX_get0_param wolfSSL_X509_STORE_CTX_get0_param #define X509_VERIFY_PARAM_new wolfSSL_X509_VERIFY_PARAM_new #define X509_VERIFY_PARAM_free wolfSSL_X509_VERIFY_PARAM_free #define X509_VERIFY_PARAM_set_flags wolfSSL_X509_VERIFY_PARAM_set_flags @@ -712,6 +722,7 @@ wolfSSL_X509_STORE_set_verify_cb((WOLFSSL_X509_STORE *)(s), (WOLFSSL_X509_STORE_ #define d2i_X509_CRL_fp wolfSSL_d2i_X509_CRL_fp #define PEM_read_X509_CRL wolfSSL_PEM_read_X509_CRL +#define X509_CRL_dup wolfSSL_X509_CRL_dup #define X509_CRL_free wolfSSL_X509_CRL_free #define X509_CRL_get_lastUpdate wolfSSL_X509_CRL_get_lastUpdate #define X509_CRL_get0_lastUpdate wolfSSL_X509_CRL_get_lastUpdate @@ -836,18 +847,21 @@ wolfSSL_X509_STORE_set_verify_cb((WOLFSSL_X509_STORE *)(s), (WOLFSSL_X509_STORE_ #ifndef NO_ASN_TIME #define ASN1_TIME_new wolfSSL_ASN1_TIME_new #define ASN1_UTCTIME_new wolfSSL_ASN1_TIME_new +#define ASN1_GENERALIZEDTIME_new wolfSSL_ASN1_TIME_new #define ASN1_TIME_free wolfSSL_ASN1_TIME_free #define ASN1_UTCTIME_free wolfSSL_ASN1_TIME_free +#define ASN1_GENERALIZEDTIME_free wolfSSL_ASN1_TIME_free #define ASN1_TIME_adj wolfSSL_ASN1_TIME_adj #define ASN1_TIME_print wolfSSL_ASN1_TIME_print #define ASN1_TIME_to_string wolfSSL_ASN1_TIME_to_string #define ASN1_TIME_to_tm wolfSSL_ASN1_TIME_to_tm #define ASN1_TIME_to_generalizedtime wolfSSL_ASN1_TIME_to_generalizedtime +#define ASN1_UTCTIME_set wolfSSL_ASN1_UTCTIME_set #endif #define ASN1_TIME_set wolfSSL_ASN1_TIME_set #define ASN1_TIME_set_string wolfSSL_ASN1_TIME_set_string +#define ASN1_GENERALIZEDTIME_set_string wolfSSL_ASN1_TIME_set_string #define ASN1_GENERALIZEDTIME_print wolfSSL_ASN1_GENERALIZEDTIME_print -#define ASN1_GENERALIZEDTIME_free wolfSSL_ASN1_GENERALIZEDTIME_free #define ASN1_tag2str wolfSSL_ASN1_tag2str @@ -938,7 +952,7 @@ wolfSSL_X509_STORE_set_verify_cb((WOLFSSL_X509_STORE *)(s), (WOLFSSL_X509_STORE_ #define SSL_alert_type_string wolfSSL_alert_type_string #define SSL_alert_desc_string wolfSSL_alert_desc_string -#define SSL_state_string wolfSSL_state_string +#define SSL_state_string wolfSSL_state_string_long #define RSA_free wolfSSL_RSA_free #define RSA_generate_key wolfSSL_RSA_generate_key diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h index dbcb336ddd..2ae6be1968 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -153,8 +153,6 @@ typedef struct WOLFSSL_SOCKADDR WOLFSSL_SOCKADDR; typedef struct WOLFSSL_CRL WOLFSSL_CRL; typedef struct WOLFSSL_X509_STORE_CTX WOLFSSL_X509_STORE_CTX; -typedef int (*WOLFSSL_X509_STORE_CTX_verify_cb)(int, WOLFSSL_X509_STORE_CTX *); - typedef struct WOLFSSL_BY_DIR_HASH WOLFSSL_BY_DIR_HASH; typedef struct WOLFSSL_BY_DIR_entry WOLFSSL_BY_DIR_entry; typedef struct WOLFSSL_BY_DIR WOLFSSL_BY_DIR; @@ -229,6 +227,12 @@ typedef struct WOLFSSL_DIST_POINT WOLFSSL_DIST_POINT; typedef struct WOLFSSL_CONF_CTX WOLFSSL_CONF_CTX; +typedef int (*WOLFSSL_X509_STORE_CTX_verify_cb)(int, WOLFSSL_X509_STORE_CTX *); +typedef int (*WOLFSSL_X509_STORE_CTX_get_crl_cb)(WOLFSSL_X509_STORE_CTX *, + WOLFSSL_X509_CRL **, WOLFSSL_X509 *); +typedef int (*WOLFSSL_X509_STORE_CTX_check_crl_cb)(WOLFSSL_X509_STORE_CTX *, + WOLFSSL_X509_CRL *); + #if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL) || defined(HAVE_CURL) struct WOLFSSL_OBJ_NAME { @@ -604,6 +608,7 @@ struct WOLFSSL_X509_STORE { #endif #if defined(OPENSSL_ALL) || defined(WOLFSSL_QT) WOLFSSL_X509_STORE_CTX_verify_cb verify_cb; + WOLFSSL_X509_STORE_CTX_get_crl_cb get_crl_cb; #endif #ifdef HAVE_EX_DATA WOLFSSL_CRYPTO_EX_DATA ex_data; @@ -705,6 +710,7 @@ struct WOLFSSL_X509_STORE_CTX { int totalCerts; /* number of peer cert buffers */ WOLFSSL_BUFFER_INFO* certs; /* peer certs */ WOLFSSL_X509_STORE_CTX_verify_cb verify_cb; /* verify callback */ + void* heap; }; typedef char* WOLFSSL_STRING; @@ -1883,6 +1889,10 @@ WOLFSSL_API void wolfSSL_X509_STORE_CTX_set_verify_cb(WOLFSSL_X509_STORE_CTX *c WOLFSSL_X509_STORE_CTX_verify_cb verify_cb); WOLFSSL_API void wolfSSL_X509_STORE_set_verify_cb(WOLFSSL_X509_STORE *st, WOLFSSL_X509_STORE_CTX_verify_cb verify_cb); +WOLFSSL_API void wolfSSL_X509_STORE_set_get_crl(WOLFSSL_X509_STORE *st, + WOLFSSL_X509_STORE_CTX_get_crl_cb get_cb); +WOLFSSL_API void wolfSSL_X509_STORE_set_check_crl(WOLFSSL_X509_STORE *st, + WOLFSSL_X509_STORE_CTX_check_crl_cb check_crl); WOLFSSL_API int wolfSSL_i2d_X509_NAME(WOLFSSL_X509_NAME* n, unsigned char** out); WOLFSSL_API int wolfSSL_i2d_X509_NAME_canon(WOLFSSL_X509_NAME* name, @@ -1944,8 +1954,12 @@ WOLFSSL_API int wolfSSL_X509_set_issuer_name(WOLFSSL_X509* cert, WOLFSSL_API int wolfSSL_X509_set_pubkey(WOLFSSL_X509* cert, WOLFSSL_EVP_PKEY* pkey); WOLFSSL_API int wolfSSL_X509_set_notAfter(WOLFSSL_X509* x509, const WOLFSSL_ASN1_TIME* t); +WOLFSSL_API int wolfSSL_X509_set1_notAfter(WOLFSSL_X509* x509, + const WOLFSSL_ASN1_TIME *t); WOLFSSL_API int wolfSSL_X509_set_notBefore(WOLFSSL_X509* x509, const WOLFSSL_ASN1_TIME* t); +WOLFSSL_API int wolfSSL_X509_set1_notBefore(WOLFSSL_X509* x509, + const WOLFSSL_ASN1_TIME *t); WOLFSSL_API WOLFSSL_ASN1_TIME* wolfSSL_X509_get_notBefore(const WOLFSSL_X509* x509); WOLFSSL_API WOLFSSL_ASN1_TIME* wolfSSL_X509_get_notAfter(const WOLFSSL_X509* x509); WOLFSSL_API int wolfSSL_X509_set_serialNumber(WOLFSSL_X509* x509, @@ -2002,6 +2016,8 @@ WOLFSSL_API void wolfSSL_X509_STORE_free(WOLFSSL_X509_STORE* store); WOLFSSL_API int wolfSSL_X509_STORE_up_ref(WOLFSSL_X509_STORE* store); WOLFSSL_API int wolfSSL_X509_STORE_add_cert( WOLFSSL_X509_STORE* store, WOLFSSL_X509* x509); +WOLFSSL_API WOLFSSL_X509_VERIFY_PARAM *wolfSSL_X509_STORE_get0_param( + const WOLFSSL_X509_STORE *ctx); WOLFSSL_API WOLFSSL_STACK* wolfSSL_X509_STORE_CTX_get_chain( WOLFSSL_X509_STORE_CTX* ctx); WOLFSSL_API WOLFSSL_STACK* wolfSSL_X509_STORE_CTX_get1_chain( @@ -2013,7 +2029,10 @@ WOLFSSL_API int wolfSSL_X509_STORE_set_flags(WOLFSSL_X509_STORE* store, WOLFSSL_API int wolfSSL_X509_STORE_set_default_paths(WOLFSSL_X509_STORE* store); WOLFSSL_API int wolfSSL_X509_STORE_get_by_subject(WOLFSSL_X509_STORE_CTX* ctx, int idx, WOLFSSL_X509_NAME* name, WOLFSSL_X509_OBJECT* obj); +WOLFSSL_API WOLFSSL_X509_VERIFY_PARAM *wolfSSL_X509_STORE_CTX_get0_param( + WOLFSSL_X509_STORE_CTX *ctx); WOLFSSL_API WOLFSSL_X509_STORE_CTX* wolfSSL_X509_STORE_CTX_new(void); +WOLFSSL_API WOLFSSL_X509_STORE_CTX* wolfSSL_X509_STORE_CTX_new_ex(void* heap); WOLFSSL_API int wolfSSL_X509_STORE_CTX_init(WOLFSSL_X509_STORE_CTX* ctx, WOLFSSL_X509_STORE* store, WOLFSSL_X509* x509, WOLF_STACK_OF(WOLFSSL_X509)*); WOLFSSL_API void wolfSSL_X509_STORE_CTX_free(WOLFSSL_X509_STORE_CTX* ctx); @@ -2941,6 +2960,7 @@ WOLFSSL_API int wolfSSL_X509_REVOKED_get_serial_number(RevokedCert* rev, byte* in, int* inOutSz); #endif #if defined(HAVE_CRL) && (defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL)) +WOLFSSL_API WOLFSSL_X509_CRL* wolfSSL_X509_CRL_dup(const WOLFSSL_X509_CRL* crl); WOLFSSL_API void wolfSSL_X509_CRL_free(WOLFSSL_X509_CRL *crl); #endif @@ -5094,7 +5114,7 @@ WOLFSSL_API int PEM_write_bio_WOLFSSL_X509(WOLFSSL_BIO *bio, WOLFSSL_API long wolfSSL_CTX_get_tlsext_ticket_keys(WOLFSSL_CTX *ctx, unsigned char *keys, int keylen); WOLFSSL_API long wolfSSL_CTX_set_tlsext_ticket_keys(WOLFSSL_CTX *ctx, - unsigned char *keys, int keylen); + const void *keys_vp, int keylen); #endif WOLFSSL_API void wolfSSL_get0_alpn_selected(const WOLFSSL *ssl, @@ -5196,6 +5216,7 @@ WOLFSSL_API int wolfSSL_ASN1_TIME_get_length(const WOLFSSL_ASN1_TIME *t); WOLFSSL_API unsigned char* wolfSSL_ASN1_TIME_get_data(const WOLFSSL_ASN1_TIME *t); WOLFSSL_API WOLFSSL_ASN1_TIME *wolfSSL_ASN1_TIME_to_generalizedtime(WOLFSSL_ASN1_TIME *t, WOLFSSL_ASN1_TIME **out); +WOLFSSL_API WOLFSSL_ASN1_TIME* wolfSSL_ASN1_UTCTIME_set(WOLFSSL_ASN1_TIME *s, time_t t); WOLFSSL_API int wolfSSL_i2c_ASN1_INTEGER(WOLFSSL_ASN1_INTEGER *a, unsigned char **pp); WOLFSSL_API int wolfSSL_a2i_ASN1_INTEGER(WOLFSSL_BIO *bio, WOLFSSL_ASN1_INTEGER *asn1, char *buf, int size); diff --git a/wolfssl/wolfcrypt/asn.h b/wolfssl/wolfcrypt/asn.h index 77ce5680c4..d848dbc4dc 100644 --- a/wolfssl/wolfcrypt/asn.h +++ b/wolfssl/wolfcrypt/asn.h @@ -2113,6 +2113,7 @@ WOLFSSL_LOCAL int StreamOctetString(const byte* inBuf, word32 inBufSz, WOLFSSL_ASN_API void FreeAltNames(DNS_entry* altNames, void* heap); WOLFSSL_ASN_API DNS_entry* AltNameNew(void* heap); +WOLFSSL_ASN_API DNS_entry* AltNameDup(DNS_entry* from, void* heap); #ifndef IGNORE_NAME_CONSTRAINTS WOLFSSL_ASN_API void FreeNameSubtrees(Base_entry* names, void* heap); #endif /* IGNORE_NAME_CONSTRAINTS */ diff --git a/wolfssl/wolfcrypt/misc.h b/wolfssl/wolfcrypt/misc.h index 2685c6cddd..9761d686a2 100644 --- a/wolfssl/wolfcrypt/misc.h +++ b/wolfssl/wolfcrypt/misc.h @@ -135,6 +135,8 @@ WOLFSSL_LOCAL byte ctSetLTE(int a, int b); WOLFSSL_LOCAL void ctMaskCopy(byte mask, byte* dst, byte* src, word16 size); WOLFSSL_LOCAL word32 MakeWordFromHash(const byte* hashID); WOLFSSL_LOCAL word32 HashObject(const byte* o, word32 len, int* error); +WOLFSSL_LOCAL char* CopyString(const char* src, int srcLen, void* heap, + int type); WOLFSSL_LOCAL void w64Increment(w64wrapper *n); WOLFSSL_LOCAL void w64Decrement(w64wrapper *n); From fcb5c362f9a6f7d9d76facaec72f5c2a139ac36f Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Thu, 18 Apr 2024 15:53:54 +0200 Subject: [PATCH 2/6] Add grpc testing --- .github/workflows/grpc.yml | 103 +++++++++++++++++++++++++++++++++++++ 1 file changed, 103 insertions(+) create mode 100644 .github/workflows/grpc.yml diff --git a/.github/workflows/grpc.yml b/.github/workflows/grpc.yml new file mode 100644 index 0000000000..9fd7724d27 --- /dev/null +++ b/.github/workflows/grpc.yml @@ -0,0 +1,103 @@ +name: grpc Tests + +# START OF COMMON SECTION +on: + push: + branches: [ 'master', 'main', 'release/**' ] + pull_request: + branches: [ '*' ] + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true +# END OF COMMON SECTION + +jobs: + build_wolfssl: + name: Build wolfSSL + # Just to keep it the same as the testing target + runs-on: ubuntu-latest + # This should be a safe limit for the tests to run. + timeout-minutes: 10 + steps: + - name: Build wolfSSL + uses: wolfSSL/actions-build-autotools-project@v1 + with: + path: wolfssl + configure: --enable-all 'CPPFLAGS=-DWOLFSSL_RSA_KEY_CHECK -DHAVE_EX_DATA_CLEANUP_HOOKS' + install: true + + - name: Upload built lib + uses: actions/upload-artifact@v4 + with: + name: wolf-install-grpc + path: build-dir + retention-days: 5 + + grpc_check: + strategy: + fail-fast: false + matrix: + include: + - ref: v1.60.0 + tests: >- + bad_ssl_alpn_test bad_ssl_cert_test client_ssl_test + crl_ssl_transport_security_test server_ssl_test + ssl_transport_security_test ssl_transport_security_utils_test + test_core_security_ssl_credentials_test test_cpp_end2end_ssl_credentials_test + h2_ssl_cert_test h2_ssl_session_reuse_test + name: ${{ matrix.ref }} + runs-on: ubuntu-latest + # This should be a safe limit for the tests to run. + timeout-minutes: 60 + needs: build_wolfssl + steps: + - name: Confirm IPv4 and IPv6 support + run: | + ip addr list lo | grep 'inet ' + ip addr list lo | grep 'inet6 ' + + - name: Install prereqs + run: + sudo apt-get install build-essential autoconf libtool pkg-config cmake clang libc++-dev + + - name: Download lib + uses: actions/download-artifact@v4 + with: + name: wolf-install-grpc + path: build-dir + + - name: Checkout OSP + uses: actions/checkout@v4 + with: + # TODO point to wolf repo once merged + repository: julek-wolfssl/osp + path: osp + ref: grpc-update + + - name: Checkout grpc + uses: actions/checkout@v4 + with: + repository: grpc/grpc + path: grpc + ref: ${{ matrix.ref }} + + - name: Build grpc + working-directory: ./grpc + run: | + patch -p1 < ../osp/grpc/grpc-${{ matrix.ref }}.patch + git submodule update --init + mkdir cmake/build + cd cmake/build + cmake -DgRPC_BUILD_TESTS=ON -DgRPC_SSL_PROVIDER=wolfssl \ + -DWOLFSSL_INSTALL_DIR=$GITHUB_WORKSPACE/build-dir ../.. + make -j $(nproc) ${{ matrix.tests }} + + - name: Run grpc tests + working-directory: ./grpc + run: | + export LD_LIBRARY_PATH=$GITHUB_WORKSPACE/build-dir/lib:$LD_LIBRARY_PATH + ./tools/run_tests/start_port_server.py + for t in ${{ matrix.tests }} ; do + ./cmake/build/$t + done From d9a236ba1e83c38795e0119901f33345a2a3beeb Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Thu, 9 May 2024 16:39:27 +0200 Subject: [PATCH 3/6] SSL_get_error does not return x509 errors --- src/ssl.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/ssl.c b/src/ssl.c index 4a6f54fde7..3dbd9b0317 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -4081,11 +4081,7 @@ int wolfSSL_get_error(WOLFSSL* ssl, int ret) else if (ssl->error == SOCKET_PEER_CLOSED_E) return WOLFSSL_ERROR_SYSCALL; /* convert to OpenSSL type */ #endif -#if defined(WOLFSSL_HAPROXY) - return GetX509Error(ssl->error); -#else - return (ssl->error); -#endif + return ssl->error; } From 12b9367598fbcdb5f351430bd3a72f0466d77167 Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Thu, 9 May 2024 19:43:14 +0200 Subject: [PATCH 4/6] test_wolfSSL_check_domain: doesn't work with WOLFSSL_HOSTNAME_VERIFY_ALT_NAME_ONLY --- tests/api.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/tests/api.c b/tests/api.c index 38f75e93de..785924a16a 100644 --- a/tests/api.c +++ b/tests/api.c @@ -41936,7 +41936,8 @@ static int test_wolfSSL_X509_VERIFY_PARAM(void) return EXPECT_RESULT(); } -#if defined(OPENSSL_EXTRA) && defined(HAVE_SSL_MEMIO_TESTS_DEPENDENCIES) +#if defined(OPENSSL_EXTRA) && defined(HAVE_SSL_MEMIO_TESTS_DEPENDENCIES) && \ + !defined(WOLFSSL_HOSTNAME_VERIFY_ALT_NAME_ONLY) static int test_wolfSSL_check_domain_verify_count = 0; @@ -42001,6 +42002,14 @@ static int test_wolfSSL_check_domain(void) return EXPECT_RESULT(); } +#else + +static int test_wolfSSL_check_domain(void) +{ + EXPECT_DECLS; + return EXPECT_RESULT(); +} + #endif /* OPENSSL_EXTRA && HAVE_SSL_MEMIO_TESTS_DEPENDENCIES */ static int test_wolfSSL_X509_get_X509_PUBKEY(void) @@ -72953,9 +72962,7 @@ TEST_CASE testCases[] = { TEST_DECL(test_wolfSSL_BIO_get_len), #endif -#if defined(OPENSSL_EXTRA) && defined(HAVE_SSL_MEMIO_TESTS_DEPENDENCIES) TEST_DECL(test_wolfSSL_check_domain), -#endif TEST_DECL(test_wolfSSL_cert_cb), TEST_DECL(test_wolfSSL_cert_cb_dyn_ciphers), TEST_DECL(test_wolfSSL_ciphersuite_auth), From c07f73b1c7c810ec25fb2d3c27d1cacd2b1b5a45 Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Tue, 14 May 2024 12:07:23 +0200 Subject: [PATCH 5/6] Fix typo --- src/ssl_sess.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ssl_sess.c b/src/ssl_sess.c index ed66cf6f3e..23b595be8b 100644 --- a/src/ssl_sess.c +++ b/src/ssl_sess.c @@ -1726,7 +1726,7 @@ WOLFSSL_SESSION* ClientSessionToSession(const WOLFSSL_SESSION* session) /* Check the session ID hash matches */ error = clientSession->sessionIDHash != sessionIDHash; if (error != 0) - WOLFSSL_MSG("session ID hash don't match"); + WOLFSSL_MSG("session ID hashes don't match"); } if (error == 0) { /* Hashes match */ From 76aba42bfa128cec811b510ed452d01897900f9e Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Tue, 14 May 2024 13:59:22 +0200 Subject: [PATCH 6/6] Fix api signature --- src/ssl.c | 4 ++-- wolfssl/openssl/ssl.h | 2 +- wolfssl/openssl/x509v3.h | 2 +- wolfssl/ssl.h | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/ssl.c b/src/ssl.c index 3dbd9b0317..fcb8bf99a3 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -11811,7 +11811,7 @@ int wolfSSL_set_compression(WOLFSSL* ssl) } #endif /* SESSION_CERTS && OPENSSL_EXTRA */ - WOLFSSL_X509_STORE* wolfSSL_CTX_get_cert_store(WOLFSSL_CTX* ctx) + WOLFSSL_X509_STORE* wolfSSL_CTX_get_cert_store(const WOLFSSL_CTX* ctx) { if (ctx == NULL) { return NULL; @@ -11819,7 +11819,7 @@ int wolfSSL_set_compression(WOLFSSL* ssl) if (ctx->x509_store_pt != NULL) return ctx->x509_store_pt; - return &ctx->x509_store; + return &((WOLFSSL_CTX*)ctx)->x509_store; } void wolfSSL_CTX_set_cert_store(WOLFSSL_CTX* ctx, WOLFSSL_X509_STORE* str) diff --git a/wolfssl/openssl/ssl.h b/wolfssl/openssl/ssl.h index edf7e379b6..d26cfdbb1d 100644 --- a/wolfssl/openssl/ssl.h +++ b/wolfssl/openssl/ssl.h @@ -931,7 +931,7 @@ wolfSSL_X509_STORE_set_verify_cb((WOLFSSL_X509_STORE *)(s), (WOLFSSL_X509_STORE_ #endif #define SSL_set0_verify_cert_store wolfSSL_set0_verify_cert_store #define SSL_set1_verify_cert_store wolfSSL_set1_verify_cert_store -#define SSL_CTX_get_cert_store(x) wolfSSL_CTX_get_cert_store ((WOLFSSL_CTX*) (x)) +#define SSL_CTX_get_cert_store(x) wolfSSL_CTX_get_cert_store ((x)) #define SSL_get_client_CA_list wolfSSL_get_client_CA_list #define SSL_set_client_CA_list wolfSSL_set_client_CA_list #define SSL_get_ex_data_X509_STORE_CTX_idx wolfSSL_get_ex_data_X509_STORE_CTX_idx diff --git a/wolfssl/openssl/x509v3.h b/wolfssl/openssl/x509v3.h index c9c9ad8507..51b4e65554 100644 --- a/wolfssl/openssl/x509v3.h +++ b/wolfssl/openssl/x509v3.h @@ -145,7 +145,7 @@ WOLFSSL_API WOLFSSL_ASN1_STRING* wolfSSL_a2i_IPADDRESS(const char* ipa); #define BASIC_CONSTRAINTS_free wolfSSL_BASIC_CONSTRAINTS_free #define AUTHORITY_KEYID_free wolfSSL_AUTHORITY_KEYID_free -#define SSL_CTX_get_cert_store(x) wolfSSL_CTX_get_cert_store ((WOLFSSL_CTX*) (x)) +#define SSL_CTX_get_cert_store(x) wolfSSL_CTX_get_cert_store ((x)) #define ASN1_INTEGER WOLFSSL_ASN1_INTEGER #define ASN1_OCTET_STRING WOLFSSL_ASN1_STRING #define X509V3_EXT_get wolfSSL_X509V3_EXT_get diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h index 2ae6be1968..f12d32a23d 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -4493,7 +4493,7 @@ WOLFSSL_API int wolfSSL_set0_verify_cert_store(WOLFSSL *ssl, WOLFSSL_X509_STORE* str); WOLFSSL_API int wolfSSL_set1_verify_cert_store(WOLFSSL *ssl, WOLFSSL_X509_STORE* str); -WOLFSSL_API WOLFSSL_X509_STORE* wolfSSL_CTX_get_cert_store(WOLFSSL_CTX* ctx); +WOLFSSL_API WOLFSSL_X509_STORE* wolfSSL_CTX_get_cert_store(const WOLFSSL_CTX* ctx); #endif /* OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL */ #if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL) || \ defined(HAVE_SECRET_CALLBACK)