Const-correct X509_TRUST and X509_PURPOSE

This gets the built-in tables out of mutable data.

Update-Note: No one uses these APIs except for rust-openssl.
rust-openssl may need fixes because they seem to not quite handle C
const correctly.

Change-Id: Ia23c61e2fe6a5637e59044e10ea2048cfe46e502
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/64508
Reviewed-by: Bob Beck <bbe@google.com>
Commit-Queue: David Benjamin <davidben@google.com>
diff --git a/crypto/x509/v3_purp.c b/crypto/x509/v3_purp.c
index 9db45ba..9a33a69 100644
--- a/crypto/x509/v3_purp.c
+++ b/crypto/x509/v3_purp.c
@@ -94,7 +94,7 @@
 static int no_check(const X509_PURPOSE *xp, const X509 *x, int ca);
 static int ocsp_helper(const X509_PURPOSE *xp, const X509 *x, int ca);
 
-static X509_PURPOSE xstandard[] = {
+static const X509_PURPOSE xstandard[] = {
     {X509_PURPOSE_SSL_CLIENT, X509_TRUST_SSL_CLIENT, 0,
      check_purpose_ssl_client, (char *)"SSL client", (char *)"sslclient", NULL},
     {X509_PURPOSE_SSL_SERVER, X509_TRUST_SSL_SERVER, 0,
@@ -150,7 +150,7 @@
 
 int X509_PURPOSE_get_count(void) { return OPENSSL_ARRAY_SIZE(xstandard); }
 
-X509_PURPOSE *X509_PURPOSE_get0(int idx) {
+const X509_PURPOSE *X509_PURPOSE_get0(int idx) {
   if (idx < 0 || (size_t)idx >= OPENSSL_ARRAY_SIZE(xstandard)) {
     return NULL;
   }
@@ -158,7 +158,7 @@
 }
 
 int X509_PURPOSE_get_by_sname(const char *sname) {
-  X509_PURPOSE *xptmp;
+  const X509_PURPOSE *xptmp;
   for (int i = 0; i < X509_PURPOSE_get_count(); i++) {
     xptmp = X509_PURPOSE_get0(i);
     if (!strcmp(xptmp->sname, sname)) {
diff --git a/crypto/x509/x509_trs.c b/crypto/x509/x509_trs.c
index ce4194b..122c20e 100644
--- a/crypto/x509/x509_trs.c
+++ b/crypto/x509/x509_trs.c
@@ -63,9 +63,9 @@
 #include "internal.h"
 
 
-static int trust_1oidany(X509_TRUST *trust, X509 *x, int flags);
-static int trust_1oid(X509_TRUST *trust, X509 *x, int flags);
-static int trust_compat(X509_TRUST *trust, X509 *x, int flags);
+static int trust_1oidany(const X509_TRUST *trust, X509 *x, int flags);
+static int trust_1oid(const X509_TRUST *trust, X509 *x, int flags);
+static int trust_compat(const X509_TRUST *trust, X509 *x, int flags);
 
 static int obj_trust(int id, X509 *x, int flags);
 
@@ -73,7 +73,7 @@
 // any gaps so we can just subtract the minimum trust value to get an index
 // into the table
 
-static X509_TRUST trstandard[] = {
+static const X509_TRUST trstandard[] = {
     {X509_TRUST_COMPAT, 0, trust_compat, (char *)"compatible", 0, NULL},
     {X509_TRUST_SSL_CLIENT, 0, trust_1oidany, (char *)"SSL Client",
      NID_client_auth, NULL},
@@ -91,7 +91,6 @@
      NULL}};
 
 int X509_check_trust(X509 *x, int id, int flags) {
-  X509_TRUST *pt;
   int idx;
   if (id == -1) {
     return 1;
@@ -109,13 +108,13 @@
   if (idx == -1) {
     return obj_trust(id, x, flags);
   }
-  pt = X509_TRUST_get0(idx);
+  const X509_TRUST *pt = X509_TRUST_get0(idx);
   return pt->check_trust(pt, x, flags);
 }
 
 int X509_TRUST_get_count(void) { return OPENSSL_ARRAY_SIZE(trstandard); }
 
-X509_TRUST *X509_TRUST_get0(int idx) {
+const X509_TRUST *X509_TRUST_get0(int idx) {
   if (idx < 0 || (size_t)idx >= OPENSSL_ARRAY_SIZE(trstandard)) {
     return NULL;
   }
@@ -144,7 +143,7 @@
 
 int X509_TRUST_get_trust(const X509_TRUST *xp) { return xp->trust; }
 
-static int trust_1oidany(X509_TRUST *trust, X509 *x, int flags) {
+static int trust_1oidany(const X509_TRUST *trust, X509 *x, int flags) {
   if (x->aux && (x->aux->trust || x->aux->reject)) {
     return obj_trust(trust->arg1, x, flags);
   }
@@ -153,14 +152,14 @@
   return trust_compat(trust, x, flags);
 }
 
-static int trust_1oid(X509_TRUST *trust, X509 *x, int flags) {
+static int trust_1oid(const X509_TRUST *trust, X509 *x, int flags) {
   if (x->aux) {
     return obj_trust(trust->arg1, x, flags);
   }
   return X509_TRUST_UNTRUSTED;
 }
 
-static int trust_compat(X509_TRUST *trust, X509 *x, int flags) {
+static int trust_compat(const X509_TRUST *trust, X509 *x, int flags) {
   if (!x509v3_cache_extensions(x)) {
     return X509_TRUST_UNTRUSTED;
   }
diff --git a/crypto/x509/x509_vfy.c b/crypto/x509/x509_vfy.c
index 011bb17..090ed03 100644
--- a/crypto/x509/x509_vfy.c
+++ b/crypto/x509/x509_vfy.c
@@ -1588,13 +1588,12 @@
   }
   // If we have a purpose then check it is valid
   if (purpose) {
-    X509_PURPOSE *ptmp;
     idx = X509_PURPOSE_get_by_id(purpose);
     if (idx == -1) {
       OPENSSL_PUT_ERROR(X509, X509_R_UNKNOWN_PURPOSE_ID);
       return 0;
     }
-    ptmp = X509_PURPOSE_get0(idx);
+    const X509_PURPOSE *ptmp = X509_PURPOSE_get0(idx);
     if (ptmp->trust == X509_TRUST_DEFAULT) {
       idx = X509_PURPOSE_get_by_id(def_purpose);
       if (idx == -1) {
diff --git a/include/openssl/x509.h b/include/openssl/x509.h
index b7352af..12b38c8 100644
--- a/include/openssl/x509.h
+++ b/include/openssl/x509.h
@@ -3112,7 +3112,7 @@
 struct x509_trust_st {
   int trust;
   int flags;
-  int (*check_trust)(struct x509_trust_st *, X509 *, int);
+  int (*check_trust)(const X509_TRUST *, X509 *, int);
   char *name;
   int arg1;
   void *arg2;
@@ -3177,7 +3177,7 @@
 
 OPENSSL_EXPORT int X509_check_trust(X509 *x, int id, int flags);
 OPENSSL_EXPORT int X509_TRUST_get_count(void);
-OPENSSL_EXPORT X509_TRUST *X509_TRUST_get0(int idx);
+OPENSSL_EXPORT const X509_TRUST *X509_TRUST_get0(int idx);
 OPENSSL_EXPORT int X509_TRUST_get_by_id(int id);
 OPENSSL_EXPORT int X509_TRUST_get_flags(const X509_TRUST *xp);
 OPENSSL_EXPORT char *X509_TRUST_get0_name(const X509_TRUST *xp);
@@ -4222,7 +4222,7 @@
 OPENSSL_EXPORT int X509_check_akid(X509 *issuer, AUTHORITY_KEYID *akid);
 
 OPENSSL_EXPORT int X509_PURPOSE_get_count(void);
-OPENSSL_EXPORT X509_PURPOSE *X509_PURPOSE_get0(int idx);
+OPENSSL_EXPORT const X509_PURPOSE *X509_PURPOSE_get0(int idx);
 OPENSSL_EXPORT int X509_PURPOSE_get_by_sname(const char *sname);
 OPENSSL_EXPORT int X509_PURPOSE_get_by_id(int id);
 OPENSSL_EXPORT char *X509_PURPOSE_get0_name(const X509_PURPOSE *xp);