@@ -84,16 +84,40 @@ int wolfSSL_X509_STORE_CTX_init(WOLFSSL_X509_STORE_CTX* ctx,
8484 #endif
8585
8686 ctx -> chain = sk ;
87- /* Add intermediate certificates from stack to store */
88- while (sk != NULL ) {
89- WOLFSSL_X509 * x509_cert = sk -> data .x509 ;
90- if (x509_cert != NULL && x509_cert -> isCa ) {
91- ret = wolfSSL_X509_STORE_add_cert (store , x509_cert );
92- if (ret < 0 ) {
93- return WOLFSSL_FAILURE ;
87+ /* Add intermediate certs, that verify to a loaded CA, to the store */
88+ if (sk != NULL ) {
89+ byte addedAtLeastOne = 1 ;
90+ WOLF_STACK_OF (WOLFSSL_X509 )* head = wolfSSL_shallow_sk_dup (sk );
91+ if (head == NULL )
92+ return WOLFSSL_FAILURE ;
93+ while (addedAtLeastOne ) {
94+ WOLF_STACK_OF (WOLFSSL_X509 )* cur = head ;
95+ WOLF_STACK_OF (WOLFSSL_X509 )* * prev = & head ;
96+ addedAtLeastOne = 0 ;
97+ while (cur ) {
98+ WOLFSSL_X509 * cert = cur -> data .x509 ;
99+ if (cert != NULL && cert -> derCert != NULL &&
100+ wolfSSL_CertManagerVerifyBuffer (store -> cm ,
101+ cert -> derCert -> buffer ,
102+ cert -> derCert -> length ,
103+ WOLFSSL_FILETYPE_ASN1 ) == WOLFSSL_SUCCESS ) {
104+ ret = wolfSSL_X509_STORE_add_cert (store , cert );
105+ if (ret < 0 ) {
106+ wolfSSL_sk_free (head );
107+ return WOLFSSL_FAILURE ;
108+ }
109+ addedAtLeastOne = 1 ;
110+ * prev = cur -> next ;
111+ wolfSSL_sk_free_node (cur );
112+ cur = * prev ;
113+ }
114+ else {
115+ prev = & cur -> next ;
116+ cur = cur -> next ;
117+ }
94118 }
95119 }
96- sk = sk -> next ;
120+ wolfSSL_sk_free ( head ) ;
97121 }
98122
99123 ctx -> sesChain = NULL ;
@@ -140,7 +164,9 @@ void wolfSSL_X509_STORE_CTX_free(WOLFSSL_X509_STORE_CTX* ctx)
140164 }
141165}
142166
143-
167+ /* Its recommended to use a full free -> init cycle of all the objects
168+ * because wolfSSL_X509_STORE_CTX_init may modify the store too which doesn't
169+ * get reset here. */
144170void wolfSSL_X509_STORE_CTX_cleanup (WOLFSSL_X509_STORE_CTX * ctx )
145171{
146172 if (ctx != NULL ) {
@@ -168,7 +194,7 @@ int GetX509Error(int e)
168194{
169195 switch (e ) {
170196 case ASN_BEFORE_DATE_E :
171- return WOLFSSL_X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD ;
197+ return WOLFSSL_X509_V_ERR_CERT_NOT_YET_VALID ;
172198 case ASN_AFTER_DATE_E :
173199 return WOLFSSL_X509_V_ERR_CERT_HAS_EXPIRED ;
174200 case ASN_NO_SIGNER_E : /* get issuer error if no CA found locally */
@@ -185,6 +211,9 @@ int GetX509Error(int e)
185211 return WOLFSSL_X509_V_ERR_CERT_SIGNATURE_FAILURE ;
186212 case CRL_CERT_REVOKED :
187213 return WOLFSSL_X509_V_ERR_CERT_REVOKED ;
214+ case 0 :
215+ case 1 :
216+ return 0 ;
188217 default :
189218#ifdef HAVE_WOLFSSL_MSG_EX
190219 WOLFSSL_MSG_EX ("Error not configured or implemented yet: %d" , e );
@@ -195,6 +224,19 @@ int GetX509Error(int e)
195224 }
196225}
197226
227+ static void SetupStoreCtxError (WOLFSSL_X509_STORE_CTX * ctx , int ret )
228+ {
229+ int depth = 0 ;
230+ int error = GetX509Error (ret );
231+
232+ /* Set error depth */
233+ if (ctx -> chain )
234+ depth = (int )ctx -> chain -> num ;
235+
236+ wolfSSL_X509_STORE_CTX_set_error (ctx , error );
237+ wolfSSL_X509_STORE_CTX_set_error_depth (ctx , depth );
238+ }
239+
198240/* Verifies certificate chain using WOLFSSL_X509_STORE_CTX
199241 * returns 0 on success or < 0 on failure.
200242 */
@@ -204,66 +246,39 @@ int wolfSSL_X509_verify_cert(WOLFSSL_X509_STORE_CTX* ctx)
204246
205247 if (ctx != NULL && ctx -> store != NULL && ctx -> store -> cm != NULL
206248 && ctx -> current_cert != NULL && ctx -> current_cert -> derCert != NULL ) {
207- int ret = 0 ;
208- int depth = 0 ;
209- int error ;
210- #ifndef NO_ASN_TIME
211- byte * afterDate , * beforeDate ;
212- #endif
213-
214- ret = wolfSSL_CertManagerVerifyBuffer (ctx -> store -> cm ,
249+ int ret = wolfSSL_CertManagerVerifyBuffer (ctx -> store -> cm ,
215250 ctx -> current_cert -> derCert -> buffer ,
216251 ctx -> current_cert -> derCert -> length ,
217252 WOLFSSL_FILETYPE_ASN1 );
218- /* If there was an error, process it and add it to CTX */
219- if (ret < 0 ) {
220- /* Get corresponding X509 error */
221- error = GetX509Error (ret );
222- /* Set error depth */
223- if (ctx -> chain )
224- depth = (int )ctx -> chain -> num ;
225-
226- wolfSSL_X509_STORE_CTX_set_error (ctx , error );
227- wolfSSL_X509_STORE_CTX_set_error_depth (ctx , depth );
228- #if defined(OPENSSL_ALL ) || defined(WOLFSSL_QT )
229- if (ctx -> store && ctx -> store -> verify_cb )
230- ctx -> store -> verify_cb (0 , ctx );
231- #endif
232- }
253+ SetupStoreCtxError (ctx , ret );
233254
234255 #ifndef NO_ASN_TIME
235- error = 0 ;
236- /* wolfSSL_CertManagerVerifyBuffer only returns ASN_AFTER_DATE_E or
237- ASN_BEFORE_DATE_E if there are no additional errors found in the
238- cert. Therefore, check if the cert is expired or not yet valid
239- in order to return the correct expected error. */
240- afterDate = ctx -> current_cert -> notAfter .data ;
241- beforeDate = ctx -> current_cert -> notBefore .data ;
242-
243- if (XVALIDATE_DATE (afterDate , (byte )ctx -> current_cert -> notAfter .type ,
244- AFTER ) < 1 ) {
245- error = WOLFSSL_X509_V_ERR_CERT_HAS_EXPIRED ;
246- }
247- else if (XVALIDATE_DATE (beforeDate ,
248- (byte )ctx -> current_cert -> notBefore .type , BEFORE ) < 1 ) {
249- error = WOLFSSL_X509_V_ERR_CERT_NOT_YET_VALID ;
256+ if (ret != ASN_BEFORE_DATE_E && ret != ASN_AFTER_DATE_E ) {
257+ /* wolfSSL_CertManagerVerifyBuffer only returns ASN_AFTER_DATE_E or
258+ ASN_BEFORE_DATE_E if there are no additional errors found in the
259+ cert. Therefore, check if the cert is expired or not yet valid
260+ in order to return the correct expected error. */
261+ byte * afterDate = ctx -> current_cert -> notAfter .data ;
262+ byte * beforeDate = ctx -> current_cert -> notBefore .data ;
263+
264+ if (XVALIDATE_DATE (afterDate ,
265+ (byte )ctx -> current_cert -> notAfter .type , AFTER ) < 1 ) {
266+ ret = ASN_AFTER_DATE_E ;
267+ }
268+ else if (XVALIDATE_DATE (beforeDate ,
269+ (byte )ctx -> current_cert -> notBefore .type , BEFORE ) < 1 ) {
270+ ret = ASN_BEFORE_DATE_E ;
271+ }
272+ SetupStoreCtxError (ctx , ret );
250273 }
274+ #endif
251275
252- if (error != 0 ) {
253- wolfSSL_X509_STORE_CTX_set_error (ctx , error );
254- wolfSSL_X509_STORE_CTX_set_error_depth (ctx , depth );
255- #if defined(OPENSSL_ALL ) || defined(WOLFSSL_QT )
256- if (ctx -> store && ctx -> store -> verify_cb )
257- ctx -> store -> verify_cb (0 , ctx );
258- #endif
259- }
276+ #if defined(OPENSSL_ALL ) || defined(WOLFSSL_QT )
277+ if (ctx -> store && ctx -> store -> verify_cb )
278+ ret = ctx -> store -> verify_cb (ret >= 0 ? 1 : 0 , ctx ) == 1 ? 0 : -1 ;
260279 #endif
261280
262- /* OpenSSL returns 0 when a chain can't be built */
263- if (ret == ASN_NO_SIGNER_E )
264- return WOLFSSL_FAILURE ;
265- else
266- return ret ;
281+ return ret >= 0 ? WOLFSSL_SUCCESS : WOLFSSL_FAILURE ;
267282 }
268283 return WOLFSSL_FATAL_ERROR ;
269284}
@@ -1029,8 +1044,11 @@ WOLFSSL_API int wolfSSL_X509_STORE_load_locations(WOLFSSL_X509_STORE *str,
10291044
10301045#ifdef HAVE_CRL
10311046 if (str -> cm -> crl == NULL ) {
1047+ /* Workaround to allocate the internals to load CRL's but don't enable
1048+ * CRL checking by default */
10321049 if (wolfSSL_CertManagerEnableCRL (str -> cm , WOLFSSL_CRL_CHECK )
1033- != WOLFSSL_SUCCESS ) {
1050+ != WOLFSSL_SUCCESS ||
1051+ wolfSSL_CertManagerDisableCRL (str -> cm ) != WOLFSSL_SUCCESS ) {
10341052 WOLFSSL_MSG ("Enable CRL failed" );
10351053 wolfSSL_CTX_free (ctx );
10361054 return WOLFSSL_FAILURE ;
0 commit comments