Don't read it->funcs without checking it->itype.

it->funcs is only an ASN1_AUX for ASN1_ITYPE_SEQUENCE and
ASN1_ITYPE_CHOICE. Fortunately, the other possible types for it->funcs
are larger than ASN1_AUX and we don't touch the result when we
shouldn't, so this is merely a strict aliasing violation.

Change-Id: I29e94249e0b137fe8df0b16254366ae6705c8784
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/49351
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: Adam Langley <agl@google.com>
diff --git a/crypto/asn1/tasn_dec.c b/crypto/asn1/tasn_dec.c
index 0d123cc..c5a6477 100644
--- a/crypto/asn1/tasn_dec.c
+++ b/crypto/asn1/tasn_dec.c
@@ -170,8 +170,6 @@
 {
     const ASN1_TEMPLATE *tt, *errtt = NULL;
     const ASN1_EXTERN_FUNCS *ef;
-    const ASN1_AUX *aux = it->funcs;
-    ASN1_aux_cb *asn1_cb;
     const unsigned char *p = NULL, *q;
     unsigned char oclass;
     char seq_eoc, seq_nolen, cst, isopt;
@@ -183,10 +181,6 @@
     aclass &= ~ASN1_TFLG_COMBINE;
     if (!pval)
         return 0;
-    if (aux && aux->asn1_cb)
-        asn1_cb = aux->asn1_cb;
-    else
-        asn1_cb = 0;
 
     /*
      * Bound |len| to comfortably fit in an int. Lengths in this module often
@@ -264,7 +258,7 @@
         ef = it->funcs;
         return ef->asn1_ex_d2i(pval, in, len, it, tag, aclass, opt, ctx);
 
-    case ASN1_ITYPE_CHOICE:
+    case ASN1_ITYPE_CHOICE: {
         /*
          * It never makes sense for CHOICE types to have implicit tagging, so if
          * tag != -1, then this looks like an error in the template.
@@ -274,6 +268,8 @@
             goto err;
         }
 
+        const ASN1_AUX *aux = it->funcs;
+        ASN1_aux_cb *asn1_cb = aux != NULL ? aux->asn1_cb : NULL;
         if (asn1_cb && !asn1_cb(ASN1_OP_D2I_PRE, pval, it, NULL))
             goto auxerr;
 
@@ -327,8 +323,9 @@
             goto auxerr;
         *in = p;
         return 1;
+    }
 
-    case ASN1_ITYPE_SEQUENCE:
+    case ASN1_ITYPE_SEQUENCE: {
         p = *in;
 
         /* If no IMPLICIT tagging set to SEQUENCE, UNIVERSAL */
@@ -356,6 +353,8 @@
             goto err;
         }
 
+        const ASN1_AUX *aux = it->funcs;
+        ASN1_aux_cb *asn1_cb = aux != NULL ? aux->asn1_cb : NULL;
         if (asn1_cb && !asn1_cb(ASN1_OP_D2I_PRE, pval, it, NULL))
             goto auxerr;
 
@@ -462,6 +461,7 @@
             goto auxerr;
         *in = p;
         return 1;
+    }
 
     default:
         return 0;
diff --git a/crypto/asn1/tasn_enc.c b/crypto/asn1/tasn_enc.c
index 6dddb52..7abd34b 100644
--- a/crypto/asn1/tasn_enc.c
+++ b/crypto/asn1/tasn_enc.c
@@ -131,8 +131,6 @@
 {
     const ASN1_TEMPLATE *tt = NULL;
     int i, seqcontlen, seqlen;
-    const ASN1_AUX *aux = it->funcs;
-    ASN1_aux_cb *asn1_cb = NULL;
 
     /* All fields are pointers, except for boolean |ASN1_ITYPE_PRIMITIVE|s.
      * Optional primitives are handled later. */
@@ -144,9 +142,6 @@
         return -1;
     }
 
-    if (aux && aux->asn1_cb)
-        asn1_cb = aux->asn1_cb;
-
     switch (it->itype) {
 
     case ASN1_ITYPE_PRIMITIVE:
@@ -179,6 +174,8 @@
             OPENSSL_PUT_ERROR(ASN1, ASN1_R_BAD_TEMPLATE);
             return -1;
         }
+        const ASN1_AUX *aux = it->funcs;
+        ASN1_aux_cb *asn1_cb = aux != NULL ? aux->asn1_cb : NULL;
         if (asn1_cb && !asn1_cb(ASN1_OP_I2D_PRE, pval, it, NULL))
             return -1;
         i = asn1_get_choice_selector(pval, it);
@@ -214,7 +211,7 @@
         return ret;
     }
 
-    case ASN1_ITYPE_SEQUENCE:
+    case ASN1_ITYPE_SEQUENCE: {
         i = asn1_enc_restore(&seqcontlen, out, pval, it);
         /* An error occurred */
         if (i < 0)
@@ -231,6 +228,8 @@
             aclass = (aclass & ~ASN1_TFLG_TAG_CLASS)
                 | V_ASN1_UNIVERSAL;
         }
+        const ASN1_AUX *aux = it->funcs;
+        ASN1_aux_cb *asn1_cb = aux != NULL ? aux->asn1_cb : NULL;
         if (asn1_cb && !asn1_cb(ASN1_OP_I2D_PRE, pval, it, NULL))
             return -1;
         /* First work out sequence content length */
@@ -267,6 +266,7 @@
         if (asn1_cb && !asn1_cb(ASN1_OP_I2D_POST, pval, it, NULL))
             return -1;
         return seqlen;
+    }
 
     default:
         OPENSSL_PUT_ERROR(ASN1, ASN1_R_BAD_TEMPLATE);
diff --git a/crypto/asn1/tasn_fre.c b/crypto/asn1/tasn_fre.c
index 2f5032d..b847901 100644
--- a/crypto/asn1/tasn_fre.c
+++ b/crypto/asn1/tasn_fre.c
@@ -79,17 +79,11 @@
 {
     const ASN1_TEMPLATE *tt = NULL, *seqtt;
     const ASN1_EXTERN_FUNCS *ef;
-    const ASN1_AUX *aux = it->funcs;
-    ASN1_aux_cb *asn1_cb;
     int i;
     if (!pval)
         return;
     if ((it->itype != ASN1_ITYPE_PRIMITIVE) && !*pval)
         return;
-    if (aux && aux->asn1_cb)
-        asn1_cb = aux->asn1_cb;
-    else
-        asn1_cb = 0;
 
     switch (it->itype) {
 
@@ -104,7 +98,9 @@
         ASN1_primitive_free(pval, it);
         break;
 
-    case ASN1_ITYPE_CHOICE:
+    case ASN1_ITYPE_CHOICE: {
+        const ASN1_AUX *aux = it->funcs;
+        ASN1_aux_cb *asn1_cb = aux != NULL ? aux->asn1_cb : NULL;
         if (asn1_cb) {
             i = asn1_cb(ASN1_OP_FREE_PRE, pval, it, NULL);
             if (i == 2)
@@ -124,6 +120,7 @@
             *pval = NULL;
         }
         break;
+    }
 
     case ASN1_ITYPE_EXTERN:
         ef = it->funcs;
@@ -131,9 +128,11 @@
             ef->asn1_ex_free(pval, it);
         break;
 
-    case ASN1_ITYPE_SEQUENCE:
+    case ASN1_ITYPE_SEQUENCE: {
         if (!asn1_refcount_dec_and_test_zero(pval, it))
             return;
+        const ASN1_AUX *aux = it->funcs;
+        ASN1_aux_cb *asn1_cb = aux != NULL ? aux->asn1_cb : NULL;
         if (asn1_cb) {
             i = asn1_cb(ASN1_OP_FREE_PRE, pval, it, NULL);
             if (i == 2)
@@ -162,6 +161,7 @@
         }
         break;
     }
+    }
 }
 
 void ASN1_template_free(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt)
diff --git a/crypto/asn1/tasn_new.c b/crypto/asn1/tasn_new.c
index 346887b..eea219d 100644
--- a/crypto/asn1/tasn_new.c
+++ b/crypto/asn1/tasn_new.c
@@ -95,14 +95,8 @@
 {
     const ASN1_TEMPLATE *tt = NULL;
     const ASN1_EXTERN_FUNCS *ef;
-    const ASN1_AUX *aux = it->funcs;
-    ASN1_aux_cb *asn1_cb;
     ASN1_VALUE **pseqval;
     int i;
-    if (aux && aux->asn1_cb)
-        asn1_cb = aux->asn1_cb;
-    else
-        asn1_cb = 0;
 
     switch (it->itype) {
 
@@ -127,7 +121,9 @@
             goto memerr;
         break;
 
-    case ASN1_ITYPE_CHOICE:
+    case ASN1_ITYPE_CHOICE: {
+        const ASN1_AUX *aux = it->funcs;
+        ASN1_aux_cb *asn1_cb = aux != NULL ? aux->asn1_cb : NULL;
         if (asn1_cb) {
             i = asn1_cb(ASN1_OP_NEW_PRE, pval, it, NULL);
             if (!i)
@@ -146,8 +142,11 @@
         if (asn1_cb && !asn1_cb(ASN1_OP_NEW_POST, pval, it, NULL))
             goto auxerr2;
         break;
+    }
 
-    case ASN1_ITYPE_SEQUENCE:
+    case ASN1_ITYPE_SEQUENCE: {
+        const ASN1_AUX *aux = it->funcs;
+        ASN1_aux_cb *asn1_cb = aux != NULL ? aux->asn1_cb : NULL;
         if (asn1_cb) {
             i = asn1_cb(ASN1_OP_NEW_PRE, pval, it, NULL);
             if (!i)
@@ -173,6 +172,7 @@
             goto auxerr2;
         break;
     }
+    }
     return 1;
 
  memerr2:
diff --git a/crypto/asn1/tasn_utl.c b/crypto/asn1/tasn_utl.c
index 24ad8c3..9b1da0b 100644
--- a/crypto/asn1/tasn_utl.c
+++ b/crypto/asn1/tasn_utl.c
@@ -118,6 +118,7 @@
 }
 
 static ASN1_ENCODING *asn1_get_enc_ptr(ASN1_VALUE **pval, const ASN1_ITEM *it) {
+  assert(it->itype == ASN1_ITYPE_SEQUENCE);
   const ASN1_AUX *aux;
   if (!pval || !*pval) {
     return NULL;