@@ -616,7 +616,7 @@ static int parse_ocsp_url(unsigned char *asn1, char ***ocsp_urls,
616616
617617 if (!err ) {
618618 new_nocsp_urls = * nocsp_urls + 1 ;
619- if ((new_ocsp_urls = apr_xrealloc (* ocsp_urls ,* nocsp_urls , new_nocsp_urls , p )) == NULL )
619+ if ((new_ocsp_urls = apr_xrealloc (* ocsp_urls , * nocsp_urls * sizeof ( char * ) , new_nocsp_urls * sizeof ( char * ) , p )) == NULL )
620620 err = 1 ;
621621 }
622622 if (!err ) {
@@ -688,11 +688,13 @@ static int parse_ASN1_Sequence(unsigned char *asn1, char ***ocsp_urls,
688688/* the main function that gets the ASN1 encoding string and returns
689689 a pointer to a NULL terminated "array" of char *, that contains
690690 the ocsp_urls */
691- static char * * decode_OCSP_url (ASN1_OCTET_STRING * os , apr_pool_t * p )
691+ static char * * decode_OCSP_url (ASN1_OCTET_STRING * os , int * numofresponses , apr_pool_t * p )
692692{
693693 char * * response = NULL ;
694694 unsigned char * ocsp_urls ;
695- int len , numofresponses = 0 ;
695+ int len ;
696+
697+ * numofresponses = 0 ;
696698
697699 len = ASN1_STRING_length (os );
698700
@@ -703,8 +705,8 @@ static char **decode_OCSP_url(ASN1_OCTET_STRING *os, apr_pool_t *p)
703705 if ((response = apr_pcalloc (p , sizeof (char * ))) == NULL ) {
704706 return NULL ;
705707 }
706- if (parse_ASN1_Sequence (ocsp_urls , & response , & numofresponses , p ) ||
707- numofresponses == 0 ) {
708+ if (parse_ASN1_Sequence (ocsp_urls , & response , numofresponses , p ) ||
709+ * numofresponses == 0 ) {
708710 response = NULL ;
709711 }
710712 return response ;
@@ -1090,7 +1092,7 @@ static int process_ocsp_response(OCSP_REQUEST *ocsp_req, OCSP_RESPONSE *ocsp_res
10901092static int ssl_ocsp_request (X509 * cert , X509 * issuer , X509_STORE_CTX * ctx , int timeout , int verifyFlags )
10911093{
10921094 char * * ocsp_urls = NULL ;
1093- int nid ;
1095+ int nid , numofresponses ;
10941096 int rv = OCSP_STATUS_UNKNOWN ;
10951097 X509_EXTENSION * ext ;
10961098 ASN1_OCTET_STRING * os ;
@@ -1104,36 +1106,47 @@ static int ssl_ocsp_request(X509 *cert, X509 *issuer, X509_STORE_CTX *ctx, int t
11041106 ext = X509_get_ext (cert ,nid );
11051107 os = X509_EXTENSION_get_data (ext );
11061108
1107- ocsp_urls = decode_OCSP_url (os , p );
1109+ ocsp_urls = decode_OCSP_url (os , & numofresponses , p );
11081110 }
1109-
11101111 /* if we find the extensions and we can parse it check
11111112 the ocsp status. Otherwise, return OCSP_STATUS_UNKNOWN */
1112- if (ocsp_urls != NULL ) {
1113+ if (ocsp_urls != NULL && numofresponses > 0 ) {
11131114 OCSP_REQUEST * req ;
11141115 OCSP_RESPONSE * resp = NULL ;
1115- /* for the time being just check for the fist response .. a better
1116- approach is to iterate for all the possible ocsp urls */
1116+ int i ;
1117+
11171118 req = get_ocsp_request (cert , issuer );
1118- if (req != NULL ) {
1119- resp = get_ocsp_response (p , ocsp_urls [0 ], req , timeout );
1120- if (resp != NULL ) {
1121- rv = process_ocsp_response (req , resp , cert , issuer , ctx , verifyFlags );
1122- } else {
1123- /* Unable to send request / receive response. */
1124- X509_STORE_CTX_set_error (ctx , X509_V_ERR_UNABLE_TO_GET_CRL );
1125- }
1126- } else {
1119+ if (req == NULL ) {
11271120 /* correct error code for application errors? */
11281121 X509_STORE_CTX_set_error (ctx , X509_V_ERR_APPLICATION_VERIFICATION );
1129- }
1122+ } else {
1123+ /* Iterate through all the possible OCSP URLs until we get a definitive response */
1124+ for (i = 0 ; i < numofresponses ; i ++ ) {
1125+ if (ocsp_urls [i ] == NULL ) {
1126+ continue ;
1127+ }
11301128
1131- if (req != NULL ) {
1132- OCSP_REQUEST_free (req );
1133- }
1129+ resp = get_ocsp_response (p , ocsp_urls [i ], req , timeout );
1130+ if (resp != NULL ) {
1131+ rv = process_ocsp_response (req , resp , cert , issuer , ctx , verifyFlags );
1132+ OCSP_RESPONSE_free (resp );
1133+ resp = NULL ;
1134+
1135+ /* If we got a definitive answer (OK or REVOKED), stop trying */
1136+ if (rv == OCSP_STATUS_OK || rv == OCSP_STATUS_REVOKED ) {
1137+ break ;
1138+ }
1139+ /* Otherwise (UNKNOWN), try the next URL */
1140+ }
1141+ }
11341142
1135- if (resp != NULL ) {
1136- OCSP_RESPONSE_free (resp );
1143+ /* If all URLs failed to respond or returned UNKNOWN */
1144+ if (rv == OCSP_STATUS_UNKNOWN ) {
1145+ /* Unable to send request / receive response from any URL. */
1146+ X509_STORE_CTX_set_error (ctx , X509_V_ERR_UNABLE_TO_GET_CRL );
1147+ }
1148+
1149+ OCSP_REQUEST_free (req );
11371150 }
11381151 }
11391152 apr_pool_destroy (p );
0 commit comments