@@ -92,7 +92,7 @@ void wolfSSL_X509_STORE_CTX_free(WOLFSSL_X509_STORE_CTX* ctx)
9292 ctx -> param = NULL ;
9393
9494 if (ctx -> chain != NULL ) {
95- wolfSSL_sk_X509_free (ctx -> chain );
95+ wolfSSL_sk_X509_pop_free (ctx -> chain , NULL );
9696 }
9797 if (ctx -> owned != NULL ) {
9898 wolfSSL_sk_X509_pop_free (ctx -> owned , NULL );
@@ -207,7 +207,7 @@ int wolfSSL_X509_STORE_CTX_init(WOLFSSL_X509_STORE_CTX* ctx,
207207 ctx -> crls = NULL ;
208208#endif
209209 if (ctx -> chain != NULL ) {
210- wolfSSL_sk_X509_free (ctx -> chain );
210+ wolfSSL_sk_X509_pop_free (ctx -> chain , NULL );
211211 ctx -> chain = NULL ;
212212 }
213213#ifdef SESSION_CERTS
@@ -663,6 +663,22 @@ static int X509StoreRemoveCert(WOLFSSL_STACK *stack, WOLFSSL_X509 *cert) {
663663}
664664
665665
666+ /* Push x509 onto the ctx chain with its own reference, like OpenSSL.
667+ * The chain owns a reference to each of its certs. */
668+ static int X509StoreChainPush (WOLF_STACK_OF (WOLFSSL_X509 )* chain ,
669+ WOLFSSL_X509 * x509 )
670+ {
671+ int ret = WC_NO_ERR_TRACE (WOLFSSL_FAILURE );
672+
673+ if (x509 == NULL || wolfSSL_X509_up_ref (x509 ) != WOLFSSL_SUCCESS )
674+ return ret ;
675+ ret = wolfSSL_sk_X509_push (chain , x509 ) > 0 ? WOLFSSL_SUCCESS :
676+ WC_NO_ERR_TRACE (WOLFSSL_FAILURE );
677+ if (ret != WOLFSSL_SUCCESS )
678+ wolfSSL_X509_free (x509 );
679+ return ret ;
680+ }
681+
666682/* Current certificate failed, but it is possible there is an
667683 * alternative cert with the same subject key which will work.
668684 * Retry until all possible candidate certs are exhausted. */
@@ -677,6 +693,9 @@ static int X509VerifyCertSetupRetry(WOLFSSL_X509_STORE_CTX* ctx,
677693 WOLFSSL_TEMP_CA );
678694 X509StoreMoveCert (certs , failed , ctx -> current_cert );
679695 ctx -> current_cert = wolfSSL_sk_X509_pop (ctx -> chain );
696+ /* Release the chain's reference. The cert stays valid through its
697+ * original owner. */
698+ wolfSSL_X509_free (ctx -> current_cert );
680699 if (* depth < origDepth )
681700 * depth += 1 ;
682701
@@ -907,7 +926,7 @@ int wolfSSL_X509_verify_cert(WOLFSSL_X509_STORE_CTX* ctx)
907926 }
908927
909928 if (ctx -> chain != NULL ) {
910- wolfSSL_sk_X509_free (ctx -> chain );
929+ wolfSSL_sk_X509_pop_free (ctx -> chain , NULL );
911930 }
912931 ctx -> chain = wolfSSL_sk_X509_new_null ();
913932 if (ctx -> chain == NULL ) {
@@ -941,7 +960,7 @@ int wolfSSL_X509_verify_cert(WOLFSSL_X509_STORE_CTX* ctx)
941960 ctx -> current_cert );
942961 if (ret == WOLFSSL_SUCCESS ) {
943962 if (ctx -> current_cert == issuer ) {
944- wolfSSL_sk_X509_push (ctx -> chain , ctx -> current_cert );
963+ X509StoreChainPush (ctx -> chain , ctx -> current_cert );
945964 break ;
946965 }
947966
@@ -988,7 +1007,7 @@ int wolfSSL_X509_verify_cert(WOLFSSL_X509_STORE_CTX* ctx)
9881007 continue ;
9891008 }
9901009 /* Add it to the current chain and look at the issuer cert next */
991- wolfSSL_sk_X509_push (ctx -> chain , ctx -> current_cert );
1010+ X509StoreChainPush (ctx -> chain , ctx -> current_cert );
9921011 ctx -> current_cert = issuer ;
9931012 }
9941013 else if (ret == WC_NO_ERR_TRACE (WOLFSSL_FAILURE )) {
@@ -1025,7 +1044,7 @@ int wolfSSL_X509_verify_cert(WOLFSSL_X509_STORE_CTX* ctx)
10251044 (ctx -> store -> param -> flags & WOLFSSL_PARTIAL_CHAIN ))) &&
10261045 X509StoreCertIsTrusted (ctx -> store , ctx -> current_cert ,
10271046 origTrustedSk )) {
1028- wolfSSL_sk_X509_push (ctx -> chain , ctx -> current_cert );
1047+ X509StoreChainPush (ctx -> chain , ctx -> current_cert );
10291048 /* Clear error set by the failed X509StoreVerifyCert
10301049 * attempt; the partial-chain fallback accepted the
10311050 * chain at a caller-trusted certificate. */
@@ -1046,7 +1065,7 @@ int wolfSSL_X509_verify_cert(WOLFSSL_X509_STORE_CTX* ctx)
10461065 }
10471066
10481067 /* Cert verified, finish building the chain */
1049- wolfSSL_sk_X509_push (ctx -> chain , ctx -> current_cert );
1068+ X509StoreChainPush (ctx -> chain , ctx -> current_cert );
10501069 issuer = NULL ;
10511070 #ifdef WOLFSSL_SIGNER_DER_CERT
10521071 x509GetIssuerFromCM (& issuer , ctx -> store -> cm , ctx -> current_cert );
@@ -1064,7 +1083,7 @@ int wolfSSL_X509_verify_cert(WOLFSSL_X509_STORE_CTX* ctx)
10641083 }
10651084 #endif
10661085 if (issuer != NULL ) {
1067- wolfSSL_sk_X509_push (ctx -> chain , issuer );
1086+ X509StoreChainPush (ctx -> chain , issuer );
10681087 }
10691088
10701089 done = 1 ;
0 commit comments