@@ -86,33 +86,36 @@ struct WOLFSSH_CERTMAN {
8686
8787static WOLFSSH_CERTMAN * _CertMan_init (WOLFSSH_CERTMAN * cm , void * heap )
8888{
89+ WOLFSSH_CERTMAN * ret = NULL ;
8990 WLOG_ENTER ();
9091
91- if (cm != NULL ) {
92- WMEMSET (cm , 0 , sizeof * cm );
93- cm -> cm = wolfSSL_CertManagerNew_ex (heap );
94- if (cm -> cm != NULL ) {
95- int ret ;
92+ ret = cm ;
93+ if (ret != NULL ) {
94+ WMEMSET (ret , 0 , sizeof (WOLFSSH_CERTMAN ));
95+ ret -> cm = wolfSSL_CertManagerNew_ex (heap );
96+ if (ret -> cm == NULL ) {
97+ ret = NULL ;
98+ }
99+ #ifdef HAVE_OCSP
100+ else {
101+ int err ;
96102
97- ret = wolfSSL_CertManagerEnableOCSP (cm -> cm ,
103+ err = wolfSSL_CertManagerEnableOCSP (ret -> cm ,
98104 WOLFSSL_OCSP_CHECKALL );
99-
100- if (ret == WOLFSSL_SUCCESS ) {
105+ if (err == WOLFSSL_SUCCESS ) {
101106 WLOG (WS_LOG_CERTMAN , "Enabled OCSP" );
102107 }
103108 else {
104109 WLOG (WS_LOG_CERTMAN , "Couldn't enable OCSP" );
105- wolfSSL_CertManagerFree (cm -> cm );
106- cm = NULL ;
110+ wolfSSL_CertManagerFree (ret -> cm );
111+ ret = NULL ;
107112 }
108113 }
109- else {
110- cm = NULL ;
111- }
114+ #endif
112115 }
113116
114- WLOG_LEAVE_PTR (cm );
115- return cm ;
117+ WLOG_LEAVE_PTR (ret );
118+ return ret ;
116119}
117120
118121
@@ -190,59 +193,148 @@ enum {
190193};
191194#endif /* WOLFSSH_NO_FPKI */
192195
193- int wolfSSH_CERTMAN_VerifyCert_buffer (WOLFSSH_CERTMAN * cm ,
194- const unsigned char * cert , word32 certSz )
196+ /* if handling a chain it is expected to be the leaf cert first followed by
197+ * intermediates and CA last (CA may be ommited) */
198+ int wolfSSH_CERTMAN_VerifyCerts_buffer (WOLFSSH_CERTMAN * cm ,
199+ const unsigned char * certs , word32 certSz , word32 certsCount )
195200{
196201 int ret = WS_SUCCESS ;
202+ int idx ;
203+
204+ unsigned char * * certLoc ; /* locations of certificate start */
205+ word32 * certLen ; /* size of certificate, in sync with certLoc */
206+
207+ unsigned char * currentPt ;
208+ word32 currentSz ;
197209
198210 WLOG_ENTER ();
199211
200- if (ret == WS_SUCCESS ) {
201- ret = wolfSSL_CertManagerVerifyBuffer (cm -> cm , cert , certSz ,
202- WOLFSSL_FILETYPE_ASN1 );
212+ certLoc = (unsigned char * * )WMALLOC (certsCount * sizeof (unsigned char * ),
213+ cm -> heap , DYNTYPE_CERT );
214+ certLen = (word32 * )WMALLOC (certsCount * sizeof (word32 ), cm -> heap ,
215+ DYNTYPE_CERT );
203216
204- if (ret == WOLFSSL_SUCCESS ) {
205- ret = WS_SUCCESS ;
206- }
207- else if (ret == ASN_NO_SIGNER_E ) {
208- WLOG (WS_LOG_CERTMAN , "cert verify: no signer" );
209- ret = WS_CERT_NO_SIGNER_E ;
210- }
211- else if (ret == ASN_AFTER_DATE_E ) {
212- WLOG (WS_LOG_CERTMAN , "cert verify: expired" );
213- ret = WS_CERT_EXPIRED_E ;
214- }
215- else if (ret == ASN_SIG_CONFIRM_E ) {
216- WLOG (WS_LOG_CERTMAN , "cert verify: bad sig" );
217- ret = WS_CERT_SIG_CONFIRM_E ;
217+ currentPt = (unsigned char * )certs ; /* set initial certificate pointer */
218+ currentSz = 0 ;
219+
220+ for (idx = 0 ; idx < (int )certsCount ; idx ++ ) {
221+ word32 sz = 0 ;
222+ certLoc [idx ] = currentPt ;
223+
224+ /* get the size of the certificate from first sequence */
225+ if (currentSz + MAX_SEQ_SZ >= certSz ) {
226+ ret = WS_BUFFER_E ;
227+ break ;
218228 }
219229 else {
220- WLOG (WS_LOG_CERTMAN , "cert verify: other error (%d)" , ret );
221- ret = WS_CERT_OTHER_E ;
230+ /* at this point there is at least 5 bytes in currentPt */
231+ if (currentPt [sz ] != (ASN_SEQUENCE | ASN_CONSTRUCTED )) {
232+ WLOG (WS_LOG_CERTMAN , "no cert sequence to get length from" );
233+ ret = ASN_PARSE_E ;
234+ break ;
235+ }
236+ sz ++ ;
237+
238+ if (ret == WS_SUCCESS ) {
239+ if (currentPt [sz ] >= ASN_LONG_LENGTH ) {
240+ word32 bytes = currentPt [sz ++ ] & 0x7F ;
241+ if (bytes > MAX_LENGTH_SZ ) {
242+ WLOG (WS_LOG_CERTMAN , "length found is too large!" );
243+ ret = ASN_PARSE_E ;
244+ break ;
245+ }
246+ else {
247+ byte b ;
248+ certLen [idx ] = 0 ;
249+ for (; bytes > 0 ; bytes -- ) {
250+ b = currentPt [sz ++ ];
251+ certLen [idx ] = (certLen [idx ] << 8 ) | b ;
252+ }
253+ }
254+ }
255+ else {
256+ certLen [idx ] = (word32 )currentPt [sz ++ ];
257+ }
258+ sz += certLen [idx ];
259+ certLen [idx ] = sz ; /* update size to contain first sequence */
260+ }
261+ }
262+
263+ /* advance current pointer and update current total size */
264+ if (ret == WS_SUCCESS ) {
265+ if (currentSz + sz > certSz ) {
266+ WLOG (WS_LOG_CERTMAN , "cert found is too large!" );
267+ ret = ASN_PARSE_E ;
268+ break ;
269+ }
270+ currentSz += sz ;
271+ currentPt += sz ;
222272 }
223273 }
224274
225275 if (ret == WS_SUCCESS ) {
226- ret = wolfSSL_CertManagerCheckOCSP (cm -> cm , (byte * )cert , certSz );
276+ for (idx = certsCount - 1 ; idx >= 0 ; idx -- ) {
277+ WLOG (WS_LOG_CERTMAN , "verifying cert at index %d" , idx );
278+ ret = wolfSSL_CertManagerVerifyBuffer (cm -> cm , certLoc [idx ],
279+ certLen [idx ], WOLFSSL_FILETYPE_ASN1 );
280+ if (ret == WOLFSSL_SUCCESS ) {
281+ ret = WS_SUCCESS ;
282+ }
283+ else if (ret == ASN_NO_SIGNER_E ) {
284+ WLOG (WS_LOG_CERTMAN , "cert verify: no signer" );
285+ ret = WS_CERT_NO_SIGNER_E ;
286+ }
287+ else if (ret == ASN_AFTER_DATE_E ) {
288+ WLOG (WS_LOG_CERTMAN , "cert verify: expired" );
289+ ret = WS_CERT_EXPIRED_E ;
290+ }
291+ else if (ret == ASN_SIG_CONFIRM_E ) {
292+ WLOG (WS_LOG_CERTMAN , "cert verify: bad sig" );
293+ ret = WS_CERT_SIG_CONFIRM_E ;
294+ }
295+ else {
296+ WLOG (WS_LOG_CERTMAN , "cert verify: other error (%d)" , ret );
297+ ret = WS_CERT_OTHER_E ;
298+ }
227299
228- if (ret == WOLFSSL_SUCCESS ) {
229- ret = WS_SUCCESS ;
230- }
231- else if (ret == OCSP_CERT_REVOKED ) {
232- WLOG (WS_LOG_CERTMAN , "ocsp lookup: ocsp revoked" );
233- ret = WS_CERT_REVOKED_E ;
234- }
235- else {
236- WLOG (WS_LOG_CERTMAN , "ocsp lookup: other error (%d)" , ret );
237- ret = WS_CERT_OTHER_E ;
300+ #ifdef HAVE_OCSP
301+ if (ret == WS_SUCCESS ) {
302+ ret = wolfSSL_CertManagerCheckOCSP (cm -> cm , (byte * )certLoc [idx ],
303+ certLen [idx ]);
304+
305+ if (ret == WOLFSSL_SUCCESS ) {
306+ ret = WS_SUCCESS ;
307+ }
308+ else if (ret == OCSP_CERT_REVOKED ) {
309+ WLOG (WS_LOG_CERTMAN , "ocsp lookup: ocsp revoked" );
310+ ret = WS_CERT_REVOKED_E ;
311+ }
312+ else {
313+ WLOG (WS_LOG_CERTMAN , "ocsp lookup: other error (%d)" , ret );
314+ ret = WS_CERT_OTHER_E ;
315+ }
316+ }
317+ #endif /* HAVE_OCSP */
318+
319+ /* verified successfully, add intermideate as trusted */
320+ if (ret == WS_SUCCESS && idx > 0 ) {
321+ WLOG (WS_LOG_CERTMAN , "adding intermidiate cert as trusted" );
322+ ret = wolfSSH_CERTMAN_LoadRootCA_buffer (cm , certLoc [idx ],
323+ certLen [idx ]);
324+ }
325+
326+ if (ret != WS_SUCCESS ) {
327+ break ;
328+ }
238329 }
239330 }
240331
241332#ifndef WOLFSSH_NO_FPKI
333+ /* FPKI checking on the leaf certificate */
242334 if (ret == WS_SUCCESS ) {
243335 DecodedCert decoded ;
244336
245- wc_InitDecodedCert (& decoded , cert , certSz , cm -> cm );
337+ wc_InitDecodedCert (& decoded , certLoc [ 0 ], certLen [ 0 ] , cm -> cm );
246338 ret = wc_ParseCert (& decoded , WOLFSSL_FILETYPE_ASN1 , 0 , cm -> cm );
247339
248340 if (ret == 0 ) {
@@ -387,16 +479,20 @@ static int CheckProfile(DecodedCert* cert, int profile)
387479 /* cycle through alt names to check for needed types */
388480 current = cert -> altNames ;
389481 while (current != NULL ) {
482+ #ifdef WOLFSSL_FPKI
390483 if (current -> oidSum == FASCN_OID ) {
391484 hasFascN = 1 ;
392485 }
486+ #endif /* WOLFSSL_FPKI */
393487
394488 current = current -> next ;
395489 }
396490
491+ #ifdef WOLFSSL_FPKI
397492 if (wc_GetUUIDFromCert (cert , uuid , & uuidSz ) == 0 ) {
398493 hasUUID = 1 ;
399494 }
495+ #endif /* WOLFSSL_FPKI */
400496
401497 /* all must have UUID and worksheet 6 must have FASC-N in addition to
402498 * UUID */
0 commit comments