From: Richard Levitte Date: Mon, 18 Nov 2019 00:54:11 +0000 (+0100) Subject: PROV SERIALIZER: add common functionality to serialize keys X-Git-Tag: openssl-3.0.0-alpha1~878 X-Git-Url: https://git.librecmc.org/?a=commitdiff_plain;h=cb58d81e68c72ab0128e0a5fc6faa007f8632acd;p=oweals%2Fopenssl.git PROV SERIALIZER: add common functionality to serialize keys To support generic output of public keys wrapped in a X509_PUBKEY, additional PEM and i2d/d2i routines are added for that type. Reviewed-by: Matt Caswell (Merged from https://github.com/openssl/openssl/pull/10394) --- diff --git a/crypto/err/openssl.txt b/crypto/err/openssl.txt index 8febc5c210..f7a8b8f7d5 100644 --- a/crypto/err/openssl.txt +++ b/crypto/err/openssl.txt @@ -2726,6 +2726,7 @@ PROV_R_NOT_SUPPORTED:136:not supported PROV_R_NOT_XOF_OR_INVALID_LENGTH:113:not xof or invalid length PROV_R_NO_KEY_SET:114:no key set PROV_R_OUTPUT_BUFFER_TOO_SMALL:106:output buffer too small +PROV_R_READ_KEY:159:read key PROV_R_TAG_NOTSET:119:tag notset PROV_R_TAG_NOT_NEEDED:120:tag not needed PROV_R_UNABLE_TO_LOAD_SHA1:143:unable to load sha1 diff --git a/crypto/pem/pem_all.c b/crypto/pem/pem_all.c index 2e8eb2e183..ba98371d46 100644 --- a/crypto/pem/pem_all.c +++ b/crypto/pem/pem_all.c @@ -34,6 +34,7 @@ IMPLEMENT_PEM_rw(X509_REQ, X509_REQ, PEM_STRING_X509_REQ, X509_REQ) IMPLEMENT_PEM_write(X509_REQ_NEW, X509_REQ, PEM_STRING_X509_REQ_OLD, X509_REQ) IMPLEMENT_PEM_rw(X509_CRL, X509_CRL, PEM_STRING_X509_CRL, X509_CRL) +IMPLEMENT_PEM_rw(X509_PUBKEY, X509_PUBKEY, PEM_STRING_PUBLIC, X509_PUBKEY) IMPLEMENT_PEM_rw(PKCS7, PKCS7, PEM_STRING_PKCS7, PKCS7) IMPLEMENT_PEM_rw(NETSCAPE_CERT_SEQUENCE, NETSCAPE_CERT_SEQUENCE, diff --git a/crypto/x509/x_all.c b/crypto/x509/x_all.c index 9517169b8b..fbdb100c00 100644 --- a/crypto/x509/x_all.c +++ b/crypto/x509/x_all.c @@ -589,6 +589,30 @@ int i2d_PKCS8_bio(BIO *bp, const X509_SIG *p8) return ASN1_i2d_bio_of(X509_SIG, i2d_X509_SIG, bp, p8); } +#ifndef OPENSSL_NO_STDIO +X509_PUBKEY *d2i_X509_PUBKEY_fp(FILE *fp, X509_PUBKEY **xpk) +{ + return ASN1_d2i_fp_of(X509_PUBKEY, X509_PUBKEY_new, d2i_X509_PUBKEY, + fp, xpk); +} + +int i2d_X509_PUBKEY_fp(FILE *fp, const X509_PUBKEY *xpk) +{ + return ASN1_i2d_fp_of(X509_PUBKEY, i2d_X509_PUBKEY, fp, xpk); +} +#endif + +X509_PUBKEY *d2i_X509_PUBKEY_bio(BIO *bp, X509_PUBKEY **xpk) +{ + return ASN1_d2i_bio_of(X509_PUBKEY, X509_PUBKEY_new, d2i_X509_PUBKEY, + bp, xpk); +} + +int i2d_X509_PUBKEY_bio(BIO *bp, const X509_PUBKEY *xpk) +{ + return ASN1_i2d_bio_of(X509_PUBKEY, i2d_X509_PUBKEY, bp, xpk); +} + #ifndef OPENSSL_NO_STDIO PKCS8_PRIV_KEY_INFO *d2i_PKCS8_PRIV_KEY_INFO_fp(FILE *fp, PKCS8_PRIV_KEY_INFO **p8inf) diff --git a/doc/man3/PEM_read_CMS.pod b/doc/man3/PEM_read_CMS.pod index 5cc3251753..58c357516e 100644 --- a/doc/man3/PEM_read_CMS.pod +++ b/doc/man3/PEM_read_CMS.pod @@ -35,7 +35,11 @@ PEM_write_bio_PKCS8_PRIV_KEY_INFO, PEM_read_SSL_SESSION, PEM_read_bio_SSL_SESSION, PEM_write_SSL_SESSION, -PEM_write_bio_SSL_SESSION +PEM_write_bio_SSL_SESSION, +PEM_read_X509_PUBKEY, +PEM_read_bio_X509_PUBKEY, +PEM_write_X509_PUBKEY, +PEM_write_bio_X509_PUBKEY - PEM object encoding routines =head1 SYNOPSIS diff --git a/doc/man3/d2i_X509.pod b/doc/man3/d2i_X509.pod index 62e6b245a7..8bb89e0332 100644 --- a/doc/man3/d2i_X509.pod +++ b/doc/man3/d2i_X509.pod @@ -184,6 +184,8 @@ d2i_X509_EXTENSIONS, d2i_X509_NAME, d2i_X509_NAME_ENTRY, d2i_X509_PUBKEY, +d2i_X509_PUBKEY_bio, +d2i_X509_PUBKEY_fp, d2i_X509_REQ, d2i_X509_REQ_INFO, d2i_X509_REQ_bio, @@ -376,6 +378,8 @@ i2d_X509_EXTENSIONS, i2d_X509_NAME, i2d_X509_NAME_ENTRY, i2d_X509_PUBKEY, +i2d_X509_PUBKEY_bio, +i2d_X509_PUBKEY_fp, i2d_X509_REQ, i2d_X509_REQ_INFO, i2d_X509_REQ_bio, diff --git a/include/openssl/pem.h b/include/openssl/pem.h index c90bec8eac..e48d247087 100644 --- a/include/openssl/pem.h +++ b/include/openssl/pem.h @@ -322,6 +322,7 @@ DECLARE_PEM_rw(X509_AUX, X509) DECLARE_PEM_rw(X509_REQ, X509_REQ) DECLARE_PEM_write(X509_REQ_NEW, X509_REQ) DECLARE_PEM_rw(X509_CRL, X509_CRL) +DECLARE_PEM_rw(X509_PUBKEY, X509_PUBKEY) DECLARE_PEM_rw(PKCS7, PKCS7) DECLARE_PEM_rw(NETSCAPE_CERT_SEQUENCE, NETSCAPE_CERT_SEQUENCE) DECLARE_PEM_rw(PKCS8, X509_SIG) diff --git a/include/openssl/x509.h b/include/openssl/x509.h index 116b30205c..e4de10e6f9 100644 --- a/include/openssl/x509.h +++ b/include/openssl/x509.h @@ -424,6 +424,8 @@ int i2d_ECPrivateKey_fp(FILE *fp, const EC_KEY *eckey); # endif X509_SIG *d2i_PKCS8_fp(FILE *fp, X509_SIG **p8); int i2d_PKCS8_fp(FILE *fp, const X509_SIG *p8); +X509_PUBKEY *d2i_X509_PUBKEY_fp(FILE *fp, X509_PUBKEY **xpk); +int i2d_X509_PUBKEY_fp(FILE *fp, const X509_PUBKEY *xpk); PKCS8_PRIV_KEY_INFO *d2i_PKCS8_PRIV_KEY_INFO_fp(FILE *fp, PKCS8_PRIV_KEY_INFO **p8inf); int i2d_PKCS8_PRIV_KEY_INFO_fp(FILE *fp, const PKCS8_PRIV_KEY_INFO *p8inf); @@ -462,6 +464,8 @@ int i2d_ECPrivateKey_bio(BIO *bp, const EC_KEY *eckey); # endif X509_SIG *d2i_PKCS8_bio(BIO *bp, X509_SIG **p8); int i2d_PKCS8_bio(BIO *bp, const X509_SIG *p8); +X509_PUBKEY *d2i_X509_PUBKEY_bio(BIO *bp, X509_PUBKEY **xpk); +int i2d_X509_PUBKEY_bio(BIO *bp, const X509_PUBKEY *xpk); PKCS8_PRIV_KEY_INFO *d2i_PKCS8_PRIV_KEY_INFO_bio(BIO *bp, PKCS8_PRIV_KEY_INFO **p8inf); int i2d_PKCS8_PRIV_KEY_INFO_bio(BIO *bp, const PKCS8_PRIV_KEY_INFO *p8inf); diff --git a/providers/common/include/prov/providercommonerr.h b/providers/common/include/prov/providercommonerr.h index 503f0270c5..5493ed5879 100644 --- a/providers/common/include/prov/providercommonerr.h +++ b/providers/common/include/prov/providercommonerr.h @@ -95,6 +95,7 @@ int ERR_load_PROV_strings(void); # define PROV_R_NOT_XOF_OR_INVALID_LENGTH 113 # define PROV_R_NO_KEY_SET 114 # define PROV_R_OUTPUT_BUFFER_TOO_SMALL 106 +# define PROV_R_READ_KEY 159 # define PROV_R_TAG_NOTSET 119 # define PROV_R_TAG_NOT_NEEDED 120 # define PROV_R_UNABLE_TO_LOAD_SHA1 143 diff --git a/providers/common/provider_err.c b/providers/common/provider_err.c index 2b7bac037d..440efe5bbf 100644 --- a/providers/common/provider_err.c +++ b/providers/common/provider_err.c @@ -77,6 +77,7 @@ static const ERR_STRING_DATA PROV_str_reasons[] = { {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_NO_KEY_SET), "no key set"}, {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_OUTPUT_BUFFER_TOO_SMALL), "output buffer too small"}, + {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_READ_KEY), "read key"}, {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_TAG_NOTSET), "tag notset"}, {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_TAG_NOT_NEEDED), "tag not needed"}, {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_UNABLE_TO_LOAD_SHA1), diff --git a/providers/implementations/build.info b/providers/implementations/build.info index a2fbf45a22..e4cab9bd2e 100644 --- a/providers/implementations/build.info +++ b/providers/implementations/build.info @@ -1 +1,2 @@ -SUBDIRS=digests ciphers macs kdfs exchange keymgmt signature asymciphers +SUBDIRS=digests ciphers macs kdfs exchange keymgmt signature asymciphers \ + serializers diff --git a/providers/implementations/serializers/build.info b/providers/implementations/serializers/build.info new file mode 100644 index 0000000000..9d063e4c32 --- /dev/null +++ b/providers/implementations/serializers/build.info @@ -0,0 +1,6 @@ +# We make separate GOAL variables for each algorithm, to make it easy to +# switch each to the Legacy provider when needed. + +$SERIALIZER_GOAL=../../libimplementations.a + +SOURCE[$SERIALIZER_GOAL]=serializer_common.c diff --git a/providers/implementations/serializers/serializer_common.c b/providers/implementations/serializers/serializer_common.c new file mode 100644 index 0000000000..6aa4e64e7a --- /dev/null +++ b/providers/implementations/serializers/serializer_common.c @@ -0,0 +1,339 @@ +/* + * Copyright 2019 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 + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include /* SIXTY_FOUR_BIT_LONG, ... */ +#include +#include /* PEM_BUFSIZE */ +#include /* PKCS8_encrypt() */ +#include +#include /* i2d_X509_PUBKEY_bio() */ +#include "crypto/bn.h" /* bn_get_words() */ +#include "prov/bio.h" /* ossl_prov_bio_printf() */ +#include "prov/implementations.h" +#include "prov/providercommonerr.h" /* PROV_R_READ_KEY */ +#include "serializer_local.h" + +static PKCS8_PRIV_KEY_INFO * +ossl_prov_p8info_from_obj(const void *obj, int obj_nid, + ASN1_STRING *params, + int params_type, + int (*k2d)(const void *obj, + unsigned char **pder)) +{ + /* der, derlen store the key DER output and its length */ + unsigned char *der = NULL; + int derlen; + /* The final PKCS#8 info */ + PKCS8_PRIV_KEY_INFO *p8info = NULL; + + + if ((p8info = PKCS8_PRIV_KEY_INFO_new()) == NULL + || (derlen = k2d(obj, &der)) <= 0 + || !PKCS8_pkey_set0(p8info, OBJ_nid2obj(obj_nid), 0, + params_type, params, der, derlen)) { + ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); + PKCS8_PRIV_KEY_INFO_free(p8info); + OPENSSL_free(der); + p8info = NULL; + } + + return p8info; +} + +static X509_SIG *ossl_prov_encp8_from_p8info(PKCS8_PRIV_KEY_INFO *p8info, + struct pkcs8_encrypt_ctx_st *ctx) +{ + X509_SIG *p8 = NULL; + char buf[PEM_BUFSIZE]; + const void *kstr = ctx->cipher_pass; + size_t klen = ctx->cipher_pass_length; + + if (ctx->cipher == NULL) + return NULL; + + if (kstr == NULL) { + if (!ctx->cb(buf, sizeof(buf), &klen, NULL, ctx->cbarg)) { + ERR_raise(ERR_LIB_PROV, PROV_R_READ_KEY); + return NULL; + } + kstr = buf; + } + /* NID == -1 means "standard" */ + p8 = PKCS8_encrypt(-1, ctx->cipher, kstr, klen, NULL, 0, 0, p8info); + if (kstr == buf) + OPENSSL_cleanse(buf, klen); + return p8; +} + +static X509_SIG *ossl_prov_encp8_from_obj(const void *obj, int obj_nid, + ASN1_STRING *params, + int params_type, + int (*k2d)(const void *obj, + unsigned char **pder), + struct pkcs8_encrypt_ctx_st *ctx) +{ + PKCS8_PRIV_KEY_INFO *p8info = + ossl_prov_p8info_from_obj(obj, obj_nid, params, params_type, k2d); + X509_SIG *p8 = ossl_prov_encp8_from_p8info(p8info, ctx); + + PKCS8_PRIV_KEY_INFO_free(p8info); + return p8; +} + +static X509_PUBKEY *ossl_prov_pubkey_from_obj(const void *obj, int obj_nid, + ASN1_STRING *params, + int params_type, + int (*k2d)(const void *obj, + unsigned char **pder)) +{ + /* der, derlen store the key DER output and its length */ + unsigned char *der = NULL; + int derlen; + /* The final X509_PUBKEY */ + X509_PUBKEY *xpk = NULL; + + + if ((xpk = X509_PUBKEY_new()) == NULL + || (derlen = k2d(obj, &der)) <= 0 + || !X509_PUBKEY_set0_param(xpk, OBJ_nid2obj(obj_nid), + params_type, params, der, derlen)) { + ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); + X509_PUBKEY_free(xpk); + OPENSSL_free(der); + xpk = NULL; + } + + return xpk; +} + +OSSL_OP_keymgmt_importkey_fn *ossl_prov_get_importkey(const OSSL_DISPATCH *fns) +{ + /* Pilfer the keymgmt dispatch table */ + for (; fns->function_id != 0; fns++) + if (fns->function_id == OSSL_FUNC_KEYMGMT_IMPORTKEY) + return OSSL_get_OP_keymgmt_importkey(fns); + + return NULL; +} + +# ifdef SIXTY_FOUR_BIT_LONG +# define BN_FMTu "%lu" +# define BN_FMTx "%lx" +# endif + +# ifdef SIXTY_FOUR_BIT +# define BN_FMTu "%llu" +# define BN_FMTx "%llx" +# endif + +# ifdef THIRTY_TWO_BIT +# define BN_FMTu "%u" +# define BN_FMTx "%x" +# endif + +int ossl_prov_print_labeled_bignum(BIO *out, const char *label, + const BIGNUM *n) +{ + const char *neg; + const char *post_label_spc = " "; + int bytes; + BN_ULONG *words; + int i, off; + + if (n == NULL) + return 0; + if (label == NULL) { + label = ""; + post_label_spc = ""; + } + + bytes = BN_num_bytes(n); + words = bn_get_words(n); + neg = BN_is_negative(n) ? "-" : ""; + + if (BN_is_zero(n)) + return ossl_prov_bio_printf(out, "%s%s0\n", label, post_label_spc); + + if (BN_num_bytes(n) <= BN_BYTES) + return ossl_prov_bio_printf(out, + "%s%s%s" BN_FMTu " (%s0x" BN_FMTx ")\n", + label, post_label_spc, neg, words[0], + neg, words[0]); + + if (neg[0] == '-') + neg = " (Negative)"; + + if (ossl_prov_bio_printf(out, "%s%s\n", label, neg) <= 0) + return 0; + + /* Skip past the zero bytes in the first word */ + for (off = 0; off < BN_BYTES; off++) { + BN_ULONG l = words[0]; + int o = 8 * (BN_BYTES - off - 1); + int b = ((l & (0xffLU << o)) >> o) & 0xff; + + if (b != 0) + break; + } + /* print 16 hex digits per line, indented with 4 spaces */ + for (i = 0; i < bytes; i += 16) { + int j, step; + + if (ossl_prov_bio_printf(out, " ") <= 0) + return 0; + + for (j = 0; i + j < bytes && j < 16; j += BN_BYTES - step) { + int k; + BN_ULONG l = words[(i + j + off) / BN_BYTES]; + + step = (i + j + off) % BN_BYTES; + + for (k = step; k < BN_BYTES; k++) { + int o = 8 * (BN_BYTES - k - 1); + int b = ((l & (0xffLU << o)) >> o) & 0xff; + + /* We may have reached the number of bytes prematurely */ + if (i + j + k - off >= bytes) + break; + + if (ossl_prov_bio_printf(out, "%02x:", b) <= 0) + return 0; + } + } + + if (ossl_prov_bio_printf(out, "\n") <= 0) + return 0; + } + + return 1; +} + +/* p2s = param to asn1_string, k2d = key to der */ +int ossl_prov_write_priv_der_from_obj(BIO *out, const void *obj, int obj_nid, + int (*p2s)(const void *obj, int nid, + ASN1_STRING **str, + int *strtype), + int (*k2d)(const void *obj, + unsigned char **pder), + struct pkcs8_encrypt_ctx_st *ctx) +{ + int ret = 0; + ASN1_STRING *str = NULL; + int strtype = 0; + + if (p2s != NULL && !p2s(obj, obj_nid, &str, &strtype)) + return 0; + + if (ctx->cipher_intent) { + X509_SIG *p8 = + ossl_prov_encp8_from_obj(obj, obj_nid, str, strtype, k2d, ctx); + + if (p8 != NULL) + ret = i2d_PKCS8_bio(out, p8); + + X509_SIG_free(p8); + } else { + PKCS8_PRIV_KEY_INFO *p8info = + ossl_prov_p8info_from_obj(obj, obj_nid, str, strtype, k2d); + + if (p8info != NULL) + ret = i2d_PKCS8_PRIV_KEY_INFO_bio(out, p8info); + + PKCS8_PRIV_KEY_INFO_free(p8info); + } + + return ret; +} + +int ossl_prov_write_priv_pem_from_obj(BIO *out, const void *obj, int obj_nid, + int (*p2s)(const void *obj, int nid, + ASN1_STRING **str, + int *strtype), + int (*k2d)(const void *obj, + unsigned char **pder), + struct pkcs8_encrypt_ctx_st *ctx) +{ + int ret = 0; + ASN1_STRING *str = NULL; + int strtype = 0; + + if (p2s != NULL && !p2s(obj, obj_nid, &str, &strtype)) + return 0; + + if (ctx->cipher_intent) { + X509_SIG *p8 = ossl_prov_encp8_from_obj(obj, obj_nid, str, strtype, + k2d, ctx); + + if (p8 != NULL) + ret = PEM_write_bio_PKCS8(out, p8); + + X509_SIG_free(p8); + } else { + PKCS8_PRIV_KEY_INFO *p8info = + ossl_prov_p8info_from_obj(obj, obj_nid, str, strtype, k2d); + + if (p8info != NULL) + ret = PEM_write_bio_PKCS8_PRIV_KEY_INFO(out, p8info); + + PKCS8_PRIV_KEY_INFO_free(p8info); + } + + return ret; +} + +int ossl_prov_write_pub_der_from_obj(BIO *out, const void *obj, int obj_nid, + int (*p2s)(const void *obj, int nid, + ASN1_STRING **str, + int *strtype), + int (*k2d)(const void *obj, + unsigned char **pder)) +{ + int ret = 0; + ASN1_STRING *str = NULL; + int strtype = 0; + X509_PUBKEY *xpk = NULL; + + if (p2s != NULL && !p2s(obj, obj_nid, &str, &strtype)) + return 0; + + xpk = ossl_prov_pubkey_from_obj(obj, obj_nid, str, strtype, k2d); + + if (xpk != NULL) + ret = i2d_X509_PUBKEY_bio(out, xpk); + + /* Also frees |str| */ + X509_PUBKEY_free(xpk); + return ret; +} + +int ossl_prov_write_pub_pem_from_obj(BIO *out, const void *obj, int obj_nid, + int (*p2s)(const void *obj, int nid, + ASN1_STRING **str, + int *strtype), + int (*k2d)(const void *obj, + unsigned char **pder)) +{ + int ret = 0; + ASN1_STRING *str = NULL; + int strtype = 0; + X509_PUBKEY *xpk = NULL; + + if (p2s != NULL && !p2s(obj, obj_nid, &str, &strtype)) + return 0; + + xpk = ossl_prov_pubkey_from_obj(obj, obj_nid, str, strtype, k2d); + + if (xpk != NULL) + ret = PEM_write_bio_X509_PUBKEY(out, xpk); + + /* Also frees |str| */ + X509_PUBKEY_free(xpk); + return ret; +} + diff --git a/providers/implementations/serializers/serializer_local.h b/providers/implementations/serializers/serializer_local.h new file mode 100644 index 0000000000..dca7a4e217 --- /dev/null +++ b/providers/implementations/serializers/serializer_local.h @@ -0,0 +1,69 @@ +/* + * Copyright 2019 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 + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include +#include +#include /* i2d_of_void */ +#include /* X509_SIG */ +#include + +struct pkcs8_encrypt_ctx_st { + /* Set to 1 if intending to encrypt/decrypt, otherwise 0 */ + int cipher_intent; + + EVP_CIPHER *cipher; + int pbe_nid; /* For future variation */ + + /* Passphrase that was passed by the caller */ + void *cipher_pass; + size_t cipher_pass_length; + + /* This callback is only used of |cipher_pass| is NULL */ + OSSL_PASSPHRASE_CALLBACK *cb; + void *cbarg; +}; + +OSSL_OP_keymgmt_importkey_fn *ossl_prov_get_importkey(const OSSL_DISPATCH *fns); + +int ossl_prov_print_labeled_bignum(BIO *out, const char *label, + const BIGNUM *n); + +enum dh_print_type { + dh_print_priv, + dh_print_pub, + dh_print_params +}; + +int ossl_prov_write_priv_der_from_obj(BIO *out, const void *obj, int obj_nid, + int (*p2s)(const void *obj, int nid, + ASN1_STRING **str, + int *strtype), + int (*k2d)(const void *obj, + unsigned char **pder), + struct pkcs8_encrypt_ctx_st *ctx); +int ossl_prov_write_priv_pem_from_obj(BIO *out, const void *obj, int obj_nid, + int (*p2s)(const void *obj, int nid, + ASN1_STRING **str, + int *strtype), + int (*k2d)(const void *obj, + unsigned char **pder), + struct pkcs8_encrypt_ctx_st *ctx); +int ossl_prov_write_pub_der_from_obj(BIO *out, const void *obj, int obj_nid, + int (*p2s)(const void *obj, int nid, + ASN1_STRING **str, + int *strtype), + int (*k2d)(const void *obj, + unsigned char **pder)); +int ossl_prov_write_pub_pem_from_obj(BIO *out, const void *obj, int obj_nid, + int (*p2s)(const void *obj, int nid, + ASN1_STRING **str, + int *strtype), + int (*k2d)(const void *obj, + unsigned char **pder)); diff --git a/util/libcrypto.num b/util/libcrypto.num index d83f675f53..28db5054af 100644 --- a/util/libcrypto.num +++ b/util/libcrypto.num @@ -4900,3 +4900,12 @@ OSSL_SERIALIZER_CTX_set_passphrase ? 3_0_0 EXIST::FUNCTION: OSSL_SERIALIZER_CTX_set_passphrase_cb ? 3_0_0 EXIST::FUNCTION: OSSL_SERIALIZER_CTX_set_passphrase_ui ? 3_0_0 EXIST::FUNCTION: ERR_load_OSSL_SERIALIZER_strings ? 3_0_0 EXIST::FUNCTION: +RSA_get0_pss_params ? 3_0_0 EXIST::FUNCTION:RSA +PEM_read_X509_PUBKEY ? 3_0_0 EXIST::FUNCTION:STDIO +PEM_write_X509_PUBKEY ? 3_0_0 EXIST::FUNCTION:STDIO +PEM_read_bio_X509_PUBKEY ? 3_0_0 EXIST::FUNCTION: +PEM_write_bio_X509_PUBKEY ? 3_0_0 EXIST::FUNCTION: +d2i_X509_PUBKEY_fp ? 3_0_0 EXIST::FUNCTION:STDIO +i2d_X509_PUBKEY_fp ? 3_0_0 EXIST::FUNCTION:STDIO +d2i_X509_PUBKEY_bio ? 3_0_0 EXIST::FUNCTION: +i2d_X509_PUBKEY_bio ? 3_0_0 EXIST::FUNCTION: