Add d2i_PUBKEY_ex_fp and d2i_PUBKEY_ex_bio.
authorslontis <shane.lontis@oracle.com>
Mon, 30 May 2022 04:32:36 +0000 (14:32 +1000)
committerTomas Mraz <tomas@openssl.org>
Wed, 2 Nov 2022 10:25:48 +0000 (11:25 +0100)
These functions pass a library content and prop query.
The i2d documentation related to these functions has been corrected since the bio and fp functions always return 0 or 1.

Reviewed-by: Hugo Landau <hlandau@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/18427)

crypto/x509/x_all.c
doc/man3/X509_PUBKEY_new.pod
include/openssl/x509.h.in
test/build.info
test/evp_extra_test2.c
util/libcrypto.num

index b7806c1ec10974f57b086042c4126f224662b2ad..075ea1ac031074e6c17d1178da414143807b5d0f 100644 (file)
@@ -705,6 +705,22 @@ int i2d_PUBKEY_fp(FILE *fp, const EVP_PKEY *pkey)
     return ASN1_i2d_fp_of(EVP_PKEY, i2d_PUBKEY, fp, pkey);
 }
 
+EVP_PKEY *d2i_PUBKEY_ex_fp(FILE *fp, EVP_PKEY **a, OSSL_LIB_CTX *libctx,
+                           const char *propq)
+{
+    BIO *b;
+    void *ret;
+
+    if ((b = BIO_new(BIO_s_file())) == NULL) {
+        ERR_raise(ERR_LIB_X509, ERR_R_BUF_LIB);
+        return NULL;
+    }
+    BIO_set_fp(b, fp, BIO_NOCLOSE);
+    ret = d2i_PUBKEY_ex_bio(b, a, libctx, propq);
+    BIO_free(b);
+    return ret;
+}
+
 EVP_PKEY *d2i_PUBKEY_fp(FILE *fp, EVP_PKEY **a)
 {
     return ASN1_d2i_fp_of(EVP_PKEY, EVP_PKEY_new, d2i_PUBKEY, fp, a);
@@ -772,6 +788,25 @@ int i2d_PUBKEY_bio(BIO *bp, const EVP_PKEY *pkey)
     return ASN1_i2d_bio_of(EVP_PKEY, i2d_PUBKEY, bp, pkey);
 }
 
+EVP_PKEY *d2i_PUBKEY_ex_bio(BIO *bp, EVP_PKEY **a, OSSL_LIB_CTX *libctx,
+                            const char *propq)
+{
+    BUF_MEM *b = NULL;
+    const unsigned char *p;
+    void *ret = NULL;
+    int len;
+
+    len = asn1_d2i_read_bio(bp, &b);
+    if (len < 0)
+        goto err;
+
+    p = (unsigned char *)b->data;
+    ret = d2i_PUBKEY_ex(a, &p, len, libctx, propq);
+ err:
+    BUF_MEM_free(b);
+    return ret;
+}
+
 EVP_PKEY *d2i_PUBKEY_bio(BIO *bp, EVP_PKEY **a)
 {
     return ASN1_d2i_bio_of(EVP_PKEY, EVP_PKEY_new, d2i_PUBKEY, bp, a);
index e92184f1a5c7782fc597c56b51f8577d36f086c7..45f9c010c1ab67be15d87bd506d669fbd463268b 100644 (file)
@@ -4,9 +4,9 @@
 
 X509_PUBKEY_new_ex, X509_PUBKEY_new, X509_PUBKEY_free, X509_PUBKEY_dup,
 X509_PUBKEY_set, X509_PUBKEY_get0, X509_PUBKEY_get,
-d2i_PUBKEY_ex, d2i_PUBKEY, i2d_PUBKEY, d2i_PUBKEY_bio, d2i_PUBKEY_fp,
-i2d_PUBKEY_fp, i2d_PUBKEY_bio, X509_PUBKEY_set0_public_key,
-X509_PUBKEY_set0_param, X509_PUBKEY_get0_param,
+d2i_PUBKEY_ex, d2i_PUBKEY, i2d_PUBKEY, d2i_PUBKEY_ex_bio, d2i_PUBKEY_bio,
+d2i_PUBKEY_ex_fp, d2i_PUBKEY_fp, i2d_PUBKEY_fp, i2d_PUBKEY_bio,
+X509_PUBKEY_set0_public_key, X509_PUBKEY_set0_param, X509_PUBKEY_get0_param,
 X509_PUBKEY_eq - SubjectPublicKeyInfo public key functions
 
 =head1 SYNOPSIS
@@ -27,7 +27,12 @@ X509_PUBKEY_eq - SubjectPublicKeyInfo public key functions
  EVP_PKEY *d2i_PUBKEY(EVP_PKEY **a, const unsigned char **pp, long length);
  int i2d_PUBKEY(const EVP_PKEY *a, unsigned char **pp);
 
+ EVP_PKEY *d2i_PUBKEY_ex_bio(BIO *bp, EVP_PKEY **a, OSSL_LIB_CTX *libctx,
+                             const char *propq);
  EVP_PKEY *d2i_PUBKEY_bio(BIO *bp, EVP_PKEY **a);
+
+ EVP_PKEY *d2i_PUBKEY_ex_fp(FILE *fp, EVP_PKEY **a, OSSL_LIB_CTX *libctx,
+                            const char *propq);
  EVP_PKEY *d2i_PUBKEY_fp(FILE *fp, EVP_PKEY **a);
 
  int i2d_PUBKEY_fp(const FILE *fp, EVP_PKEY *pkey);
@@ -88,6 +93,9 @@ d2i_PUBKEY_bio(), d2i_PUBKEY_fp(), i2d_PUBKEY_bio() and i2d_PUBKEY_fp() are
 similar to d2i_PUBKEY() and i2d_PUBKEY() except they decode or encode using a
 B<BIO> or B<FILE> pointer.
 
+d2i_PUBKEY_ex_bio() and d2i_PUBKEY_ex_fp() are similar to d2i_PUBKEY_ex() except
+they decode using a B<BIO> or B<FILE> pointer.
+
 X509_PUBKEY_set0_public_key() sets the public-key encoding of I<pub>
 to the I<penclen> bytes contained in buffer I<penc>.
 Any earlier public-key encoding in I<pub> is freed.
@@ -129,8 +137,15 @@ Otherwise they return a pointer to the newly allocated structure.
 
 X509_PUBKEY_free() does not return a value.
 
-X509_PUBKEY_get0() and X509_PUBKEY_get() return a pointer to an B<EVP_PKEY>
-structure or NULL if an error occurs.
+X509_PUBKEY_get0(), X509_PUBKEY_get(), d2i_PUBKEY_ex(), d2i_PUBKEY(),
+d2i_PUBKEY_ex_bio(), d2i_PUBKEY_bio(), d2i_PUBKEY_ex_fp() and d2i_PUBKEY_fp()
+return a pointer to an B<EVP_PKEY> structure or NULL if an error occurs.
+
+i2d_PUBKEY() returns the number of bytes successfully encoded or a
+negative value if an error occurs.
+
+i2d_PUBKEY_fp() and i2d_PUBKEY_bio() return 1 if successfully
+encoded or 0 if an error occurs.
 
 X509_PUBKEY_set0_public_key() does not return a value.
 
@@ -150,11 +165,12 @@ L<X509_get_pubkey(3)>,
 The X509_PUBKEY_new_ex() and X509_PUBKEY_eq() functions were added in OpenSSL
 3.0.
 
-X509_PUBKEY_set0_public_key() was added in OpenSSL 3.2.
+The X509_PUBKEY_set0_public_key(), d2i_PUBKEY_ex_bio() and d2i_PUBKEY_ex_fp()
+functions were added in OpenSSL 3.2.
 
 =head1 COPYRIGHT
 
-Copyright 2016-2021 The OpenSSL Project Authors. All Rights Reserved.
+Copyright 2016-2022 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
index 204938748e7c82622f6549cb50adf8f4d6c592c5..d45ce19e32752b85a0f27cd1afe17baa07a489b6 100644 (file)
@@ -412,6 +412,8 @@ EVP_PKEY *d2i_PrivateKey_ex_fp(FILE *fp, EVP_PKEY **a, OSSL_LIB_CTX *libctx,
                                const char *propq);
 EVP_PKEY *d2i_PrivateKey_fp(FILE *fp, EVP_PKEY **a);
 int i2d_PUBKEY_fp(FILE *fp, const EVP_PKEY *pkey);
+EVP_PKEY *d2i_PUBKEY_ex_fp(FILE *fp, EVP_PKEY **a, OSSL_LIB_CTX *libctx,
+                           const char *propq);
 EVP_PKEY *d2i_PUBKEY_fp(FILE *fp, EVP_PKEY **a);
 # endif
 
@@ -460,6 +462,8 @@ EVP_PKEY *d2i_PrivateKey_ex_bio(BIO *bp, EVP_PKEY **a, OSSL_LIB_CTX *libctx,
                                 const char *propq);
 EVP_PKEY *d2i_PrivateKey_bio(BIO *bp, EVP_PKEY **a);
 int i2d_PUBKEY_bio(BIO *bp, const EVP_PKEY *pkey);
+EVP_PKEY *d2i_PUBKEY_ex_bio(BIO *bp, EVP_PKEY **a, OSSL_LIB_CTX *libctx,
+                            const char *propq);
 EVP_PKEY *d2i_PUBKEY_bio(BIO *bp, EVP_PKEY **a);
 
 DECLARE_ASN1_DUP_FUNCTION(X509)
index 419b5fb12cf588eb326793db302e62a96fdca362..fd7fa953fd713e1dc6e777db2d18fbd738f1c21f 100644 (file)
@@ -184,7 +184,7 @@ IF[{- !$disabled{tests} -}]
   INCLUDE[evp_extra_test]=../include ../apps/include
   DEPEND[evp_extra_test]=../libcrypto.a libtestutil.a
 
-  SOURCE[evp_extra_test2]=evp_extra_test2.c
+  SOURCE[evp_extra_test2]=evp_extra_test2.c $INITSRC
   INCLUDE[evp_extra_test2]=../include ../apps/include
   DEPEND[evp_extra_test2]=../libcrypto libtestutil.a
 
index fc73994ca3b31c9981a83cb3f354323dfb136225..b03b6bd234c5f7929223bc9737dc08ecda5c675e 100644 (file)
@@ -359,6 +359,35 @@ static int test_dh_tofrom_data_select(void)
 #endif
 
 #ifndef OPENSSL_NO_EC
+
+static int test_ec_d2i_i2d_pubkey(void)
+{
+    int ret = 0;
+    FILE *fp = NULL;
+    EVP_PKEY *key = NULL, *outkey = NULL;
+    static const char *filename = "pubkey.der";
+
+    if (!TEST_ptr(fp = fopen(filename, "wb"))
+        || !TEST_ptr(key = EVP_PKEY_Q_keygen(mainctx, NULL, "EC", "P-256"))
+        || !TEST_true(i2d_PUBKEY_fp(fp, key))
+        || !TEST_int_eq(fclose(fp), 0))
+        goto err;
+    fp = NULL;
+
+    if (!TEST_ptr(fp = fopen(filename, "rb"))
+        || !TEST_ptr(outkey = d2i_PUBKEY_ex_fp(fp, NULL, mainctx, NULL))
+        || !TEST_int_eq(EVP_PKEY_eq(key, outkey), 1))
+        goto err;
+
+    ret = 1;
+
+err:
+    EVP_PKEY_free(outkey);
+    EVP_PKEY_free(key);
+    fclose(fp);
+    return ret;
+}
+
 static int test_ec_tofrom_data_select(void)
 {
     int ret;
@@ -1117,6 +1146,7 @@ int setup_tests(void)
     ADD_ALL_TESTS(test_d2i_PrivateKey_ex, 2);
     ADD_TEST(test_ec_tofrom_data_select);
     ADD_TEST(test_ecx_tofrom_data_select);
+    ADD_TEST(test_ec_d2i_i2d_pubkey);
 #else
     ADD_ALL_TESTS(test_d2i_PrivateKey_ex, 1);
 #endif
index 81d67b32e9530fb597057e53d369a33eea9f1b76..d9ed04ecb3a69d9e946857b5bbed5d8913af8e26 100644 (file)
@@ -5478,3 +5478,5 @@ BIO_f_brotli                            ? 3_2_0   EXIST::FUNCTION:COMP
 COMP_zstd                               ?      3_2_0   EXIST::FUNCTION:COMP
 COMP_zstd_oneshot                       ?      3_2_0   EXIST::FUNCTION:COMP
 BIO_f_zstd                              ?      3_2_0   EXIST::FUNCTION:COMP
+d2i_PUBKEY_ex_fp                        ?      3_2_0   EXIST::FUNCTION:STDIO
+d2i_PUBKEY_ex_bio                       ?      3_2_0   EXIST::FUNCTION: