From a643ae1907832abce444cc0016ffbf58dffa2648 Mon Sep 17 00:00:00 2001 From: Jacob Barthelmeh Date: Wed, 21 Jun 2017 10:15:48 -0600 Subject: [PATCH] return code of sk num, X509 store peer chain, and get text by NID fix --- src/internal.c | 18 ++++++++++++++++++ src/ssl.c | 36 ++++++++++++++++++++++++++++++++++-- tests/api.c | 2 +- wolfssl/ssl.h | 1 + 4 files changed, 54 insertions(+), 3 deletions(-) diff --git a/src/internal.c b/src/internal.c index c24cb8bfc..5791de382 100644 --- a/src/internal.c +++ b/src/internal.c @@ -8374,6 +8374,7 @@ int ProcessPeerCerts(WOLFSSL* ssl, byte* input, word32* inOutIdx, #if defined(WOLFSSL_ALWAYS_VERIFY_CB) && defined(OPENSSL_EXTRA) if (ssl->verifyCallback) { int ok; + #ifdef WOLFSSL_SMALL_STACK WOLFSSL_X509_STORE_CTX* store = (WOLFSSL_X509_STORE_CTX*)XMALLOC( sizeof(WOLFSSL_X509_STORE_CTX), ssl->heap, @@ -8410,6 +8411,9 @@ int ProcessPeerCerts(WOLFSSL* ssl, byte* input, word32* inOutIdx, if (CopyDecodedToX509(x509, args->dCert) == 0) { store->current_cert = x509; } + #endif + #ifdef SESSION_CERTS + store->sesChain = &(ssl->session.chain); #endif store->ex_data = ssl; @@ -8423,6 +8427,10 @@ int ProcessPeerCerts(WOLFSSL* ssl, byte* input, word32* inOutIdx, #ifndef NO_CERTS FreeX509(x509); #endif + #ifdef SESSION_CERTS + wolfSSL_sk_X509_free(store->chain); + store->chain = NULL; + #endif #ifdef WOLFSSL_SMALL_STACK XFREE(store, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER); XFREE(x509, ssl->heap, DYNAMIC_TYPE_X509); @@ -8957,6 +8965,9 @@ int ProcessPeerCerts(WOLFSSL* ssl, byte* input, word32* inOutIdx, #endif /* KEEP_PEER_CERT */ #if defined(HAVE_EX_DATA) || defined(HAVE_FORTRESS) store->ex_data = ssl; + #endif + #ifdef SESSION_CERTS + store->sesChain = &(ssl->session.chain); #endif ok = ssl->verifyCallback(0, store); if (ok) { @@ -9003,6 +9014,9 @@ int ProcessPeerCerts(WOLFSSL* ssl, byte* input, word32* inOutIdx, store->current_cert = NULL; #endif store->ex_data = ssl; + #ifdef SESSION_CERTS + store->sesChain = &(ssl->session.chain); + #endif ok = ssl->verifyCallback(1, store); if (!ok) { @@ -9038,6 +9052,10 @@ int ProcessPeerCerts(WOLFSSL* ssl, byte* input, word32* inOutIdx, args->idx += ssl->keys.padSz; } + #ifdef SESSION_CERTS + wolfSSL_sk_X509_free(store->chain); + store->chain = NULL; + #endif #ifdef WOLFSSL_SMALL_STACK XFREE(store, ssl->heap, DYNAMIC_TYPE_X509_STORE); #endif diff --git a/src/ssl.c b/src/ssl.c index f8ac0da1d..531be8bdc 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -16342,14 +16342,14 @@ WOLFSSL_ASN1_OBJECT* wolfSSL_sk_GENERAL_NAME_value(WOLFSSL_STACK* sk, int i) * * sk stack to get the number of nodes from * - * returns the number of nodes + * returns the number of nodes, -1 if no nodes */ int wolfSSL_sk_GENERAL_NAME_num(WOLFSSL_STACK* sk) { WOLFSSL_ENTER("wolfSSL_sk_GENERAL_NAME_num"); if (sk == NULL) { - return 0; + return -1; } return (int)sk->num; @@ -18209,6 +18209,38 @@ WOLFSSL_STACK* wolfSSL_X509_STORE_CTX_get_chain(WOLFSSL_X509_STORE_CTX* ctx) return NULL; } +#ifdef SESSION_CERTS + /* if chain is null but sesChain is available then populate stack */ + if (ctx->chain == NULL && ctx->sesChain != NULL) { + int i; + WOLFSSL_X509_CHAIN* c = ctx->sesChain; + WOLFSSL_STACK* sk = (WOLFSSL_STACK*)XMALLOC(sizeof(WOLFSSL_STACK), + NULL, DYNAMIC_TYPE_X509); + + if (sk == NULL) { + return NULL; + } + + XMEMSET(sk, 0, sizeof(WOLFSSL_STACK)); + ctx->chain = sk; + 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_free(sk); + return NULL; + } + + if (wolfSSL_sk_X509_push(sk, x509) != SSL_SUCCESS) { + WOLFSSL_MSG("Unable to load x509 into stack"); + wolfSSL_sk_X509_free(sk); + return NULL; + } + } + } +#endif /* SESSION_CERTS */ + return ctx->chain; } diff --git a/tests/api.c b/tests/api.c index 93052d072..c763c6706 100644 --- a/tests/api.c +++ b/tests/api.c @@ -15900,7 +15900,7 @@ static void test_wolfSSL_sk_GENERAL_NAME(void) /* current cert has no alt names */ AssertNull(sk = X509_get_ext_d2i(x509, NID_subject_alt_name, NULL, NULL)); - AssertIntEQ(sk_GENERAL_NAME_num(sk), 0); + AssertIntEQ(sk_GENERAL_NAME_num(sk), -1); #if 0 for (i = 0; i < sk_GENERAL_NAME_num(sk); i++) { GENERAL_NAME* gn = sk_GENERAL_NAME_value(sk, i); diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h index 2a654887c..1aa2bf40e 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -334,6 +334,7 @@ typedef struct WOLFSSL_BUFFER_INFO { typedef struct WOLFSSL_X509_STORE_CTX { WOLFSSL_X509_STORE* store; /* Store full of a CA cert chain */ WOLFSSL_X509* current_cert; /* stunnel dereference */ + WOLFSSL_X509_CHAIN* sesChain; /* pointer to WOLFSSL_SESSION peer chain */ WOLFSSL_STACK* chain; #ifdef OPENSSL_EXTRA WOLFSSL_X509_VERIFY_PARAM* param; /* certificate validation parameter */