CORE: pre-populate the namemap with legacy OIDs too
[openssl.git] / providers / implementations / storemgmt / file_store_der2obj.c
index c7388a9..94bc467 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2020 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2020-2021 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the Apache License 2.0 (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
@@ -27,6 +27,8 @@
 #include <openssl/core_object.h>
 #include <openssl/bio.h>
 #include <openssl/buffer.h>
+#include <openssl/err.h>
+#include <openssl/asn1err.h>
 #include <openssl/params.h>
 #include "internal/asn1.h"
 #include "prov/bio.h"
@@ -34,7 +36,7 @@
 
 /*
  * newctx and freectx are not strictly necessary.  However, the method creator,
- * ossl_decoder_from_dispatch(), demands that they exist, so we make sure to
+ * ossl_decoder_from_algorithm(), demands that they exist, so we make sure to
  * oblige.
  */
 
@@ -75,7 +77,7 @@ static int der2obj_get_params(OSSL_PARAM params[])
     return 1;
 }
 
-static int der2obj_decode(void *provctx, OSSL_CORE_BIO *cin,
+static int der2obj_decode(void *provctx, OSSL_CORE_BIO *cin, int selection,
                           OSSL_CALLBACK *data_cb, void *data_cbarg,
                           OSSL_PASSPHRASE_CALLBACK *pw_cb, void *pw_cbarg)
 {
@@ -83,10 +85,28 @@ static int der2obj_decode(void *provctx, OSSL_CORE_BIO *cin,
      * We're called from file_store.c, so we know that OSSL_CORE_BIO is a
      * BIO in this case.
      */
-    BIO *in = (BIO *)cin;
+    BIO *in = ossl_bio_new_from_core_bio(provctx, cin);
     BUF_MEM *mem = NULL;
-    int ok = (asn1_d2i_read_bio(in, &mem) >= 0);
+    int err, ok;
 
+    if (in == NULL)
+        return 0;
+
+    ERR_set_mark();
+    ok = (asn1_d2i_read_bio(in, &mem) >= 0);
+    /*
+     * Prune low-level ASN.1 parse errors from error queue, assuming that
+     * this is called by decoder_process() in a loop trying several formats.
+     */
+    err = ERR_peek_last_error();
+    if (ERR_GET_LIB(err) == ERR_LIB_ASN1
+            && (ERR_GET_REASON(err) == ASN1_R_HEADER_TOO_LONG
+                || ERR_GET_REASON(err) == ASN1_R_UNSUPPORTED_TYPE
+                || ERR_GET_REASON(err) == ERR_R_NESTED_ASN1_ERROR
+                || ERR_GET_REASON(err) == ASN1_R_NOT_ENOUGH_DATA))
+        ERR_pop_to_mark();
+    else
+        ERR_clear_last_mark();
     if (ok) {
         OSSL_PARAM params[3];
         int object_type = OSSL_OBJECT_UNKNOWN;
@@ -102,6 +122,7 @@ static int der2obj_decode(void *provctx, OSSL_CORE_BIO *cin,
         OPENSSL_free(mem->data);
         OPENSSL_free(mem);
     }
+    BIO_free(in);
     return ok;
 }
 
@@ -115,5 +136,5 @@ static const OSSL_DISPATCH der_to_obj_decoder_functions[] = {
     { 0, NULL }
 };
 
-const OSSL_ALGORITHM der_to_obj_algorithm =
+const OSSL_ALGORITHM ossl_der_to_obj_algorithm =
     { "obj", NULL, der_to_obj_decoder_functions };