Add X509_get_pathlen and X509_REVOKED_get0_extensions.

Conscrypt will need these functions. Also fix a bug in
X509_get_extension_flags's error-handling. While I'm here, add
X509_CRL_get0_extensions for completeness. Nothing uses this yet, but
this could later be an alternative to avoid Conscrypt's mess with
templates.

Change-Id: I9393b75fcf53346535e6a4712355be081baa630d
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/42744
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: Adam Langley <agl@google.com>
diff --git a/crypto/x509v3/v3_purp.c b/crypto/x509v3/v3_purp.c
index 51783a4..acb7602 100644
--- a/crypto/x509v3/v3_purp.c
+++ b/crypto/x509v3/v3_purp.c
@@ -451,8 +451,14 @@
                 || !bs->ca) {
                 x->ex_flags |= EXFLAG_INVALID;
                 x->ex_pathlen = 0;
-            } else
+            } else {
+                /* TODO(davidben): |ASN1_INTEGER_get| returns -1 on overflow,
+                 * which currently acts as if the constraint isn't present. This
+                 * works (an overflowing path length constraint may as well be
+                 * infinity), but Chromium's verifier simply treats values above
+                 * 255 as an error. */
                 x->ex_pathlen = ASN1_INTEGER_get(bs->pathlen);
+            }
         } else
             x->ex_pathlen = -1;
         BASIC_CONSTRAINTS_free(bs);
@@ -855,9 +861,9 @@
 
 uint32_t X509_get_extension_flags(X509 *x)
 {
-    if (!x509v3_cache_extensions(x)) {
-        return 0;
-    }
+    /* Ignore the return value. On failure, |x->ex_flags| will include
+     * |EXFLAG_INVALID|. */
+    x509v3_cache_extensions(x);
     return x->ex_flags;
 }
 
@@ -912,3 +918,12 @@
     }
     return x509->akid != NULL ? x509->akid->serial : NULL;
 }
+
+long X509_get_pathlen(X509 *x509)
+{
+    if (!x509v3_cache_extensions(x509) ||
+        (x509->ex_flags & EXFLAG_BCONS) == 0) {
+        return -1;
+    }
+    return x509->ex_pathlen;
+}