Decouple crypto/evp from the OID table.

BUG=chromium:499653

Change-Id: I4e8d4af3129dbf61d4a8846ec9db685e83999d5e
Reviewed-on: https://boringssl-review.googlesource.com/7565
Reviewed-by: Steven Valdez <svaldez@google.com>
Reviewed-by: David Benjamin <davidben@google.com>
diff --git a/crypto/evp/evp_asn1.c b/crypto/evp/evp_asn1.c
index ffbb148..3681d4f 100644
--- a/crypto/evp/evp_asn1.c
+++ b/crypto/evp/evp_asn1.c
@@ -56,23 +56,50 @@
 
 #include <openssl/evp.h>
 
+#include <string.h>
+
 #include <openssl/bytestring.h>
 #include <openssl/dsa.h>
 #include <openssl/ec_key.h>
 #include <openssl/err.h>
-#include <openssl/obj.h>
 #include <openssl/rsa.h>
 
 #include "internal.h"
 
 
+static const EVP_PKEY_ASN1_METHOD *const kASN1Methods[] = {
+    &rsa_asn1_meth,
+    &ec_asn1_meth,
+    &dsa_asn1_meth,
+};
+
+static int parse_key_type(CBS *cbs, int *out_type) {
+  CBS oid;
+  if (!CBS_get_asn1(cbs, &oid, CBS_ASN1_OBJECT)) {
+    return 0;
+  }
+
+  unsigned i;
+  for (i = 0; i < sizeof(kASN1Methods)/sizeof(kASN1Methods[0]); i++) {
+    const EVP_PKEY_ASN1_METHOD *method = kASN1Methods[i];
+    if (CBS_len(&oid) == method->oid_len &&
+        memcmp(CBS_data(&oid), method->oid, method->oid_len) == 0) {
+      *out_type = method->pkey_id;
+      return 1;
+    }
+  }
+
+  return 0;
+}
+
 EVP_PKEY *EVP_parse_public_key(CBS *cbs) {
   /* Parse the SubjectPublicKeyInfo. */
-  CBS spki, algorithm, oid, key;
+  CBS spki, algorithm, key;
+  int type;
   uint8_t padding;
   if (!CBS_get_asn1(cbs, &spki, CBS_ASN1_SEQUENCE) ||
       !CBS_get_asn1(&spki, &algorithm, CBS_ASN1_SEQUENCE) ||
-      !CBS_get_asn1(&algorithm, &oid, CBS_ASN1_OBJECT) ||
+      !parse_key_type(&algorithm, &type) ||
       !CBS_get_asn1(&spki, &key, CBS_ASN1_BITSTRING) ||
       CBS_len(&spki) != 0 ||
       /* Every key type defined encodes the key as a byte string with the same
@@ -86,7 +113,7 @@
   /* Set up an |EVP_PKEY| of the appropriate type. */
   EVP_PKEY *ret = EVP_PKEY_new();
   if (ret == NULL ||
-      !EVP_PKEY_set_type(ret, OBJ_cbs2nid(&oid))) {
+      !EVP_PKEY_set_type(ret, type)) {
     goto err;
   }
 
@@ -117,13 +144,14 @@
 
 EVP_PKEY *EVP_parse_private_key(CBS *cbs) {
   /* Parse the PrivateKeyInfo. */
-  CBS pkcs8, algorithm, oid, key;
+  CBS pkcs8, algorithm, key;
   uint64_t version;
+  int type;
   if (!CBS_get_asn1(cbs, &pkcs8, CBS_ASN1_SEQUENCE) ||
       !CBS_get_asn1_uint64(&pkcs8, &version) ||
       version != 0 ||
       !CBS_get_asn1(&pkcs8, &algorithm, CBS_ASN1_SEQUENCE) ||
-      !CBS_get_asn1(&algorithm, &oid, CBS_ASN1_OBJECT) ||
+      !parse_key_type(&algorithm, &type) ||
       !CBS_get_asn1(&pkcs8, &key, CBS_ASN1_OCTETSTRING)) {
     OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR);
     return NULL;
@@ -134,7 +162,7 @@
   /* Set up an |EVP_PKEY| of the appropriate type. */
   EVP_PKEY *ret = EVP_PKEY_new();
   if (ret == NULL ||
-      !EVP_PKEY_set_type(ret, OBJ_cbs2nid(&oid))) {
+      !EVP_PKEY_set_type(ret, type)) {
     goto err;
   }
 
diff --git a/crypto/evp/internal.h b/crypto/evp/internal.h
index d509539..0783143 100644
--- a/crypto/evp/internal.h
+++ b/crypto/evp/internal.h
@@ -68,6 +68,8 @@
 
 struct evp_pkey_asn1_method_st {
   int pkey_id;
+  uint8_t oid[9];
+  uint8_t oid_len;
 
   /* pub_decode decodes |params| and |key| as a SubjectPublicKeyInfo
    * and writes the result into |out|. It returns one on success and zero on
diff --git a/crypto/evp/p_dsa_asn1.c b/crypto/evp/p_dsa_asn1.c
index f6d625e..1f022f1 100644
--- a/crypto/evp/p_dsa_asn1.c
+++ b/crypto/evp/p_dsa_asn1.c
@@ -60,7 +60,6 @@
 #include <openssl/bytestring.h>
 #include <openssl/dsa.h>
 #include <openssl/err.h>
-#include <openssl/obj.h>
 
 #include "internal.h"
 
@@ -107,10 +106,11 @@
   const int has_params = dsa->p != NULL && dsa->q != NULL && dsa->g != NULL;
 
   /* See RFC 5480, section 2. */
-  CBB spki, algorithm, key_bitstring;
+  CBB spki, algorithm, oid, key_bitstring;
   if (!CBB_add_asn1(out, &spki, CBS_ASN1_SEQUENCE) ||
       !CBB_add_asn1(&spki, &algorithm, CBS_ASN1_SEQUENCE) ||
-      !OBJ_nid2cbb(&algorithm, NID_dsa) ||
+      !CBB_add_asn1(&algorithm, &oid, CBS_ASN1_OBJECT) ||
+      !CBB_add_bytes(&oid, dsa_asn1_meth.oid, dsa_asn1_meth.oid_len) ||
       (has_params &&
        !DSA_marshal_parameters(&algorithm, dsa)) ||
       !CBB_add_asn1(&spki, &key_bitstring, CBS_ASN1_BITSTRING) ||
@@ -173,11 +173,12 @@
   }
 
   /* See PKCS#11, v2.40, section 2.5. */
-  CBB pkcs8, algorithm, private_key;
+  CBB pkcs8, algorithm, oid, private_key;
   if (!CBB_add_asn1(out, &pkcs8, CBS_ASN1_SEQUENCE) ||
       !CBB_add_asn1_uint64(&pkcs8, 0 /* version */) ||
       !CBB_add_asn1(&pkcs8, &algorithm, CBS_ASN1_SEQUENCE) ||
-      !OBJ_nid2cbb(&algorithm, NID_dsa) ||
+      !CBB_add_asn1(&algorithm, &oid, CBS_ASN1_OBJECT) ||
+      !CBB_add_bytes(&oid, dsa_asn1_meth.oid, dsa_asn1_meth.oid_len) ||
       !DSA_marshal_parameters(&algorithm, dsa) ||
       !CBB_add_asn1(&pkcs8, &private_key, CBS_ASN1_OCTETSTRING) ||
       !BN_marshal_asn1(&private_key, dsa->priv_key) ||
@@ -243,6 +244,8 @@
 
 const EVP_PKEY_ASN1_METHOD dsa_asn1_meth = {
   EVP_PKEY_DSA,
+  /* 1.2.840.10040.4.1 */
+  {0x2a, 0x86, 0x48, 0xce, 0x38, 0x04, 0x01}, 7,
 
   dsa_pub_decode,
   dsa_pub_encode,
diff --git a/crypto/evp/p_ec_asn1.c b/crypto/evp/p_ec_asn1.c
index d81e54d..b723ad7 100644
--- a/crypto/evp/p_ec_asn1.c
+++ b/crypto/evp/p_ec_asn1.c
@@ -61,7 +61,6 @@
 #include <openssl/ec_key.h>
 #include <openssl/ecdsa.h>
 #include <openssl/err.h>
-#include <openssl/obj.h>
 
 #include "internal.h"
 
@@ -72,10 +71,11 @@
   const EC_POINT *public_key = EC_KEY_get0_public_key(ec_key);
 
   /* See RFC 5480, section 2. */
-  CBB spki, algorithm, key_bitstring;
+  CBB spki, algorithm, oid, key_bitstring;
   if (!CBB_add_asn1(out, &spki, CBS_ASN1_SEQUENCE) ||
       !CBB_add_asn1(&spki, &algorithm, CBS_ASN1_SEQUENCE) ||
-      !OBJ_nid2cbb(&algorithm, NID_X9_62_id_ecPublicKey) ||
+      !CBB_add_asn1(&algorithm, &oid, CBS_ASN1_OBJECT) ||
+      !CBB_add_bytes(&oid, ec_asn1_meth.oid, ec_asn1_meth.oid_len) ||
       !EC_KEY_marshal_curve_name(&algorithm, group) ||
       !CBB_add_asn1(&spki, &key_bitstring, CBS_ASN1_BITSTRING) ||
       !CBB_add_u8(&key_bitstring, 0 /* padding */) ||
@@ -170,11 +170,12 @@
   unsigned enc_flags = EC_KEY_get_enc_flags(ec_key) | EC_PKEY_NO_PARAMETERS;
 
   /* See RFC 5915. */
-  CBB pkcs8, algorithm, private_key;
+  CBB pkcs8, algorithm, oid, private_key;
   if (!CBB_add_asn1(out, &pkcs8, CBS_ASN1_SEQUENCE) ||
       !CBB_add_asn1_uint64(&pkcs8, 0 /* version */) ||
       !CBB_add_asn1(&pkcs8, &algorithm, CBS_ASN1_SEQUENCE) ||
-      !OBJ_nid2cbb(&algorithm, NID_X9_62_id_ecPublicKey) ||
+      !CBB_add_asn1(&algorithm, &oid, CBS_ASN1_OBJECT) ||
+      !CBB_add_bytes(&oid, ec_asn1_meth.oid, ec_asn1_meth.oid_len) ||
       !EC_KEY_marshal_curve_name(&algorithm, EC_KEY_get0_group(ec_key)) ||
       !CBB_add_asn1(&pkcs8, &private_key, CBS_ASN1_OCTETSTRING) ||
       !EC_KEY_marshal_private_key(&private_key, ec_key, enc_flags) ||
@@ -231,6 +232,8 @@
 
 const EVP_PKEY_ASN1_METHOD ec_asn1_meth = {
   EVP_PKEY_EC,
+  /* 1.2.840.10045.2.1 */
+  {0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01}, 7,
 
   eckey_pub_decode,
   eckey_pub_encode,
diff --git a/crypto/evp/p_rsa_asn1.c b/crypto/evp/p_rsa_asn1.c
index 3a00241..2c4b266 100644
--- a/crypto/evp/p_rsa_asn1.c
+++ b/crypto/evp/p_rsa_asn1.c
@@ -60,7 +60,6 @@
 #include <openssl/digest.h>
 #include <openssl/err.h>
 #include <openssl/mem.h>
-#include <openssl/obj.h>
 #include <openssl/rsa.h>
 
 #include "../rsa/internal.h"
@@ -69,10 +68,11 @@
 
 static int rsa_pub_encode(CBB *out, const EVP_PKEY *key) {
   /* See RFC 3279, section 2.3.1. */
-  CBB spki, algorithm, null, key_bitstring;
+  CBB spki, algorithm, oid, null, key_bitstring;
   if (!CBB_add_asn1(out, &spki, CBS_ASN1_SEQUENCE) ||
       !CBB_add_asn1(&spki, &algorithm, CBS_ASN1_SEQUENCE) ||
-      !OBJ_nid2cbb(&algorithm, NID_rsaEncryption) ||
+      !CBB_add_asn1(&algorithm, &oid, CBS_ASN1_OBJECT) ||
+      !CBB_add_bytes(&oid, rsa_asn1_meth.oid, rsa_asn1_meth.oid_len) ||
       !CBB_add_asn1(&algorithm, &null, CBS_ASN1_NULL) ||
       !CBB_add_asn1(&spki, &key_bitstring, CBS_ASN1_BITSTRING) ||
       !CBB_add_u8(&key_bitstring, 0 /* padding */) ||
@@ -120,11 +120,12 @@
 }
 
 static int rsa_priv_encode(CBB *out, const EVP_PKEY *key) {
-  CBB pkcs8, algorithm, null, private_key;
+  CBB pkcs8, algorithm, oid, null, private_key;
   if (!CBB_add_asn1(out, &pkcs8, CBS_ASN1_SEQUENCE) ||
       !CBB_add_asn1_uint64(&pkcs8, 0 /* version */) ||
       !CBB_add_asn1(&pkcs8, &algorithm, CBS_ASN1_SEQUENCE) ||
-      !OBJ_nid2cbb(&algorithm, NID_rsaEncryption) ||
+      !CBB_add_asn1(&algorithm, &oid, CBS_ASN1_OBJECT) ||
+      !CBB_add_bytes(&oid, rsa_asn1_meth.oid, rsa_asn1_meth.oid_len) ||
       !CBB_add_asn1(&algorithm, &null, CBS_ASN1_NULL) ||
       !CBB_add_asn1(&pkcs8, &private_key, CBS_ASN1_OCTETSTRING) ||
       !RSA_marshal_private_key(&private_key, key->pkey.rsa) ||
@@ -177,6 +178,8 @@
 
 const EVP_PKEY_ASN1_METHOD rsa_asn1_meth = {
   EVP_PKEY_RSA,
+  /* 1.2.840.113549.1.1.1 */
+  {0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01}, 9,
 
   rsa_pub_decode,
   rsa_pub_encode,