From 6ca12787ae87c56803c44f9de31514a0c707e940 Mon Sep 17 00:00:00 2001 From: Tesfa Mael Date: Thu, 31 Oct 2019 20:21:35 -0700 Subject: [PATCH 1/6] retrieve a stack of X509 certs in a cert manager and a store ctx --- src/ssl.c | 240 +++++++++++++++++++++++++++++++++++++++++++++++++- tests/api.c | 51 +++++++++++ wolfssl/ssl.h | 5 +- 3 files changed, 291 insertions(+), 5 deletions(-) diff --git a/src/ssl.c b/src/ssl.c index bdd71e9a2..1e2206fa7 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -3448,6 +3448,240 @@ void wolfSSL_CertManagerFree(WOLFSSL_CERT_MANAGER* cm) } +#if defined(OPENSSL_EXTRA) && !defined(NO_FILESYSTEM) +#if defined(WOLFSSL_SIGNER_DER_CERT) +/****************************************************************************** +* wolfSSL_CertManager_GetCerts - retrieve stack of X509 certificates in a +* certificate manager (CM), also knows as cert store in OpenSSL. +* +* RETURNS: +* returns stack of X509 certs on success, otherwise returns a NULL. +*/ +WOLFSSL_STACK* wolfSSL_CertManager_GetCerts(WOLFSSL_CERT_MANAGER* cm) +{ + WOLFSSL_STACK* sk = NULL; + Signer* signers = NULL; + word32 row = 0; + DecodedCert* dCert = NULL; + WOLFSSL_X509* x509 = NULL; + int found = 0; + + if (cm == NULL) + return NULL; + + sk = wolfSSL_sk_X509_new(); + + if (sk == NULL) { + return NULL; + } + + XMEMSET(sk, 0, sizeof(WOLFSSL_STACK)); + + if (wc_LockMutex(&cm->caLock) != 0) { + goto error_init; + } + + for (row = 0; row < CA_TABLE_SIZE; row++) { + signers = cm->caTable[row]; + while (signers && signers->derCert && signers->derCert->buffer) { + + dCert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), cm->heap, + DYNAMIC_TYPE_DCERT); + if (dCert == NULL) { + goto error; + } + + XMEMSET(dCert, 0, sizeof(DecodedCert)); + + InitDecodedCert(dCert, signers->derCert->buffer, + signers->derCert->length, cm->heap); + + /* Parse Certificate */ + if (ParseCert(dCert, CERT_TYPE, NO_VERIFY, cm)) { + goto error; + } + + x509 = (WOLFSSL_X509*)XMALLOC(sizeof(WOLFSSL_X509), cm->heap, + DYNAMIC_TYPE_X509); + + if (x509 == NULL) { + goto error; + } + + InitX509(x509, 1, NULL); + + if (CopyDecodedToX509(x509, dCert) == 0) { + + if (wolfSSL_sk_X509_push(sk, x509) != SSL_SUCCESS) { + WOLFSSL_MSG("Unable to load x509 into stack"); + goto error; + } + } + else { + goto error; + } + + found = 1; + + signers = signers->next; + + FreeDecodedCert(dCert); + XFREE(dCert, cm->heap, DYNAMIC_TYPE_DCERT); + dCert = NULL; + } + } + wc_UnLockMutex(&cm->caLock); + + if (!found) { + goto error_init; + } + + return sk; + +error: + wc_UnLockMutex(&cm->caLock); + +error_init: + + if (dCert) { + FreeDecodedCert(dCert); + XFREE(dCert, cm->heap, DYNAMIC_TYPE_DCERT); + } + if (x509) + FreeX509(x509); + + if (sk) + wolfSSL_sk_X509_free(sk); + + return NULL; +} +#endif /* WOLFSSL_SIGNER_DER_CERT */ + +/****************************************************************************** +* wolfSSL_X509_STORE_GetCerts - retrieve stack of X509 in a certificate store ctx +* +* This API can be used in SSL verify callback function to view cert chain +* Here's an example to display certs to stdout. + +static int verify_callback(int ok, X509_STORE_CTX *ctx) +{ + WOLFSSL_BIO* bio = NULL; + WOLFSSL_STACK* sk = NULL; + X509* x509 = NULL; + int i = 0; + + sk = wolfSSL_X509_STORE_GetCerts(ctx->store->cm); + + for (i = 0; i < sk_X509_num(sk); i++) { + x509 = sk_X509_value(sk, i); + bio = BIO_new(wolfSSL_BIO_s_file()); + if (bio != NULL) { + BIO_set_fp(bio, stdout, BIO_NOCLOSE); + X509_print(bio, x509); + BIO_free(bio); + } + } + + sk_X509_free(sk); + return ok; +} +* You can register your call back function in your app as follows: +* +* ctx = SSL_CTX_new(SSLv23_method()); +* SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, +* verify_callback); +* +* RETURNS: +* returns stack of X509 certs on success, otherwise returns a NULL. +*/ +WOLFSSL_STACK* wolfSSL_X509_STORE_GetCerts(WOLFSSL_X509_STORE_CTX* s) +{ + int certIdx = 0; + WOLFSSL_BUFFER_INFO* cert = NULL; + DecodedCert* dCert = NULL; + WOLFSSL_X509* x509 = NULL; + WOLFSSL_STACK* sk = NULL; + int found = 0; + + if (s == NULL) { + return NULL; + } + + sk = wolfSSL_sk_X509_new(); + + if (sk == NULL) { + return NULL; + } + + XMEMSET(sk, 0, sizeof(WOLFSSL_STACK)); + certIdx = s->totalCerts; + + while (certIdx-- > 0) { + /* get certificate buffer */ + cert = &s->certs[certIdx]; + + if (cert == NULL) + break; + + dCert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), NULL, DYNAMIC_TYPE_DCERT); + + if (dCert == NULL) { + goto error; + } + XMEMSET(dCert, 0, sizeof(DecodedCert)); + + InitDecodedCert(dCert, cert->buffer, cert->length, NULL); + + /* Parse Certificate */ + if (ParseCert(dCert, CERT_TYPE, NO_VERIFY, NULL)){ + goto error; + } + x509 = (WOLFSSL_X509*)XMALLOC(sizeof(WOLFSSL_X509), NULL, + DYNAMIC_TYPE_X509); + + if (x509 == NULL) { + goto error; + } + InitX509(x509, 1, NULL); + + if (CopyDecodedToX509(x509, dCert) == 0) { + + if (wolfSSL_sk_X509_push(sk, x509) != SSL_SUCCESS) { + WOLFSSL_MSG("Unable to load x509 into stack"); + goto error; + } + } + else { + goto error; + } + found = 1; + + FreeDecodedCert(dCert); + XFREE(dCert, NULL, DYNAMIC_TYPE_DCERT); + dCert = NULL; + } + + if (!found) { + wolfSSL_sk_X509_free(sk); + sk = NULL; + } + return sk; + +error: + if (dCert) { + FreeDecodedCert(dCert); + XFREE(dCert, NULL, DYNAMIC_TYPE_DCERT); + } + + if (x509) + FreeX509(x509); + + if (sk) + wolfSSL_sk_X509_free(sk); + + return NULL; +} +#endif /* defined(OPENSSL_EXTRA) && !defined(NO_FILESYSTEM) */ /* Unload the CA signer list */ int wolfSSL_CertManagerUnloadCAs(WOLFSSL_CERT_MANAGER* cm) @@ -14114,10 +14348,8 @@ int wolfSSL_set_compression(WOLFSSL* ssl) return WOLFSSL_SUCCESS; } - - - #ifndef NO_CERTS + WOLFSSL_X509_STORE* wolfSSL_CTX_get_cert_store(WOLFSSL_CTX* ctx) { if (ctx == NULL) { @@ -43550,7 +43782,7 @@ error: } #endif /* defined(OPENSSL_ALL) && defined(HAVE_PKCS7) */ -#ifdef OPENSSL_ALL +#if defined(OPENSSL_ALL) || defined(OPENSSL_EXTRA) WOLFSSL_STACK* wolfSSL_sk_X509_new(void) { WOLFSSL_STACK* s = (WOLFSSL_STACK*)XMALLOC(sizeof(WOLFSSL_STACK), NULL, diff --git a/tests/api.c b/tests/api.c index 964f1e35e..cee4447e2 100644 --- a/tests/api.c +++ b/tests/api.c @@ -1093,6 +1093,56 @@ static int test_wolfSSL_CertManagerLoadCABuffer(void) return ret; } +static void test_wolfSSL_CertManager_GetCerts(void) +{ +#if defined(OPENSSL_ALL) && !defined(NO_CERTS) && \ + !defined(NO_FILESYSTEM) && !defined(NO_RSA) && \ + defined(WOLFSSL_SIGNER_DER_CERT) + + WOLFSSL_CERT_MANAGER* cm = NULL; + WOLFSSL_STACK* sk = NULL; + X509* x509 = NULL; + X509* cert1 = NULL; + FILE* file1 = NULL; +#ifdef DEBUG_WOLFSSL_VERBOSE + WOLFSSL_BIO* bio = NULL; +#endif + int i = 0; + + printf(testingFmt, "wolfSSL_CertManager_GetCerts()"); + AssertNotNull(file1=fopen("./certs/ca-cert.pem", "rb")); + + AssertNotNull(cert1 = wolfSSL_PEM_read_X509(file1, NULL, NULL, NULL)); + fclose(file1); + + AssertNotNull(cm = wolfSSL_CertManagerNew_ex(NULL)); + AssertNull(sk = wolfSSL_CertManager_GetCerts(cm)); + AssertIntEQ(WOLFSSL_SUCCESS, wolfSSL_CertManagerLoadCA(cm, + "./certs/ca-cert.pem", NULL)); + + AssertNotNull(sk = wolfSSL_CertManager_GetCerts(cm)); + + for (i = 0; i < sk_X509_num(sk); i++) { + x509 = sk_X509_value(sk, i); + AssertIntEQ(0, wolfSSL_X509_cmp(x509, cert1)); + +#ifdef DEBUG_WOLFSSL_VERBOSE + bio = BIO_new(wolfSSL_BIO_s_file()); + if (bio != NULL) { + BIO_set_fp(bio, stdout, BIO_NOCLOSE); + X509_print(bio, x509); + BIO_free(bio); + } +#endif /* DEBUG_WOLFSSL_VERBOSE */ + } + wolfSSL_X509_free(cert1); + sk_X509_free(sk); + wolfSSL_CertManagerFree(cm); + printf(resultFmt, passed); +#endif /* defined(OPENSSL_ALL) && !defined(NO_CERTS) && \ + !defined(NO_FILESYSTEM) && !defined(NO_RSA) && \ + defined(WOLFSSL_SIGNER_DER_CERT) */ +} static void test_wolfSSL_CertManagerCRL(void) { #if !defined(NO_FILESYSTEM) && !defined(NO_CERTS) && defined(HAVE_CRL) && \ @@ -28267,6 +28317,7 @@ void ApiTest(void) test_wolfSSL_CTX_use_PrivateKey_file(); test_wolfSSL_CTX_load_verify_locations(); test_wolfSSL_CertManagerLoadCABuffer(); + test_wolfSSL_CertManager_GetCerts(); test_wolfSSL_CertManagerCRL(); test_wolfSSL_CTX_load_verify_locations_ex(); test_wolfSSL_CTX_load_verify_buffer_ex(); diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h index bc162965f..87b47c72f 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -2574,7 +2574,9 @@ WOLFSSL_API void* wolfSSL_GetRsaDecCtx(WOLFSSL* ssl); WOLFSSL_CERT_MANAGER* cm); WOLFSSL_API int wolfSSL_CertManagerDisableOCSPStapling( WOLFSSL_CERT_MANAGER* cm); - +#if defined(OPENSSL_EXTRA) && defined(WOLFSSL_SIGNER_DER_CERT) && !defined(NO_FILESYSTEM) +WOLFSSL_API WOLFSSL_STACK* wolfSSL_CertManager_GetCerts(WOLFSSL_CERT_MANAGER* cm); +#endif WOLFSSL_API int wolfSSL_EnableCRL(WOLFSSL* ssl, int options); WOLFSSL_API int wolfSSL_DisableCRL(WOLFSSL* ssl); WOLFSSL_API int wolfSSL_LoadCRL(WOLFSSL*, const char*, int, int); @@ -3159,6 +3161,7 @@ WOLFSSL_API int wolfSSL_i2d_X509_bio(WOLFSSL_BIO* bio, WOLFSSL_X509* x509); #if !defined(NO_FILESYSTEM) WOLFSSL_API WOLFSSL_X509* wolfSSL_d2i_X509_fp(XFILE fp, WOLFSSL_X509** x509); +WOLFSSL_API WOLFSSL_STACK* wolfSSL_X509_STORE_GetCerts(WOLFSSL_X509_STORE_CTX* s); #endif WOLFSSL_API WOLFSSL_X509* wolfSSL_d2i_X509_bio(WOLFSSL_BIO* bio, WOLFSSL_X509** x509); From 520a032b718d80500f198b3c6b726e7eb0ff097a Mon Sep 17 00:00:00 2001 From: Tesfa Mael Date: Tue, 12 Nov 2019 14:58:06 -0800 Subject: [PATCH 2/6] Add show x509 test --- src/internal.c | 1 + src/ssl.c | 66 +++++++++++++------------------------------------- tests/api.c | 10 ++++---- wolfssl/ssl.h | 4 +-- wolfssl/test.h | 24 ++++++++++++++++++ 5 files changed, 49 insertions(+), 56 deletions(-) diff --git a/src/internal.c b/src/internal.c index 34e6b37e7..6cde72fbe 100644 --- a/src/internal.c +++ b/src/internal.c @@ -9501,6 +9501,7 @@ static int DoVerifyCallback(WOLFSSL* ssl, int ret, ProcPeerCertArgs* args) } #if defined(OPENSSL_EXTRA) + store->depth = args->count; store->param = (WOLFSSL_X509_VERIFY_PARAM*)XMALLOC( sizeof(WOLFSSL_X509_VERIFY_PARAM), ssl->heap, DYNAMIC_TYPE_OPENSSL); diff --git a/src/ssl.c b/src/ssl.c index 1e2206fa7..62fd551a0 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -3451,13 +3451,13 @@ void wolfSSL_CertManagerFree(WOLFSSL_CERT_MANAGER* cm) #if defined(OPENSSL_EXTRA) && !defined(NO_FILESYSTEM) #if defined(WOLFSSL_SIGNER_DER_CERT) /****************************************************************************** -* wolfSSL_CertManager_GetCerts - retrieve stack of X509 certificates in a +* wolfSSL_CertManagerGetCerts - retrieve stack of X509 certificates in a * certificate manager (CM), also knows as cert store in OpenSSL. * * RETURNS: * returns stack of X509 certs on success, otherwise returns a NULL. */ -WOLFSSL_STACK* wolfSSL_CertManager_GetCerts(WOLFSSL_CERT_MANAGER* cm) +WOLFSSL_STACK* wolfSSL_CertManagerGetCerts(WOLFSSL_CERT_MANAGER* cm) { WOLFSSL_STACK* sk = NULL; Signer* signers = NULL; @@ -3475,8 +3475,6 @@ WOLFSSL_STACK* wolfSSL_CertManager_GetCerts(WOLFSSL_CERT_MANAGER* cm) return NULL; } - XMEMSET(sk, 0, sizeof(WOLFSSL_STACK)); - if (wc_LockMutex(&cm->caLock) != 0) { goto error_init; } @@ -3561,35 +3559,7 @@ error_init: * wolfSSL_X509_STORE_GetCerts - retrieve stack of X509 in a certificate store ctx * * This API can be used in SSL verify callback function to view cert chain -* Here's an example to display certs to stdout. - -static int verify_callback(int ok, X509_STORE_CTX *ctx) -{ - WOLFSSL_BIO* bio = NULL; - WOLFSSL_STACK* sk = NULL; - X509* x509 = NULL; - int i = 0; - - sk = wolfSSL_X509_STORE_GetCerts(ctx->store->cm); - - for (i = 0; i < sk_X509_num(sk); i++) { - x509 = sk_X509_value(sk, i); - bio = BIO_new(wolfSSL_BIO_s_file()); - if (bio != NULL) { - BIO_set_fp(bio, stdout, BIO_NOCLOSE); - X509_print(bio, x509); - BIO_free(bio); - } - } - - sk_X509_free(sk); - return ok; -} -* You can register your call back function in your app as follows: -* -* ctx = SSL_CTX_new(SSLv23_method()); -* SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, -* verify_callback); +* See examples/client/client.c and myVerify() function in test.h * * RETURNS: * returns stack of X509 certs on success, otherwise returns a NULL. @@ -3613,10 +3583,7 @@ WOLFSSL_STACK* wolfSSL_X509_STORE_GetCerts(WOLFSSL_X509_STORE_CTX* s) return NULL; } - XMEMSET(sk, 0, sizeof(WOLFSSL_STACK)); - certIdx = s->totalCerts; - - while (certIdx-- > 0) { + for (certIdx = s->totalCerts - 1; certIdx >= 0; certIdx--) { /* get certificate buffer */ cert = &s->certs[certIdx]; @@ -3681,7 +3648,7 @@ error: return NULL; } -#endif /* defined(OPENSSL_EXTRA) && !defined(NO_FILESYSTEM) */ +#endif /* OPENSSL_EXTRA && !NO_FILESYSTEM */ /* Unload the CA signer list */ int wolfSSL_CertManagerUnloadCAs(WOLFSSL_CERT_MANAGER* cm) @@ -38374,15 +38341,6 @@ int wolfSSL_CIPHER_get_bits(const WOLFSSL_CIPHER *c, int *alg_bits) return ret; } -int wolfSSL_sk_X509_num(const WOLF_STACK_OF(WOLFSSL_X509) *s) -{ - WOLFSSL_ENTER("wolfSSL_sk_X509_num"); - - if (s == NULL) - return -1; - return (int)s->num; -} - #if defined(OPENSSL_ALL) WOLFSSL_X509_INFO* wolfSSL_X509_INFO_new(void) { @@ -39110,6 +39068,16 @@ WOLF_STACK_OF(WOLFSSL_X509)* wolfSSL_X509_STORE_get1_certs(WOLFSSL_X509_STORE_CT #if defined(OPENSSL_EXTRA) + +int wolfSSL_sk_X509_num(const WOLF_STACK_OF(WOLFSSL_X509) *s) +{ + WOLFSSL_ENTER("wolfSSL_sk_X509_num"); + + if (s == NULL) + return -1; + return (int)s->num; +} + unsigned long wolfSSL_ERR_peek_last_error(void) { WOLFSSL_ENTER("wolfSSL_ERR_peek_last_error"); @@ -43780,9 +43748,9 @@ error: } return WOLFSSL_FAILURE; } -#endif /* defined(OPENSSL_ALL) && defined(HAVE_PKCS7) */ +#endif /* OPENSSL_ALL && HAVE_PKCS7 */ -#if defined(OPENSSL_ALL) || defined(OPENSSL_EXTRA) +#if defined(OPENSSL_EXTRA) WOLFSSL_STACK* wolfSSL_sk_X509_new(void) { WOLFSSL_STACK* s = (WOLFSSL_STACK*)XMALLOC(sizeof(WOLFSSL_STACK), NULL, diff --git a/tests/api.c b/tests/api.c index cee4447e2..674be630e 100644 --- a/tests/api.c +++ b/tests/api.c @@ -1093,7 +1093,7 @@ static int test_wolfSSL_CertManagerLoadCABuffer(void) return ret; } -static void test_wolfSSL_CertManager_GetCerts(void) +static void test_wolfSSL_CertManagerGetCerts(void) { #if defined(OPENSSL_ALL) && !defined(NO_CERTS) && \ !defined(NO_FILESYSTEM) && !defined(NO_RSA) && \ @@ -1109,18 +1109,18 @@ static void test_wolfSSL_CertManager_GetCerts(void) #endif int i = 0; - printf(testingFmt, "wolfSSL_CertManager_GetCerts()"); + printf(testingFmt, "wolfSSL_CertManagerGetCerts()"); AssertNotNull(file1=fopen("./certs/ca-cert.pem", "rb")); AssertNotNull(cert1 = wolfSSL_PEM_read_X509(file1, NULL, NULL, NULL)); fclose(file1); AssertNotNull(cm = wolfSSL_CertManagerNew_ex(NULL)); - AssertNull(sk = wolfSSL_CertManager_GetCerts(cm)); + AssertNull(sk = wolfSSL_CertManagerGetCerts(cm)); AssertIntEQ(WOLFSSL_SUCCESS, wolfSSL_CertManagerLoadCA(cm, "./certs/ca-cert.pem", NULL)); - AssertNotNull(sk = wolfSSL_CertManager_GetCerts(cm)); + AssertNotNull(sk = wolfSSL_CertManagerGetCerts(cm)); for (i = 0; i < sk_X509_num(sk); i++) { x509 = sk_X509_value(sk, i); @@ -28317,7 +28317,7 @@ void ApiTest(void) test_wolfSSL_CTX_use_PrivateKey_file(); test_wolfSSL_CTX_load_verify_locations(); test_wolfSSL_CertManagerLoadCABuffer(); - test_wolfSSL_CertManager_GetCerts(); + test_wolfSSL_CertManagerGetCerts(); test_wolfSSL_CertManagerCRL(); test_wolfSSL_CTX_load_verify_locations_ex(); test_wolfSSL_CTX_load_verify_buffer_ex(); diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h index 87b47c72f..535ab05e3 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -570,7 +570,7 @@ typedef struct WOLFSSL_X509_STORE_CTX { #if defined(HAVE_EX_DATA) || defined(FORTRESS) void* ex_data[MAX_EX_DATA]; /* external data */ #endif -#if defined(WOLFSSL_APACHE_HTTPD) || defined(OPENSSL_ALL) +#if defined(WOLFSSL_APACHE_HTTPD) || defined(OPENSSL_EXTRA) int depth; /* used in X509_STORE_CTX_*_depth */ #endif void* userCtx; /* user ctx */ @@ -2575,7 +2575,7 @@ WOLFSSL_API void* wolfSSL_GetRsaDecCtx(WOLFSSL* ssl); WOLFSSL_API int wolfSSL_CertManagerDisableOCSPStapling( WOLFSSL_CERT_MANAGER* cm); #if defined(OPENSSL_EXTRA) && defined(WOLFSSL_SIGNER_DER_CERT) && !defined(NO_FILESYSTEM) -WOLFSSL_API WOLFSSL_STACK* wolfSSL_CertManager_GetCerts(WOLFSSL_CERT_MANAGER* cm); +WOLFSSL_API WOLFSSL_STACK* wolfSSL_CertManagerGetCerts(WOLFSSL_CERT_MANAGER* cm); #endif WOLFSSL_API int wolfSSL_EnableCRL(WOLFSSL* ssl, int options); WOLFSSL_API int wolfSSL_DisableCRL(WOLFSSL* ssl); diff --git a/wolfssl/test.h b/wolfssl/test.h index 69b7bddd8..bcf9c4568 100644 --- a/wolfssl/test.h +++ b/wolfssl/test.h @@ -1650,6 +1650,12 @@ static WC_INLINE int myVerify(int preverify, WOLFSSL_X509_STORE_CTX* store) char buffer[WOLFSSL_MAX_ERROR_SZ]; #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL) WOLFSSL_X509* peer; +#if defined(SHOW_CERTS) && !defined(NO_FILESYSTEM) + WOLFSSL_BIO* bio = NULL; + WOLFSSL_STACK* sk = NULL; + X509* x509 = NULL; + int i = 0; +#endif #endif (void)preverify; @@ -1681,6 +1687,24 @@ static WC_INLINE int myVerify(int preverify, WOLFSSL_X509_STORE_CTX* store) subject); XFREE(subject, 0, DYNAMIC_TYPE_OPENSSL); XFREE(issuer, 0, DYNAMIC_TYPE_OPENSSL); +#if defined(SHOW_CERTS) && !defined(NO_FILESYSTEM) +/* avoid printing same certs since myVerify is called for every cert in the chain */ + if (store->depth == 1) { + /* retrieve x509 certs and display them on stdout */ + sk = wolfSSL_X509_STORE_GetCerts(store); + + for (i = 0; i < wolfSSL_sk_X509_num(sk); i++) { + x509 = wolfSSL_sk_X509_value(sk, i); + bio = wolfSSL_BIO_new(wolfSSL_BIO_s_file()); + if (bio != NULL) { + wolfSSL_BIO_set_fp(bio, stdout, BIO_NOCLOSE); + wolfSSL_X509_print(bio, x509); + wolfSSL_BIO_free(bio); + } + } + wolfSSL_sk_X509_free(sk); + } +#endif } else printf("\tPeer has no cert!\n"); From 74dd142a511c8b5381f1f7c0e93f961051a4f34d Mon Sep 17 00:00:00 2001 From: Tesfa Mael Date: Mon, 18 Nov 2019 15:13:59 -0800 Subject: [PATCH 3/6] Review comment --- src/ssl.c | 2 +- wolfssl/test.h | 10 +++++++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/ssl.c b/src/ssl.c index 62fd551a0..f0105cd78 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -3452,7 +3452,7 @@ void wolfSSL_CertManagerFree(WOLFSSL_CERT_MANAGER* cm) #if defined(WOLFSSL_SIGNER_DER_CERT) /****************************************************************************** * wolfSSL_CertManagerGetCerts - retrieve stack of X509 certificates in a -* certificate manager (CM), also knows as cert store in OpenSSL. +* certificate manager (CM). * * RETURNS: * returns stack of X509 certs on success, otherwise returns a NULL. diff --git a/wolfssl/test.h b/wolfssl/test.h index bcf9c4568..805d6d3d8 100644 --- a/wolfssl/test.h +++ b/wolfssl/test.h @@ -1645,6 +1645,14 @@ static WC_INLINE void OCSPRespFreeCb(void* ioCtx, unsigned char* response) #endif /* !NO_CERTS */ static int myVerifyFail = 0; + +/* The verify callback is called for every certificate only when + * --enable-opensslextra is defined because it sets WOLFSSL_ALWAYS_VERIFY_CB and + * WOLFSSL_VERIFY_CB_ALL_CERTS. + * Normal cases of the verify callback only occur on certificate failures when the + * wolfSSL_set_verify(ssl, SSL_VERIFY_PEER, myVerifyCb); is called +*/ + static WC_INLINE int myVerify(int preverify, WOLFSSL_X509_STORE_CTX* store) { char buffer[WOLFSSL_MAX_ERROR_SZ]; @@ -1688,7 +1696,7 @@ static WC_INLINE int myVerify(int preverify, WOLFSSL_X509_STORE_CTX* store) XFREE(subject, 0, DYNAMIC_TYPE_OPENSSL); XFREE(issuer, 0, DYNAMIC_TYPE_OPENSSL); #if defined(SHOW_CERTS) && !defined(NO_FILESYSTEM) -/* avoid printing same certs since myVerify is called for every cert in the chain */ +/* avoid printing duplicate certs */ if (store->depth == 1) { /* retrieve x509 certs and display them on stdout */ sk = wolfSSL_X509_STORE_GetCerts(store); From 62eaa27b41b2f58693faecc763e6e9de8674ea9f Mon Sep 17 00:00:00 2001 From: Tesfa Mael Date: Tue, 19 Nov 2019 15:29:48 -0800 Subject: [PATCH 4/6] Review comment, avoid double-free --- src/ssl.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/ssl.c b/src/ssl.c index f0105cd78..523d05158 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -3545,8 +3545,6 @@ error_init: FreeDecodedCert(dCert); XFREE(dCert, cm->heap, DYNAMIC_TYPE_DCERT); } - if (x509) - FreeX509(x509); if (sk) wolfSSL_sk_X509_free(sk); @@ -3640,9 +3638,6 @@ error: XFREE(dCert, NULL, DYNAMIC_TYPE_DCERT); } - if (x509) - FreeX509(x509); - if (sk) wolfSSL_sk_X509_free(sk); From f95d5eebff0bcf298c8b84fbbe2a9074b6198162 Mon Sep 17 00:00:00 2001 From: Tesfa Mael Date: Wed, 20 Nov 2019 17:02:13 -0800 Subject: [PATCH 5/6] Add FreeX509() to clean up when sk stack is empty --- src/ssl.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/ssl.c b/src/ssl.c index 523d05158..ff4885785 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -3512,6 +3512,7 @@ WOLFSSL_STACK* wolfSSL_CertManagerGetCerts(WOLFSSL_CERT_MANAGER* cm) if (wolfSSL_sk_X509_push(sk, x509) != SSL_SUCCESS) { WOLFSSL_MSG("Unable to load x509 into stack"); + FreeX509(x509); goto error; } } @@ -3613,6 +3614,7 @@ WOLFSSL_STACK* wolfSSL_X509_STORE_GetCerts(WOLFSSL_X509_STORE_CTX* s) if (wolfSSL_sk_X509_push(sk, x509) != SSL_SUCCESS) { WOLFSSL_MSG("Unable to load x509 into stack"); + FreeX509(x509); goto error; } } From 8bc3b7df35436a60adc5371ebef1b2f49c788a88 Mon Sep 17 00:00:00 2001 From: Tesfa Mael Date: Fri, 22 Nov 2019 14:31:59 -0800 Subject: [PATCH 6/6] Free x509 --- src/ssl.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/ssl.c b/src/ssl.c index ff4885785..9c8dcea8a 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -3513,6 +3513,7 @@ WOLFSSL_STACK* wolfSSL_CertManagerGetCerts(WOLFSSL_CERT_MANAGER* cm) if (wolfSSL_sk_X509_push(sk, x509) != SSL_SUCCESS) { WOLFSSL_MSG("Unable to load x509 into stack"); FreeX509(x509); + XFREE(x509, cm->heap, DYNAMIC_TYPE_X509); goto error; } } @@ -3602,8 +3603,7 @@ WOLFSSL_STACK* wolfSSL_X509_STORE_GetCerts(WOLFSSL_X509_STORE_CTX* s) if (ParseCert(dCert, CERT_TYPE, NO_VERIFY, NULL)){ goto error; } - x509 = (WOLFSSL_X509*)XMALLOC(sizeof(WOLFSSL_X509), NULL, - DYNAMIC_TYPE_X509); + x509 = wolfSSL_X509_new(); if (x509 == NULL) { goto error; @@ -3614,7 +3614,7 @@ WOLFSSL_STACK* wolfSSL_X509_STORE_GetCerts(WOLFSSL_X509_STORE_CTX* s) if (wolfSSL_sk_X509_push(sk, x509) != SSL_SUCCESS) { WOLFSSL_MSG("Unable to load x509 into stack"); - FreeX509(x509); + wolfSSL_X509_free(x509); goto error; } }