On the ocsp-verification branch:
Retrieve the list of OCSP responder URIs from a certificate.

* BRANCH-README
  (serf_ssl_cert_certificate): Adjust doc to match actual semantics.

* serf_bucket_types.h
  (serf_ssl_cert_certificate): Update docstring.
* buckets/ssl_buckets.c
  (get_ocsp_responders): New helper function.
  (serf_ssl_cert_certificate): Also return an array OCSP responder URIs.


git-svn-id: https://svn.apache.org/repos/asf/serf/branches/ocsp-verification@1772999 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/BRANCH-README b/BRANCH-README
index 2bab2ca..4cd03c3 100644
--- a/BRANCH-README
+++ b/BRANCH-README
@@ -14,10 +14,9 @@
 
 1. serf_ssl_cert_certificate()
 
-   Extract the OCSP responder URL from the certificate's x509v3
-   extension field authorityInfoAccess:OCSP;URI and, if it is
-   present, insert it into the returned hash table with key
-   "ocsp.uri".
+   Extract the OCSP responder locations from the certificate's x509v3
+   extension field authorityInfoAccess:OCSP;URI and, if it is present,
+   insert the array into the returned hash table with key "OCSP".
 
 2. serf_ssl_cert_import()
 
diff --git a/buckets/ssl_buckets.c b/buckets/ssl_buckets.c
index 7befef6..0eef47c 100644
--- a/buckets/ssl_buckets.c
+++ b/buckets/ssl_buckets.c
@@ -733,6 +733,42 @@
     return APR_SUCCESS;
 }
 
+
+static apr_status_t
+get_ocsp_responders(apr_array_header_t **ocsp_arr, X509 *ssl_cert,
+                    apr_pool_t *pool)
+{
+    /* assert: (ocsp_arr && pool) */
+
+    if (ocsp_arr) {
+        STACK_OF(OPENSSL_STRING) *uris;
+
+        *ocsp_arr = NULL;
+        uris = X509_get1_ocsp(ssl_cert);
+        if (uris) {
+            int uris_count = sk_OPENSSL_STRING_num(uris);
+            int uri_idx;
+
+            *ocsp_arr = apr_array_make(pool, uris_count, sizeof(char*));
+
+            for (uri_idx = 0; uri_idx < uris_count; ++uri_idx) {
+                OPENSSL_STRING uri = sk_OPENSSL_STRING_value(uris, uri_idx);
+                if (uri) {
+                    char *p = apr_pstrdup(pool, uri);
+
+                    if (p) {
+                        APR_ARRAY_PUSH(*ocsp_arr, char*) = p;
+                    }
+                }
+            }
+        }
+        X509_email_free(uris);
+    }
+
+    return APR_SUCCESS;
+}
+
+
 static apr_status_t validate_cert_hostname(X509 *server_cert, apr_pool_t *pool)
 {
     char buf[1024];
@@ -2268,6 +2304,7 @@
     unsigned char md[EVP_MAX_MD_SIZE];
     BIO *bio;
     apr_array_header_t *san_arr;
+    apr_array_header_t *ocsp_arr;
 
     /* sha1 fingerprint */
     if (X509_digest(cert->ssl_cert, EVP_sha1(), md, &md_size)) {
@@ -2316,6 +2353,10 @@
     if (!get_subject_alt_names(&san_arr, cert->ssl_cert, EscapeNulAndCopy, pool))
       apr_hash_set(tgt, "subjectAltName", APR_HASH_KEY_STRING, san_arr);
 
+    /* Get authorityAccessInfo.OCSP */
+    if (!get_ocsp_responders(&ocsp_arr, cert->ssl_cert, pool))
+      apr_hash_set(tgt, "OCSP", APR_HASH_KEY_STRING, ocsp_arr);
+
     return tgt;
 }
 
diff --git a/serf_bucket_types.h b/serf_bucket_types.h
index 92d6634..6d1045a 100644
--- a/serf_bucket_types.h
+++ b/serf_bucket_types.h
@@ -701,8 +701,9 @@
     apr_pool_t *pool);
 
 /**
- * Extract the fields of the certificate in a table with keys (sha1, notBefore,
- * notAfter, subjectAltName). The returned table will be allocated in @a pool.
+ * Extract the fields of the certificate in a table with keys
+ *   (sha1, notBefore, notAfter, subjectAltName, OCSP).
+ * The returned table will be allocated in @a pool.
  */
 apr_hash_t *serf_ssl_cert_certificate(
     const serf_ssl_certificate_t *cert,