Document or unexport some more of x509.h

Get the remaining config APIs, extensions accessors, and the get1_email
family. I'm not sure yet whether the various remaining
extension-specific functions should get their own sections (probably),
in which case, maybe we should move the accessors these into their
sections? Put them with the rest of the certificate getters for now.

As part of this, deduplicate the X509v3_KU_* and KU_* constants. See
https://github.com/openssl/openssl/issues/22955

Bug: 426
Change-Id: I31a9b887eb1e6cfa272f04d2ee80dbb5a9ed98f7
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/64256
Reviewed-by: Bob Beck <bbe@google.com>
Commit-Queue: Bob Beck <bbe@google.com>
diff --git a/crypto/x509/internal.h b/crypto/x509/internal.h
index 7ee3ee7..efb9037 100644
--- a/crypto/x509/internal.h
+++ b/crypto/x509/internal.h
@@ -567,6 +567,16 @@
 // |name|, or NULL if no such name is defined.
 const X509_VERIFY_PARAM *X509_VERIFY_PARAM_lookup(const char *name);
 
+GENERAL_NAME *v2i_GENERAL_NAME(const X509V3_EXT_METHOD *method,
+                               const X509V3_CTX *ctx, const CONF_VALUE *cnf);
+GENERAL_NAME *v2i_GENERAL_NAME_ex(GENERAL_NAME *out,
+                                  const X509V3_EXT_METHOD *method,
+                                  const X509V3_CTX *ctx, const CONF_VALUE *cnf,
+                                  int is_nc);
+GENERAL_NAMES *v2i_GENERAL_NAMES(const X509V3_EXT_METHOD *method,
+                                 const X509V3_CTX *ctx,
+                                 const STACK_OF(CONF_VALUE) *nval);
+
 
 #if defined(__cplusplus)
 }  // extern C
diff --git a/crypto/x509/v3_alt.c b/crypto/x509/v3_alt.c
index f61645a..61ea4a9 100644
--- a/crypto/x509/v3_alt.c
+++ b/crypto/x509/v3_alt.c
@@ -446,10 +446,10 @@
   return v2i_GENERAL_NAME_ex(NULL, method, ctx, cnf, 0);
 }
 
-GENERAL_NAME *a2i_GENERAL_NAME(GENERAL_NAME *out,
-                               const X509V3_EXT_METHOD *method,
-                               const X509V3_CTX *ctx, int gen_type,
-                               const char *value, int is_nc) {
+static GENERAL_NAME *a2i_GENERAL_NAME(GENERAL_NAME *out,
+                                      const X509V3_EXT_METHOD *method,
+                                      const X509V3_CTX *ctx, int gen_type,
+                                      const char *value, int is_nc) {
   if (!value) {
     OPENSSL_PUT_ERROR(X509V3, X509V3_R_MISSING_VALUE);
     return NULL;
diff --git a/crypto/x509/v3_info.c b/crypto/x509/v3_info.c
index eb190de..ce7e523 100644
--- a/crypto/x509/v3_info.c
+++ b/crypto/x509/v3_info.c
@@ -67,6 +67,9 @@
 #include <openssl/obj.h>
 #include <openssl/x509.h>
 
+#include "internal.h"
+
+
 static STACK_OF(CONF_VALUE) *i2v_AUTHORITY_INFO_ACCESS(
     const X509V3_EXT_METHOD *method, void *ext, STACK_OF(CONF_VALUE) *ret);
 static void *v2i_AUTHORITY_INFO_ACCESS(const X509V3_EXT_METHOD *method,
@@ -206,8 +209,3 @@
   sk_ACCESS_DESCRIPTION_pop_free(ainfo, ACCESS_DESCRIPTION_free);
   return NULL;
 }
-
-int i2a_ACCESS_DESCRIPTION(BIO *bp, const ACCESS_DESCRIPTION *a) {
-  i2a_ASN1_OBJECT(bp, a->method);
-  return 2;
-}
diff --git a/crypto/x509/v3_purp.c b/crypto/x509/v3_purp.c
index e7a9764..de1e8be 100644
--- a/crypto/x509/v3_purp.c
+++ b/crypto/x509/v3_purp.c
@@ -498,7 +498,7 @@
     x->ex_flags |= EXFLAG_SI;
     // If SKID matches AKID also indicate self signed
     if (X509_check_akid(x, x->akid) == X509_V_OK &&
-        !ku_reject(x, KU_KEY_CERT_SIGN)) {
+        !ku_reject(x, X509v3_KU_KEY_CERT_SIGN)) {
       x->ex_flags |= EXFLAG_SS;
     }
   }
@@ -534,7 +534,7 @@
 // otherwise.
 static int check_ca(const X509 *x) {
   // keyUsage if present should allow cert signing
-  if (ku_reject(x, KU_KEY_CERT_SIGN)) {
+  if (ku_reject(x, X509v3_KU_KEY_CERT_SIGN)) {
     return 0;
   }
   // Version 1 certificates are considered CAs and don't have extensions.
@@ -561,7 +561,7 @@
     return check_ca(x);
   }
   // We need to do digital signatures or key agreement
-  if (ku_reject(x, KU_DIGITAL_SIGNATURE | KU_KEY_AGREEMENT)) {
+  if (ku_reject(x, X509v3_KU_DIGITAL_SIGNATURE | X509v3_KU_KEY_AGREEMENT)) {
     return 0;
   }
   // nsCertType if present should allow SSL client use
@@ -574,7 +574,9 @@
 // Key usage needed for TLS/SSL server: digital signature, encipherment or
 // key agreement. The ssl code can check this more thoroughly for individual
 // key types.
-#define KU_TLS (KU_DIGITAL_SIGNATURE | KU_KEY_ENCIPHERMENT | KU_KEY_AGREEMENT)
+#define X509v3_KU_TLS                                         \
+  (X509v3_KU_DIGITAL_SIGNATURE | X509v3_KU_KEY_ENCIPHERMENT | \
+   X509v3_KU_KEY_AGREEMENT)
 
 static int check_purpose_ssl_server(const X509_PURPOSE *xp, const X509 *x,
                                     int ca) {
@@ -588,7 +590,7 @@
   if (ns_reject(x, NS_SSL_SERVER)) {
     return 0;
   }
-  if (ku_reject(x, KU_TLS)) {
+  if (ku_reject(x, X509v3_KU_TLS)) {
     return 0;
   }
 
@@ -603,7 +605,7 @@
     return ret;
   }
   // We need to encipher or Netscape complains
-  if (ku_reject(x, KU_KEY_ENCIPHERMENT)) {
+  if (ku_reject(x, X509v3_KU_KEY_ENCIPHERMENT)) {
     return 0;
   }
   return ret;
@@ -636,7 +638,7 @@
   if (!ret || ca) {
     return ret;
   }
-  if (ku_reject(x, KU_DIGITAL_SIGNATURE | KU_NON_REPUDIATION)) {
+  if (ku_reject(x, X509v3_KU_DIGITAL_SIGNATURE | X509v3_KU_NON_REPUDIATION)) {
     return 0;
   }
   return ret;
@@ -649,7 +651,7 @@
   if (!ret || ca) {
     return ret;
   }
-  if (ku_reject(x, KU_KEY_ENCIPHERMENT)) {
+  if (ku_reject(x, X509v3_KU_KEY_ENCIPHERMENT)) {
     return 0;
   }
   return ret;
@@ -660,7 +662,7 @@
   if (ca) {
     return check_ca(x);
   }
-  if (ku_reject(x, KU_CRL_SIGN)) {
+  if (ku_reject(x, X509v3_KU_CRL_SIGN)) {
     return 0;
   }
   return 1;
@@ -691,8 +693,10 @@
   // and/or nonRepudiation (other values are not consistent and shall
   // be rejected).
   if ((x->ex_flags & EXFLAG_KUSAGE) &&
-      ((x->ex_kusage & ~(KU_NON_REPUDIATION | KU_DIGITAL_SIGNATURE)) ||
-       !(x->ex_kusage & (KU_NON_REPUDIATION | KU_DIGITAL_SIGNATURE)))) {
+      ((x->ex_kusage &
+        ~(X509v3_KU_NON_REPUDIATION | X509v3_KU_DIGITAL_SIGNATURE)) ||
+       !(x->ex_kusage &
+         (X509v3_KU_NON_REPUDIATION | X509v3_KU_DIGITAL_SIGNATURE)))) {
     return 0;
   }
 
@@ -739,7 +743,7 @@
     }
   }
 
-  if (ku_reject(issuer, KU_KEY_CERT_SIGN)) {
+  if (ku_reject(issuer, X509v3_KU_KEY_CERT_SIGN)) {
     return X509_V_ERR_KEYUSAGE_NO_CERTSIGN;
   }
   return X509_V_OK;
@@ -798,6 +802,9 @@
   if (x->ex_flags & EXFLAG_KUSAGE) {
     return x->ex_kusage;
   }
+  // If there is no extension, key usage is unconstrained, so set all bits to
+  // one. Note that, although we use |UINT32_MAX|, |ex_kusage| only contains the
+  // first 16 bits when the extension is present.
   return UINT32_MAX;
 }
 
@@ -808,6 +815,8 @@
   if (x->ex_flags & EXFLAG_XKUSAGE) {
     return x->ex_xkusage;
   }
+  // If there is no extension, extended key usage is unconstrained, so set all
+  // bits to one.
   return UINT32_MAX;
 }
 
diff --git a/crypto/x509/v3_utl.c b/crypto/x509/v3_utl.c
index 04d940f..559143b 100644
--- a/crypto/x509/v3_utl.c
+++ b/crypto/x509/v3_utl.c
@@ -555,7 +555,7 @@
   return strcmp(*a, *b);
 }
 
-STACK_OF(OPENSSL_STRING) *X509_get1_email(X509 *x) {
+STACK_OF(OPENSSL_STRING) *X509_get1_email(const X509 *x) {
   GENERAL_NAMES *gens;
   STACK_OF(OPENSSL_STRING) *ret;
 
@@ -565,7 +565,7 @@
   return ret;
 }
 
-STACK_OF(OPENSSL_STRING) *X509_get1_ocsp(X509 *x) {
+STACK_OF(OPENSSL_STRING) *X509_get1_ocsp(const X509 *x) {
   AUTHORITY_INFO_ACCESS *info;
   STACK_OF(OPENSSL_STRING) *ret = NULL;
   size_t i;
@@ -588,7 +588,7 @@
   return ret;
 }
 
-STACK_OF(OPENSSL_STRING) *X509_REQ_get1_email(X509_REQ *x) {
+STACK_OF(OPENSSL_STRING) *X509_REQ_get1_email(const X509_REQ *x) {
   GENERAL_NAMES *gens;
   STACK_OF(X509_EXTENSION) *exts;
   STACK_OF(OPENSSL_STRING) *ret;
@@ -1143,12 +1143,8 @@
   return ret;
 
 err:
-  if (iptmp) {
-    OPENSSL_free(iptmp);
-  }
-  if (ret) {
-    ASN1_OCTET_STRING_free(ret);
-  }
+  OPENSSL_free(iptmp);
+  ASN1_OCTET_STRING_free(ret);
   return NULL;
 }
 
diff --git a/crypto/x509/x509_req.c b/crypto/x509/x509_req.c
index 563627f..6b14a8c 100644
--- a/crypto/x509/x509_req.c
+++ b/crypto/x509/x509_req.c
@@ -114,7 +114,7 @@
   return req_nid == NID_ext_req || req_nid == NID_ms_ext_req;
 }
 
-STACK_OF(X509_EXTENSION) *X509_REQ_get_extensions(X509_REQ *req) {
+STACK_OF(X509_EXTENSION) *X509_REQ_get_extensions(const X509_REQ *req) {
   if (req == NULL || req->req_info == NULL) {
     return NULL;
   }
@@ -127,8 +127,10 @@
     return NULL;
   }
 
-  X509_ATTRIBUTE *attr = X509_REQ_get_attr(req, idx);
-  ASN1_TYPE *ext = X509_ATTRIBUTE_get0_type(attr, 0);
+  const X509_ATTRIBUTE *attr = X509_REQ_get_attr(req, idx);
+  // TODO(davidben): |X509_ATTRIBUTE_get0_type| is not const-correct. It should
+  // take and return a const pointer.
+  const ASN1_TYPE *ext = X509_ATTRIBUTE_get0_type((X509_ATTRIBUTE *)attr, 0);
   if (!ext || ext->type != V_ASN1_SEQUENCE) {
     return NULL;
   }
diff --git a/crypto/x509/x509_vfy.c b/crypto/x509/x509_vfy.c
index 09394cc..011bb17 100644
--- a/crypto/x509/x509_vfy.c
+++ b/crypto/x509/x509_vfy.c
@@ -1198,7 +1198,7 @@
   if (issuer) {
     // Check for cRLSign bit if keyUsage present
     if ((issuer->ex_flags & EXFLAG_KUSAGE) &&
-        !(issuer->ex_kusage & KU_CRL_SIGN)) {
+        !(issuer->ex_kusage & X509v3_KU_CRL_SIGN)) {
       ctx->error = X509_V_ERR_KEYUSAGE_NO_CRL_SIGN;
       ok = ctx->verify_cb(0, ctx);
       if (!ok) {
diff --git a/include/openssl/base.h b/include/openssl/base.h
index af69282..f0981b8 100644
--- a/include/openssl/base.h
+++ b/include/openssl/base.h
@@ -373,6 +373,7 @@
 typedef struct trust_token_issuer_st TRUST_TOKEN_ISSUER;
 typedef struct trust_token_method_st TRUST_TOKEN_METHOD;
 typedef struct v3_ext_ctx X509V3_CTX;
+typedef struct v3_ext_method X509V3_EXT_METHOD;
 typedef struct x509_attributes_st X509_ATTRIBUTE;
 typedef struct x509_lookup_st X509_LOOKUP;
 typedef struct x509_lookup_method_st X509_LOOKUP_METHOD;
diff --git a/include/openssl/x509.h b/include/openssl/x509.h
index 09ae9c0..7f42593 100644
--- a/include/openssl/x509.h
+++ b/include/openssl/x509.h
@@ -222,6 +222,45 @@
                                    const ASN1_BIT_STRING **out_issuer_uid,
                                    const ASN1_BIT_STRING **out_subject_uid);
 
+// The following bits are returned from |X509_get_extension_flags|.
+
+// EXFLAG_BCONS indicates the certificate has a basic constraints extension.
+#define EXFLAG_BCONS 0x1
+// EXFLAG_KUSAGE indicates the certifcate has a key usage extension.
+#define EXFLAG_KUSAGE 0x2
+// EXFLAG_XKUSAGE indicates the certifcate has an extended key usage extension.
+#define EXFLAG_XKUSAGE 0x4
+// EXFLAG_NSCERT indicates the certificate has a legacy Netscape certificate
+// type extension.
+#define EXFLAG_NSCERT 0x8
+// EXFLAG_CA indicates the certificate has a basic constraints extension with
+// the CA bit set.
+#define EXFLAG_CA 0x10
+// EXFLAG_SI indicates the certificate is self-issued, i.e. its subject and
+// issuer names match.
+#define EXFLAG_SI 0x20
+// EXFLAG_V1 indicates an X.509v1 certificate.
+#define EXFLAG_V1 0x40
+// EXFLAG_INVALID indicates an error processing some extension. The certificate
+// should not be accepted. Note the lack of this bit does not imply all
+// extensions are valid, only those used to compute extension flags.
+#define EXFLAG_INVALID 0x80
+// EXFLAG_SET is an internal bit that indicates extension flags were computed.
+#define EXFLAG_SET 0x100
+// EXFLAG_CRITICAL indicates an unsupported critical extension. The certificate
+// should not be accepted.
+#define EXFLAG_CRITICAL 0x200
+// EXFLAG_SS indicates the certificate is likely self-signed. That is, if it is
+// self-issued, its authority key identifer (if any) matches itself, and its key
+// usage extension (if any) allows certificate signatures. The signature itself
+// is not checked in computing this bit.
+#define EXFLAG_SS 0x2000
+
+// X509_get_extension_flags decodes a set of extensions from |x509| and returns
+// a collection of |EXFLAG_*| bits which reflect |x509|. If there was an error
+// in computing this bitmask, the result will include the |EXFLAG_INVALID| bit.
+OPENSSL_EXPORT uint32_t X509_get_extension_flags(X509 *x509);
+
 // X509_get_pathlen returns path length constraint from the basic constraints
 // extension in |x509|. (See RFC 5280, section 4.2.1.9.) It returns -1 if the
 // constraint is not present, or if some extension in |x509| was invalid.
@@ -231,6 +270,101 @@
 // |X509_get_extensions_flags| and check the |EXFLAG_INVALID| bit.
 OPENSSL_EXPORT long X509_get_pathlen(X509 *x509);
 
+// X509v3_KU_* are key usage bits returned from |X509_get_key_usage|.
+#define X509v3_KU_DIGITAL_SIGNATURE 0x0080
+#define X509v3_KU_NON_REPUDIATION 0x0040
+#define X509v3_KU_KEY_ENCIPHERMENT 0x0020
+#define X509v3_KU_DATA_ENCIPHERMENT 0x0010
+#define X509v3_KU_KEY_AGREEMENT 0x0008
+#define X509v3_KU_KEY_CERT_SIGN 0x0004
+#define X509v3_KU_CRL_SIGN 0x0002
+#define X509v3_KU_ENCIPHER_ONLY 0x0001
+#define X509v3_KU_DECIPHER_ONLY 0x8000
+
+// X509_get_key_usage returns a bitmask of key usages (see Section 4.2.1.3 of
+// RFC 5280) which |x509| is valid for. This function only reports the first 16
+// bits, in a little-endian byte order, but big-endian bit order. That is, bits
+// 0 though 7 are reported at 1<<7 through 1<<0, and bits 8 through 15 are
+// reported at 1<<15 through 1<<8.
+//
+// Instead of depending on this bit order, callers should compare against the
+// |X509v3_KU_*| constants.
+//
+// If |x509| has no key usage extension, all key usages are valid and this
+// function returns |UINT32_MAX|. If there was an error processing |x509|'s
+// extensions, or if the first 16 bits in the key usage extension were all zero,
+// this function returns zero.
+OPENSSL_EXPORT uint32_t X509_get_key_usage(X509 *x509);
+
+// XKU_* are extended key usage bits returned from
+// |X509_get_extended_key_usage|.
+#define XKU_SSL_SERVER 0x1
+#define XKU_SSL_CLIENT 0x2
+#define XKU_SMIME 0x4
+#define XKU_CODE_SIGN 0x8
+#define XKU_SGC 0x10
+#define XKU_OCSP_SIGN 0x20
+#define XKU_TIMESTAMP 0x40
+#define XKU_DVCS 0x80
+#define XKU_ANYEKU 0x100
+
+// X509_get_extended_key_usage returns a bitmask of extended key usages (see
+// Section 4.2.1.12 of RFC 5280) which |x509| is valid for. The result will be
+// a combination of |XKU_*| constants. If checking an extended key usage not
+// defined above, callers should extract the extended key usage extension
+// separately, e.g. via |X509_get_ext_d2i|.
+//
+// If |x509| has no extended key usage extension, all extended key usages are
+// valid and this function returns |UINT32_MAX|. If there was an error
+// processing |x509|'s extensions, or if |x509|'s extended key usage extension
+// contained no recognized usages, this function returns zero.
+OPENSSL_EXPORT uint32_t X509_get_extended_key_usage(X509 *x509);
+
+// X509_get0_subject_key_id returns |x509|'s subject key identifier, if present.
+// (See RFC 5280, section 4.2.1.2.) It returns NULL if the extension is not
+// present or if some extension in |x509| was invalid.
+//
+// TODO(crbug.com/boringssl/381): Decoding an |X509| object will not check for
+// invalid extensions. To detect the error case, call
+// |X509_get_extensions_flags| and check the |EXFLAG_INVALID| bit.
+OPENSSL_EXPORT const ASN1_OCTET_STRING *X509_get0_subject_key_id(X509 *x509);
+
+// X509_get0_authority_key_id returns keyIdentifier of |x509|'s authority key
+// identifier, if the extension and field are present. (See RFC 5280,
+// section 4.2.1.1.) It returns NULL if the extension is not present, if it is
+// present but lacks a keyIdentifier field, or if some extension in |x509| was
+// invalid.
+//
+// TODO(crbug.com/boringssl/381): Decoding an |X509| object will not check for
+// invalid extensions. To detect the error case, call
+// |X509_get_extensions_flags| and check the |EXFLAG_INVALID| bit.
+OPENSSL_EXPORT const ASN1_OCTET_STRING *X509_get0_authority_key_id(X509 *x509);
+
+DEFINE_STACK_OF(GENERAL_NAME)
+typedef STACK_OF(GENERAL_NAME) GENERAL_NAMES;
+
+// X509_get0_authority_issuer returns the authorityCertIssuer of |x509|'s
+// authority key identifier, if the extension and field are present. (See
+// RFC 5280, section 4.2.1.1.) It returns NULL if the extension is not present,
+// if it is present but lacks a authorityCertIssuer field, or if some extension
+// in |x509| was invalid.
+//
+// TODO(crbug.com/boringssl/381): Decoding an |X509| object will not check for
+// invalid extensions. To detect the error case, call
+// |X509_get_extensions_flags| and check the |EXFLAG_INVALID| bit.
+OPENSSL_EXPORT const GENERAL_NAMES *X509_get0_authority_issuer(X509 *x509);
+
+// X509_get0_authority_serial returns the authorityCertSerialNumber of |x509|'s
+// authority key identifier, if the extension and field are present. (See
+// RFC 5280, section 4.2.1.1.) It returns NULL if the extension is not present,
+// if it is present but lacks a authorityCertSerialNumber field, or if some
+// extension in |x509| was invalid.
+//
+// TODO(crbug.com/boringssl/381): Decoding an |X509| object will not check for
+// invalid extensions. To detect the error case, call
+// |X509_get_extensions_flags| and check the |EXFLAG_INVALID| bit.
+OPENSSL_EXPORT const ASN1_INTEGER *X509_get0_authority_serial(X509 *x509);
+
 // X509_get0_extensions returns |x509|'s extension list, or NULL if |x509| omits
 // it.
 OPENSSL_EXPORT const STACK_OF(X509_EXTENSION) *X509_get0_extensions(
@@ -305,6 +439,30 @@
 // validation.
 OPENSSL_EXPORT int X509_verify(X509 *x509, EVP_PKEY *pkey);
 
+// X509_get1_email returns a newly-allocated list of NUL-terminated strings
+// containing all email addresses in |x509|'s subject and all rfc822name names
+// in |x509|'s subject alternative names. Email addresses which contain embedded
+// NUL bytes are skipped.
+//
+// On error, or if there are no such email addresses, it returns NULL. When
+// done, the caller must release the result with |X509_email_free|.
+OPENSSL_EXPORT STACK_OF(OPENSSL_STRING) *X509_get1_email(const X509 *x509);
+
+// X509_get1_ocsp returns a newly-allocated list of NUL-terminated strings
+// containing all OCSP URIs in |x509|. That is, it collects all URI
+// AccessDescriptions with an accessMethod of id-ad-ocsp in |x509|'s authority
+// information access extension. URIs which contain embedded NUL bytes are
+// skipped.
+//
+// On error, or if there are no such URIs, it returns NULL. When done, the
+// caller must release the result with |X509_email_free|.
+OPENSSL_EXPORT STACK_OF(OPENSSL_STRING) *X509_get1_ocsp(const X509 *x509);
+
+// X509_email_free releases memory associated with |sk|, including |sk| itself.
+// Each |OPENSSL_STRING| in |sk| must be a NUL-terminated string allocated with
+// |OPENSSL_malloc|. If |sk| is NULL, no action is taken.
+OPENSSL_EXPORT void X509_email_free(STACK_OF(OPENSSL_STRING) *sk);
+
 
 // Issuing certificates.
 //
@@ -988,16 +1146,18 @@
 // (a Microsoft szOID_CERT_EXTENSIONS variant).
 OPENSSL_EXPORT int X509_REQ_extension_nid(int nid);
 
-// X509_REQ_get_extensions decodes the list of requested extensions in |req| and
-// returns a newly-allocated |STACK_OF(X509_EXTENSION)| containing the result.
-// It returns NULL on error, or if |req| did not request extensions.
+// X509_REQ_get_extensions decodes the most preferred list of requested
+// extensions in |req| and returns a newly-allocated |STACK_OF(X509_EXTENSION)|
+// containing the result. It returns NULL on error, or if |req| did not request
+// extensions.
 //
 // CSRs do not store extensions directly. Instead there are attribute types
 // which are defined to hold extensions. See |X509_REQ_extension_nid|. This
 // function supports both pkcs-9-at-extensionRequest from RFC 2985 and the
 // Microsoft szOID_CERT_EXTENSIONS variant. If both are present,
 // pkcs-9-at-extensionRequest is preferred.
-OPENSSL_EXPORT STACK_OF(X509_EXTENSION) *X509_REQ_get_extensions(X509_REQ *req);
+OPENSSL_EXPORT STACK_OF(X509_EXTENSION) *X509_REQ_get_extensions(
+    const X509_REQ *req);
 
 // X509_REQ_get0_signature sets |*out_sig| and |*out_alg| to the signature and
 // signature algorithm of |req|, respectively. Either output pointer may be NULL
@@ -1015,6 +1175,17 @@
 // one if the signature is valid and zero otherwise.
 OPENSSL_EXPORT int X509_REQ_verify(X509_REQ *req, EVP_PKEY *pkey);
 
+// X509_REQ_get1_email returns a newly-allocated list of NUL-terminated strings
+// containing all email addresses in |req|'s subject and all rfc822name names
+// in |req|'s subject alternative names. The subject alternative names extension
+// is extracted from the result of |X509_REQ_get_extensions|. Email addresses
+// which contain embedded NUL bytes are skipped.
+//
+// On error, or if there are no such email addresses, it returns NULL. When
+// done, the caller must release the result with |X509_email_free|.
+OPENSSL_EXPORT STACK_OF(OPENSSL_STRING) *X509_REQ_get1_email(
+    const X509_REQ *req);
+
 
 // Issuing certificate requests.
 //
@@ -2726,6 +2897,85 @@
                                             const X509V3_CTX *ctx,
                                             const char *section, X509_CRL *crl);
 
+// i2s_ASN1_OCTET_STRING returns a human-readable representation of |oct| as a
+// newly-allocated, NUL-terminated string, or NULL on error. |method| is
+// ignored. The caller must release the result with |OPENSSL_free| when done.
+OPENSSL_EXPORT char *i2s_ASN1_OCTET_STRING(const X509V3_EXT_METHOD *method,
+                                           const ASN1_OCTET_STRING *oct);
+
+// s2i_ASN1_OCTET_STRING decodes |str| as a hexdecimal byte string, with
+// optional colon separators between bytes. It returns a newly-allocated
+// |ASN1_OCTET_STRING| with the result on success, or NULL on error. |method|
+// and |ctx| are ignored.
+OPENSSL_EXPORT ASN1_OCTET_STRING *s2i_ASN1_OCTET_STRING(
+    const X509V3_EXT_METHOD *method, const X509V3_CTX *ctx, const char *str);
+
+// i2s_ASN1_INTEGER returns a human-readable representation of |aint| as a
+// newly-allocated, NUL-terminated string, or NULL on error. |method| is
+// ignored. The caller must release the result with |OPENSSL_free| when done.
+OPENSSL_EXPORT char *i2s_ASN1_INTEGER(const X509V3_EXT_METHOD *method,
+                                      const ASN1_INTEGER *aint);
+
+// s2i_ASN1_INTEGER decodes |value| as the ASCII representation of an integer,
+// and returns a newly-allocated |ASN1_INTEGER| containing the result, or NULL
+// on error. |method| is ignored. If |value| begins with "0x" or "0X", the input
+// is decoded in hexadecimal, otherwise decimal.
+OPENSSL_EXPORT ASN1_INTEGER *s2i_ASN1_INTEGER(const X509V3_EXT_METHOD *method,
+                                              const char *value);
+
+// i2s_ASN1_ENUMERATED returns a human-readable representation of |aint| as a
+// newly-allocated, NUL-terminated string, or NULL on error. |method| is
+// ignored. The caller must release the result with |OPENSSL_free| when done.
+OPENSSL_EXPORT char *i2s_ASN1_ENUMERATED(const X509V3_EXT_METHOD *method,
+                                         const ASN1_ENUMERATED *aint);
+
+// X509V3_conf_free releases memory associated with |CONF_VALUE|.
+OPENSSL_EXPORT void X509V3_conf_free(CONF_VALUE *val);
+
+// i2v_GENERAL_NAME serializes |gen| as a |CONF_VALUE|. If |ret| is non-NULL, it
+// appends the value to |ret| and returns |ret| on success or NULL on error. If
+// it returns NULL, the caller is still responsible for freeing |ret|. If |ret|
+// is NULL, it returns a newly-allocated |STACK_OF(CONF_VALUE)| containing the
+// result. |method| is ignored. When done, the caller should release the result
+// with |sk_CONF_VALUE_pop_free| and |X509V3_conf_free|.
+//
+// Do not use this function. This is an internal implementation detail of the
+// human-readable print functions. If extracting a SAN list from a certificate,
+// look at |gen| directly.
+OPENSSL_EXPORT STACK_OF(CONF_VALUE) *i2v_GENERAL_NAME(
+    const X509V3_EXT_METHOD *method, const GENERAL_NAME *gen,
+    STACK_OF(CONF_VALUE) *ret);
+
+// i2v_GENERAL_NAMES serializes |gen| as a list of |CONF_VALUE|s. If |ret| is
+// non-NULL, it appends the values to |ret| and returns |ret| on success or NULL
+// on error. If it returns NULL, the caller is still responsible for freeing
+// |ret|. If |ret| is NULL, it returns a newly-allocated |STACK_OF(CONF_VALUE)|
+// containing the results. |method| is ignored.
+//
+// Do not use this function. This is an internal implementation detail of the
+// human-readable print functions. If extracting a SAN list from a certificate,
+// look at |gen| directly.
+OPENSSL_EXPORT STACK_OF(CONF_VALUE) *i2v_GENERAL_NAMES(
+    const X509V3_EXT_METHOD *method, const GENERAL_NAMES *gen,
+    STACK_OF(CONF_VALUE) *extlist);
+
+// a2i_IPADDRESS decodes |ipasc| as the textual representation of an IPv4 or
+// IPv6 address. On success, it returns a newly-allocated |ASN1_OCTET_STRING|
+// containing the decoded IP address. IPv4 addresses are represented as 4-byte
+// strings and IPv6 addresses as 16-byte strings. On failure, it returns NULL.
+OPENSSL_EXPORT ASN1_OCTET_STRING *a2i_IPADDRESS(const char *ipasc);
+
+// a2i_IPADDRESS_NC decodes |ipasc| as the textual representation of an IPv4 or
+// IPv6 address range. On success, it returns a newly-allocated
+// |ASN1_OCTET_STRING| containing the decoded IP address, followed by the
+// decoded mask. IPv4 ranges are represented as 8-byte strings and IPv6 ranges
+// as 32-byte strings. On failure, it returns NULL.
+//
+// The text format decoded by this function is not the standard CIDR notiation.
+// Instead, the mask after the "/" is represented as another IP address. For
+// example, "192.168.0.0/16" would be written "192.168.0.0/255.255.0.0".
+OPENSSL_EXPORT ASN1_OCTET_STRING *a2i_IPADDRESS_NC(const char *ipasc);
+
 
 // Deprecated functions.
 
@@ -2838,6 +3088,17 @@
 #define X509_STORE_get1_certs X509_STORE_CTX_get1_certs
 #define X509_STORE_get1_crls X509_STORE_CTX_get1_crls
 
+// The following constants are legacy aliases for |X509v3_KU_*|.
+#define KU_DIGITAL_SIGNATURE X509v3_KU_DIGITAL_SIGNATURE
+#define KU_NON_REPUDIATION X509v3_KU_NON_REPUDIATION
+#define KU_KEY_ENCIPHERMENT X509v3_KU_KEY_ENCIPHERMENT
+#define KU_DATA_ENCIPHERMENT X509v3_KU_DATA_ENCIPHERMENT
+#define KU_KEY_AGREEMENT X509v3_KU_KEY_AGREEMENT
+#define KU_KEY_CERT_SIGN X509v3_KU_KEY_CERT_SIGN
+#define KU_CRL_SIGN X509v3_KU_CRL_SIGN
+#define KU_ENCIPHER_ONLY X509v3_KU_ENCIPHER_ONLY
+#define KU_DECIPHER_ONLY X509v3_KU_DECIPHER_ONLY
+
 
 // Private structures.
 
@@ -2849,17 +3110,6 @@
 
 // Functions below this point have not yet been organized into sections.
 
-#define X509v3_KU_DIGITAL_SIGNATURE 0x0080
-#define X509v3_KU_NON_REPUDIATION 0x0040
-#define X509v3_KU_KEY_ENCIPHERMENT 0x0020
-#define X509v3_KU_DATA_ENCIPHERMENT 0x0010
-#define X509v3_KU_KEY_AGREEMENT 0x0008
-#define X509v3_KU_KEY_CERT_SIGN 0x0004
-#define X509v3_KU_CRL_SIGN 0x0002
-#define X509v3_KU_ENCIPHER_ONLY 0x0001
-#define X509v3_KU_DECIPHER_ONLY 0x8000
-#define X509v3_KU_UNDEF 0xffff
-
 // This stuff is certificate "auxiliary info"
 // it contains details which are useful in certificate
 // stores and databases. When used this is tagged onto
@@ -3494,14 +3744,6 @@
 
 OPENSSL_EXPORT int X509_VERIFY_PARAM_get_depth(const X509_VERIFY_PARAM *param);
 
-// Forward reference
-struct v3_ext_method;
-struct v3_ext_ctx;
-
-// Useful typedefs
-
-typedef struct v3_ext_method X509V3_EXT_METHOD;
-
 typedef void *(*X509V3_EXT_NEW)(void);
 typedef void (*X509V3_EXT_FREE)(void *);
 typedef void *(*X509V3_EXT_D2I)(void *, const unsigned char **, long);
@@ -3606,10 +3848,6 @@
   } d;
 } /* GENERAL_NAME */;
 
-DEFINE_STACK_OF(GENERAL_NAME)
-
-typedef STACK_OF(GENERAL_NAME) GENERAL_NAMES;
-
 DEFINE_STACK_OF(GENERAL_NAMES)
 
 typedef struct ACCESS_DESCRIPTION_st {
@@ -3731,32 +3969,6 @@
 
 // X509_PURPOSE stuff
 
-#define EXFLAG_BCONS 0x1
-#define EXFLAG_KUSAGE 0x2
-#define EXFLAG_XKUSAGE 0x4
-#define EXFLAG_NSCERT 0x8
-
-#define EXFLAG_CA 0x10
-// Really self issued not necessarily self signed
-#define EXFLAG_SI 0x20
-#define EXFLAG_V1 0x40
-#define EXFLAG_INVALID 0x80
-#define EXFLAG_SET 0x100
-#define EXFLAG_CRITICAL 0x200
-
-// Self signed
-#define EXFLAG_SS 0x2000
-
-#define KU_DIGITAL_SIGNATURE 0x0080
-#define KU_NON_REPUDIATION 0x0040
-#define KU_KEY_ENCIPHERMENT 0x0020
-#define KU_DATA_ENCIPHERMENT 0x0010
-#define KU_KEY_AGREEMENT 0x0008
-#define KU_KEY_CERT_SIGN 0x0004
-#define KU_CRL_SIGN 0x0002
-#define KU_ENCIPHER_ONLY 0x0001
-#define KU_DECIPHER_ONLY 0x8000
-
 #define NS_SSL_CLIENT 0x80
 #define NS_SSL_SERVER 0x40
 #define NS_SMIME 0x20
@@ -3766,16 +3978,6 @@
 #define NS_OBJSIGN_CA 0x01
 #define NS_ANY_CA (NS_SSL_CA | NS_SMIME_CA | NS_OBJSIGN_CA)
 
-#define XKU_SSL_SERVER 0x1
-#define XKU_SSL_CLIENT 0x2
-#define XKU_SMIME 0x4
-#define XKU_CODE_SIGN 0x8
-#define XKU_SGC 0x10
-#define XKU_OCSP_SIGN 0x20
-#define XKU_TIMESTAMP 0x40
-#define XKU_DVCS 0x80
-#define XKU_ANYEKU 0x100
-
 #define X509_PURPOSE_DYNAMIC 0x1
 #define X509_PURPOSE_DYNAMIC_NAME 0x2
 
@@ -3815,39 +4017,10 @@
 DECLARE_ASN1_FUNCTIONS(GENERAL_NAME)
 OPENSSL_EXPORT GENERAL_NAME *GENERAL_NAME_dup(GENERAL_NAME *a);
 
-// i2v_GENERAL_NAME serializes |gen| as a |CONF_VALUE|. If |ret| is non-NULL, it
-// appends the value to |ret| and returns |ret| on success or NULL on error. If
-// it returns NULL, the caller is still responsible for freeing |ret|. If |ret|
-// is NULL, it returns a newly-allocated |STACK_OF(CONF_VALUE)| containing the
-// result. |method| is ignored.
-//
-// Do not use this function. This is an internal implementation detail of the
-// human-readable print functions. If extracting a SAN list from a certificate,
-// look at |gen| directly.
-OPENSSL_EXPORT STACK_OF(CONF_VALUE) *i2v_GENERAL_NAME(
-    const X509V3_EXT_METHOD *method, const GENERAL_NAME *gen,
-    STACK_OF(CONF_VALUE) *ret);
-
 // TODO(https://crbug.com/boringssl/407): This is not const because it contains
 // an |X509_NAME|.
 DECLARE_ASN1_FUNCTIONS(GENERAL_NAMES)
 
-// i2v_GENERAL_NAMES serializes |gen| as a list of |CONF_VALUE|s. If |ret| is
-// non-NULL, it appends the values to |ret| and returns |ret| on success or NULL
-// on error. If it returns NULL, the caller is still responsible for freeing
-// |ret|. If |ret| is NULL, it returns a newly-allocated |STACK_OF(CONF_VALUE)|
-// containing the results. |method| is ignored.
-//
-// Do not use this function. This is an internal implementation detail of the
-// human-readable print functions. If extracting a SAN list from a certificate,
-// look at |gen| directly.
-OPENSSL_EXPORT STACK_OF(CONF_VALUE) *i2v_GENERAL_NAMES(
-    const X509V3_EXT_METHOD *method, const GENERAL_NAMES *gen,
-    STACK_OF(CONF_VALUE) *extlist);
-OPENSSL_EXPORT GENERAL_NAMES *v2i_GENERAL_NAMES(
-    const X509V3_EXT_METHOD *method, const X509V3_CTX *ctx,
-    const STACK_OF(CONF_VALUE) *nval);
-
 DECLARE_ASN1_FUNCTIONS_const(OTHERNAME)
 DECLARE_ASN1_FUNCTIONS_const(EDIPARTYNAME)
 OPENSSL_EXPORT void GENERAL_NAME_set0_value(GENERAL_NAME *a, int type,
@@ -3860,17 +4033,7 @@
                                                ASN1_OBJECT **poid,
                                                ASN1_TYPE **pvalue);
 
-// i2s_ASN1_OCTET_STRING returns a human-readable representation of |oct| as a
-// newly-allocated, NUL-terminated string, or NULL on error. |method| is
-// ignored. The caller must release the result with |OPENSSL_free| when done.
-OPENSSL_EXPORT char *i2s_ASN1_OCTET_STRING(const X509V3_EXT_METHOD *method,
-                                           const ASN1_OCTET_STRING *oct);
-
-OPENSSL_EXPORT ASN1_OCTET_STRING *s2i_ASN1_OCTET_STRING(
-    const X509V3_EXT_METHOD *method, const X509V3_CTX *ctx, const char *str);
-
 DECLARE_ASN1_FUNCTIONS_const(EXTENDED_KEY_USAGE)
-OPENSSL_EXPORT int i2a_ACCESS_DESCRIPTION(BIO *bp, const ACCESS_DESCRIPTION *a);
 
 DECLARE_ASN1_FUNCTIONS_const(CERTIFICATEPOLICIES)
 DECLARE_ASN1_FUNCTIONS_const(POLICYINFO)
@@ -3916,26 +4079,6 @@
 DECLARE_ASN1_ALLOC_FUNCTIONS(POLICY_CONSTRAINTS)
 DECLARE_ASN1_ITEM(POLICY_CONSTRAINTS)
 
-OPENSSL_EXPORT GENERAL_NAME *a2i_GENERAL_NAME(GENERAL_NAME *out,
-                                              const X509V3_EXT_METHOD *method,
-                                              const X509V3_CTX *ctx, int gen_type,
-                                              const char *value, int is_nc);
-
-OPENSSL_EXPORT GENERAL_NAME *v2i_GENERAL_NAME(const X509V3_EXT_METHOD *method,
-                                              const X509V3_CTX *ctx,
-                                              const CONF_VALUE *cnf);
-OPENSSL_EXPORT GENERAL_NAME *v2i_GENERAL_NAME_ex(
-    GENERAL_NAME *out, const X509V3_EXT_METHOD *method, const X509V3_CTX *ctx,
-    const CONF_VALUE *cnf, int is_nc);
-OPENSSL_EXPORT void X509V3_conf_free(CONF_VALUE *val);
-
-OPENSSL_EXPORT char *i2s_ASN1_INTEGER(const X509V3_EXT_METHOD *meth,
-                                      const ASN1_INTEGER *aint);
-OPENSSL_EXPORT ASN1_INTEGER *s2i_ASN1_INTEGER(const X509V3_EXT_METHOD *meth,
-                                              const char *value);
-OPENSSL_EXPORT char *i2s_ASN1_ENUMERATED(const X509V3_EXT_METHOD *meth,
-                                         const ASN1_ENUMERATED *aint);
-
 // X509V3_EXT_add registers |ext| as a custom extension for the extension type
 // |ext->ext_nid|. |ext| must be valid for the remainder of the address space's
 // lifetime. It returns one on success and zero on error.
@@ -4101,68 +4244,6 @@
 OPENSSL_EXPORT int X509_check_issued(X509 *issuer, X509 *subject);
 OPENSSL_EXPORT int X509_check_akid(X509 *issuer, AUTHORITY_KEYID *akid);
 
-OPENSSL_EXPORT uint32_t X509_get_extension_flags(X509 *x509);
-
-// X509_get_key_usage returns a bitmask of key usages (see Section 4.2.1.3 of
-// RFC 5280) which |x509| is valid for. The result will be a combination of
-// |KU_*| constants.
-//
-// If |x509| has no key usage extension, all key usages are valid and this
-// function returns |UINT32_MAX|. If there was an error processing |x509|'s
-// extensions, this function returns zero.
-OPENSSL_EXPORT uint32_t X509_get_key_usage(X509 *x509);
-
-// X509_get_extended_key_usage returns a bitmask of extended key usages (see
-// Section 4.2.1.12 of RFC 5280) which |x509| is valid for. The result will be
-// a combination of |XKU_*| constants.
-//
-// If |x509| has no extended key usage extension, all extended key usages are
-// valid and this function returns |UINT32_MAX|. If there was an error
-// processing |x509|'s extensions, this function returns zero.
-OPENSSL_EXPORT uint32_t X509_get_extended_key_usage(X509 *x509);
-
-// X509_get0_subject_key_id returns |x509|'s subject key identifier, if present.
-// (See RFC 5280, section 4.2.1.2.) It returns NULL if the extension is not
-// present or if some extension in |x509| was invalid.
-//
-// Note that decoding an |X509| object will not check for invalid extensions. To
-// detect the error case, call |X509_get_extensions_flags| and check the
-// |EXFLAG_INVALID| bit.
-OPENSSL_EXPORT const ASN1_OCTET_STRING *X509_get0_subject_key_id(X509 *x509);
-
-// X509_get0_authority_key_id returns keyIdentifier of |x509|'s authority key
-// identifier, if the extension and field are present. (See RFC 5280,
-// section 4.2.1.1.) It returns NULL if the extension is not present, if it is
-// present but lacks a keyIdentifier field, or if some extension in |x509| was
-// invalid.
-//
-// Note that decoding an |X509| object will not check for invalid extensions. To
-// detect the error case, call |X509_get_extensions_flags| and check the
-// |EXFLAG_INVALID| bit.
-OPENSSL_EXPORT const ASN1_OCTET_STRING *X509_get0_authority_key_id(X509 *x509);
-
-// X509_get0_authority_issuer returns the authorityCertIssuer of |x509|'s
-// authority key identifier, if the extension and field are present. (See
-// RFC 5280, section 4.2.1.1.) It returns NULL if the extension is not present,
-// if it is present but lacks a authorityCertIssuer field, or if some extension
-// in |x509| was invalid.
-//
-// Note that decoding an |X509| object will not check for invalid extensions. To
-// detect the error case, call |X509_get_extensions_flags| and check the
-// |EXFLAG_INVALID| bit.
-OPENSSL_EXPORT const GENERAL_NAMES *X509_get0_authority_issuer(X509 *x509);
-
-// X509_get0_authority_serial returns the authorityCertSerialNumber of |x509|'s
-// authority key identifier, if the extension and field are present. (See
-// RFC 5280, section 4.2.1.1.) It returns NULL if the extension is not present,
-// if it is present but lacks a authorityCertSerialNumber field, or if some
-// extension in |x509| was invalid.
-//
-// Note that decoding an |X509| object will not check for invalid extensions. To
-// detect the error case, call |X509_get_extensions_flags| and check the
-// |EXFLAG_INVALID| bit.
-OPENSSL_EXPORT const ASN1_INTEGER *X509_get0_authority_serial(X509 *x509);
-
 OPENSSL_EXPORT int X509_PURPOSE_get_count(void);
 OPENSSL_EXPORT X509_PURPOSE *X509_PURPOSE_get0(int idx);
 OPENSSL_EXPORT int X509_PURPOSE_get_by_sname(const char *sname);
@@ -4178,10 +4259,6 @@
 OPENSSL_EXPORT void X509_PURPOSE_cleanup(void);
 OPENSSL_EXPORT int X509_PURPOSE_get_id(const X509_PURPOSE *);
 
-OPENSSL_EXPORT STACK_OF(OPENSSL_STRING) *X509_get1_email(X509 *x);
-OPENSSL_EXPORT STACK_OF(OPENSSL_STRING) *X509_REQ_get1_email(X509_REQ *x);
-OPENSSL_EXPORT void X509_email_free(STACK_OF(OPENSSL_STRING) *sk);
-OPENSSL_EXPORT STACK_OF(OPENSSL_STRING) *X509_get1_ocsp(X509 *x);
 // Flags for X509_check_* functions
 
 // Deprecated: this flag does nothing
@@ -4208,9 +4285,6 @@
 OPENSSL_EXPORT int X509_check_ip_asc(X509 *x, const char *ipasc,
                                      unsigned int flags);
 
-OPENSSL_EXPORT ASN1_OCTET_STRING *a2i_IPADDRESS(const char *ipasc);
-OPENSSL_EXPORT ASN1_OCTET_STRING *a2i_IPADDRESS_NC(const char *ipasc);
-
 
 #if defined(__cplusplus)
 }  // extern C