From 35f6e7ea02b599d5aaf220b4720cbadd946d8023 Mon Sep 17 00:00:00 2001 From: Viktor Dukhovni Date: Mon, 20 Jan 2025 02:51:07 +1100 Subject: [PATCH] Make the provider context available to encoders MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit At the moment the provider context is only available to encoders that encrypt, but it is useful more generally. A similar change has already been merged to "master" on the decoder side, this is the mirror change for encoders. The only significant difference is that PEM_ASN1_write_bio needed to be "extended" (cloned) to allow it to pass the provider context down to the `k2d` function it uses to encode the data. I had to "hold my nose" and live with the random "20" added to the data size in order to accomodate encryption with padding, which may produce one more cipher block than the input length. This really should ask the EVP layer about the block length of the cipher, and allocate the right amount. This should be a separate fix for both the old PEM_ASN1_write_bio() and the new PEM_ASN1_write_bio_ctx(). Reviewed-by: Tim Hudson Reviewed-by: Shane Lontis (Merged from https://github.com/openssl/openssl/pull/26475) --- crypto/pem/pem_lib.c | 37 +++- doc/man3/PEM_read.pod | 43 +++-- include/openssl/asn1.h.in | 1 + include/openssl/pem.h | 4 + .../encode_decode/encode_key2any.c | 158 +++++++++++------- util/libcrypto.num | 1 + util/missingcrypto.txt | 1 + 7 files changed, 166 insertions(+), 79 deletions(-) diff --git a/crypto/pem/pem_lib.c b/crypto/pem/pem_lib.c index 9d8ad35ad3..5eff44dbbb 100644 --- a/crypto/pem/pem_lib.c +++ b/crypto/pem/pem_lib.c @@ -316,10 +316,11 @@ int PEM_ASN1_write(i2d_of_void *i2d, const char *name, FILE *fp, } #endif -int PEM_ASN1_write_bio(i2d_of_void *i2d, const char *name, BIO *bp, - const void *x, const EVP_CIPHER *enc, - const unsigned char *kstr, int klen, - pem_password_cb *callback, void *u) +static int +PEM_ASN1_write_bio_internal( + i2d_of_void *i2d, OSSL_i2d_of_void_ctx *i2d_ctx, void *vctx, + const char *name, BIO *bp, const void *x, const EVP_CIPHER *enc, + const unsigned char *kstr, int klen, pem_password_cb *callback, void *u) { EVP_CIPHER_CTX *ctx = NULL; int dsize = 0, i = 0, j = 0, ret = 0; @@ -344,7 +345,13 @@ int PEM_ASN1_write_bio(i2d_of_void *i2d, const char *name, BIO *bp, } } - if ((dsize = i2d(x, NULL)) <= 0) { + if (i2d == NULL && i2d_ctx == NULL) { + ERR_raise(ERR_LIB_CRYPTO, CRYPTO_R_INVALID_NULL_ARGUMENT); + dsize = 0; + goto err; + } + dsize = i2d != NULL ? i2d(x, NULL) : i2d_ctx(x, NULL, vctx); + if (dsize <= 0) { ERR_raise(ERR_LIB_PEM, ERR_R_ASN1_LIB); dsize = 0; goto err; @@ -355,7 +362,7 @@ int PEM_ASN1_write_bio(i2d_of_void *i2d, const char *name, BIO *bp, if (data == NULL) goto err; p = data; - i = i2d(x, &p); + i = i2d != NULL ? i2d(x, &p) : i2d_ctx(x, &p, vctx); if (enc != NULL) { if (kstr == NULL) { @@ -416,6 +423,24 @@ int PEM_ASN1_write_bio(i2d_of_void *i2d, const char *name, BIO *bp, return ret; } +int +PEM_ASN1_write_bio(i2d_of_void *i2d, const char *name, BIO *bp, const void *x, + const EVP_CIPHER *enc, const unsigned char *kstr, int klen, + pem_password_cb *callback, void *u) +{ + return PEM_ASN1_write_bio_internal(i2d, NULL, NULL, name, bp, x, enc, + kstr, klen, callback, u); +} + +int PEM_ASN1_write_bio_ctx(OSSL_i2d_of_void_ctx *i2d, void *vctx, + const char *name, BIO *bp, const void *x, + const EVP_CIPHER *enc, const unsigned char *kstr, + int klen, pem_password_cb *callback, void *u) +{ + return PEM_ASN1_write_bio_internal(NULL, i2d, vctx, name, bp, x, enc, + kstr, klen, callback, u); +} + int PEM_do_header(EVP_CIPHER_INFO *cipher, unsigned char *data, long *plen, pem_password_cb *callback, void *u) { diff --git a/doc/man3/PEM_read.pod b/doc/man3/PEM_read.pod index c76039f711..3a46af2300 100644 --- a/doc/man3/PEM_read.pod +++ b/doc/man3/PEM_read.pod @@ -2,19 +2,14 @@ =head1 NAME -PEM_write, PEM_write_bio, -PEM_read, PEM_read_bio, PEM_do_header, PEM_get_EVP_CIPHER_INFO +PEM_read, PEM_read_bio, PEM_do_header, PEM_get_EVP_CIPHER_INFO, PEM_write, +PEM_write_bio, PEM_ASN1_write, PEM_ASN1_write_bio, PEM_ASN1_write_bio_ctx - PEM encoding routines =head1 SYNOPSIS #include - int PEM_write(FILE *fp, const char *name, const char *header, - const unsigned char *data, long len); - int PEM_write_bio(BIO *bp, const char *name, const char *header, - const unsigned char *data, long len); - int PEM_read(FILE *fp, char **name, char **header, unsigned char **data, long *len); int PEM_read_bio(BIO *bp, char **name, char **header, @@ -24,6 +19,23 @@ PEM_read, PEM_read_bio, PEM_do_header, PEM_get_EVP_CIPHER_INFO int PEM_do_header(EVP_CIPHER_INFO *cinfo, unsigned char *data, long *len, pem_password_cb *cb, void *u); + int PEM_write(FILE *fp, const char *name, const char *header, + const unsigned char *data, long len); + int PEM_write_bio(BIO *bp, const char *name, const char *header, + const unsigned char *data, long len); + int PEM_ASN1_write(i2d_of_void *i2d, const char *name, FILE *fp, + const void *x, const EVP_CIPHER *enc, + const unsigned char *kstr, int klen, + pem_password_cb *callback, void *u); + int PEM_ASN1_write_bio(i2d_of_void *i2d, const char *name, BIO *bp, + const void *x, const EVP_CIPHER *enc, + const unsigned char *kstr, int klen, + pem_password_cb *callback, void *u); + int PEM_ASN1_write_bio_ctx(OSSL_i2d_of_void_ctx *i2d, void *vctx, + const char *name, BIO *bp, const void *x, + const EVP_CIPHER *enc, const unsigned char *kstr, + int klen, pem_password_cb *callback, void *u); + =head1 DESCRIPTION These functions read and write PEM-encoded objects, using the PEM @@ -89,9 +101,9 @@ nor PEM_get_EVP_CIPHER_INFO() need be called. =head1 RETURN VALUES -PEM_read() and PEM_read_bio() return 1 on success and 0 on failure, the latter -includes the case when no more PEM objects remain in the input file. -To distinguish end of file from more serious errors the caller must peek at the +PEM_read(), and PEM_read_bio() return 1 on success and 0 on failure, the latter +includes the case when no more PEM objects remain in the input file. To +distinguish end of file from more serious errors the caller must peek at the error stack and check for B, which indicates that no more PEM objects were found. See L, L. @@ -114,12 +126,23 @@ PEM_do_header() makes no assumption regarding the pass phrase received from the password callback. It will simply be treated as a byte sequence. +PEM_write() and PEM_write_bio() return the number of encoded bytes (not +counting the PEM header and end marker) written on success or 0 on failure. + +PEM_ASN1_write_bio(), and PEM_ASN1_write_bio_ctx() return 1 on success and 0 on +failure. The latter function passes an additional application-provided context +value to the B function that serialises the input ASN.1 object. + =head1 SEE ALSO L, L, L, L +=head1 HISTORY + +The PEM_ASN1_write_bio_ctx() function was added in OpenSSL 3.5. + =head1 COPYRIGHT Copyright 1998-2020 The OpenSSL Project Authors. All Rights Reserved. diff --git a/include/openssl/asn1.h.in b/include/openssl/asn1.h.in index 862ec740a9..b8c4989862 100644 --- a/include/openssl/asn1.h.in +++ b/include/openssl/asn1.h.in @@ -324,6 +324,7 @@ typedef struct ASN1_VALUE_st ASN1_VALUE; typedef void *d2i_of_void(void **, const unsigned char **, long); typedef int i2d_of_void(const void *, unsigned char **); +typedef int OSSL_i2d_of_void_ctx(const void *, unsigned char **, void *vctx); /*- * The following macros and typedefs allow an ASN1_ITEM diff --git a/include/openssl/pem.h b/include/openssl/pem.h index 6b7b66a2be..92da0aa357 100644 --- a/include/openssl/pem.h +++ b/include/openssl/pem.h @@ -396,6 +396,10 @@ int PEM_ASN1_write_bio(i2d_of_void *i2d, const char *name, BIO *bp, const void *x, const EVP_CIPHER *enc, const unsigned char *kstr, int klen, pem_password_cb *cb, void *u); +int PEM_ASN1_write_bio_ctx(OSSL_i2d_of_void_ctx *i2d, void *vctx, + const char *name, BIO *bp, const void *x, + const EVP_CIPHER *enc, const unsigned char *kstr, + int klen, pem_password_cb *cb, void *u); STACK_OF(X509_INFO) *PEM_X509_INFO_read_bio(BIO *bp, STACK_OF(X509_INFO) *sk, pem_password_cb *cb, void *u); diff --git a/providers/implementations/encode_decode/encode_key2any.c b/providers/implementations/encode_decode/encode_key2any.c index e77cb22e8c..42336ce781 100644 --- a/providers/implementations/encode_decode/encode_key2any.c +++ b/providers/implementations/encode_decode/encode_key2any.c @@ -40,7 +40,7 @@ # define OPENSSL_NO_KEYPARAMS #endif -struct key2any_ctx_st { +typedef struct key2any_ctx_st { PROV_CTX *provctx; /* Set to 0 if parameters should not be saved (dsa only) */ @@ -52,15 +52,15 @@ struct key2any_ctx_st { EVP_CIPHER *cipher; struct ossl_passphrase_data_st pwdata; -}; +} KEY2ANY_CTX; typedef int check_key_type_fn(const void *key, int nid); typedef int key_to_paramstring_fn(const void *key, int nid, int save, void **str, int *strtype); typedef int key_to_der_fn(BIO *out, const void *key, int key_nid, const char *pemname, - key_to_paramstring_fn *p2s, i2d_of_void *k2d, - struct key2any_ctx_st *ctx); + key_to_paramstring_fn *p2s, + OSSL_i2d_of_void_ctx *k2d, KEY2ANY_CTX *ctx); typedef int write_bio_of_void_fn(BIO *bp, const void *x); @@ -79,7 +79,8 @@ static void free_asn1_data(int type, void *data) static PKCS8_PRIV_KEY_INFO *key_to_p8info(const void *key, int key_nid, void *params, int params_type, - i2d_of_void *k2d) + OSSL_i2d_of_void_ctx *k2d, + KEY2ANY_CTX *ctx) { /* der, derlen store the key DER output and its length */ unsigned char *der = NULL; @@ -88,7 +89,7 @@ static PKCS8_PRIV_KEY_INFO *key_to_p8info(const void *key, int key_nid, PKCS8_PRIV_KEY_INFO *p8info = NULL; if ((p8info = PKCS8_PRIV_KEY_INFO_new()) == NULL - || (derlen = k2d(key, &der)) <= 0 + || (derlen = k2d(key, &der, (void *)ctx)) <= 0 || !PKCS8_pkey_set0(p8info, OBJ_nid2obj(key_nid), 0, params_type, params, der, derlen)) { ERR_raise(ERR_LIB_PROV, ERR_R_ASN1_LIB); @@ -101,7 +102,7 @@ static PKCS8_PRIV_KEY_INFO *key_to_p8info(const void *key, int key_nid, } static X509_SIG *p8info_to_encp8(PKCS8_PRIV_KEY_INFO *p8info, - struct key2any_ctx_st *ctx) + KEY2ANY_CTX *ctx) { X509_SIG *p8 = NULL; char kstr[PEM_BUFSIZE]; @@ -124,10 +125,11 @@ static X509_SIG *p8info_to_encp8(PKCS8_PRIV_KEY_INFO *p8info, static X509_SIG *key_to_encp8(const void *key, int key_nid, void *params, int params_type, - i2d_of_void *k2d, struct key2any_ctx_st *ctx) + OSSL_i2d_of_void_ctx *k2d, + KEY2ANY_CTX *ctx) { PKCS8_PRIV_KEY_INFO *p8info = - key_to_p8info(key, key_nid, params, params_type, k2d); + key_to_p8info(key, key_nid, params, params_type, k2d, ctx); X509_SIG *p8 = NULL; if (p8info == NULL) { @@ -141,7 +143,8 @@ static X509_SIG *key_to_encp8(const void *key, int key_nid, static X509_PUBKEY *key_to_pubkey(const void *key, int key_nid, void *params, int params_type, - i2d_of_void k2d) + OSSL_i2d_of_void_ctx *k2d, + KEY2ANY_CTX *ctx) { /* der, derlen store the key DER output and its length */ unsigned char *der = NULL; @@ -151,7 +154,7 @@ static X509_PUBKEY *key_to_pubkey(const void *key, int key_nid, if ((xpk = X509_PUBKEY_new()) == NULL - || (derlen = k2d(key, &der)) <= 0 + || (derlen = k2d(key, &der, (void *)ctx)) <= 0 || !X509_PUBKEY_set0_param(xpk, OBJ_nid2obj(key_nid), params_type, params, der, derlen)) { ERR_raise(ERR_LIB_PROV, ERR_R_X509_LIB); @@ -186,8 +189,8 @@ static int key_to_epki_der_priv_bio(BIO *out, const void *key, int key_nid, ossl_unused const char *pemname, key_to_paramstring_fn *p2s, - i2d_of_void *k2d, - struct key2any_ctx_st *ctx) + OSSL_i2d_of_void_ctx *k2d, + KEY2ANY_CTX *ctx) { int ret = 0; void *str = NULL; @@ -214,8 +217,8 @@ static int key_to_epki_pem_priv_bio(BIO *out, const void *key, int key_nid, ossl_unused const char *pemname, key_to_paramstring_fn *p2s, - i2d_of_void *k2d, - struct key2any_ctx_st *ctx) + OSSL_i2d_of_void_ctx *k2d, + KEY2ANY_CTX *ctx) { int ret = 0; void *str = NULL; @@ -242,8 +245,8 @@ static int key_to_pki_der_priv_bio(BIO *out, const void *key, int key_nid, ossl_unused const char *pemname, key_to_paramstring_fn *p2s, - i2d_of_void *k2d, - struct key2any_ctx_st *ctx) + OSSL_i2d_of_void_ctx *k2d, + KEY2ANY_CTX *ctx) { int ret = 0; void *str = NULL; @@ -258,7 +261,7 @@ static int key_to_pki_der_priv_bio(BIO *out, const void *key, &str, &strtype)) return 0; - p8info = key_to_p8info(key, key_nid, str, strtype, k2d); + p8info = key_to_p8info(key, key_nid, str, strtype, k2d, ctx); if (p8info != NULL) ret = i2d_PKCS8_PRIV_KEY_INFO_bio(out, p8info); @@ -274,8 +277,8 @@ static int key_to_pki_pem_priv_bio(BIO *out, const void *key, int key_nid, ossl_unused const char *pemname, key_to_paramstring_fn *p2s, - i2d_of_void *k2d, - struct key2any_ctx_st *ctx) + OSSL_i2d_of_void_ctx *k2d, + KEY2ANY_CTX *ctx) { int ret = 0; void *str = NULL; @@ -290,7 +293,7 @@ static int key_to_pki_pem_priv_bio(BIO *out, const void *key, &str, &strtype)) return 0; - p8info = key_to_p8info(key, key_nid, str, strtype, k2d); + p8info = key_to_p8info(key, key_nid, str, strtype, k2d, ctx); if (p8info != NULL) ret = PEM_write_bio_PKCS8_PRIV_KEY_INFO(out, p8info); @@ -306,8 +309,8 @@ static int key_to_spki_der_pub_bio(BIO *out, const void *key, int key_nid, ossl_unused const char *pemname, key_to_paramstring_fn *p2s, - i2d_of_void *k2d, - struct key2any_ctx_st *ctx) + OSSL_i2d_of_void_ctx *k2d, + KEY2ANY_CTX *ctx) { int ret = 0; void *str = NULL; @@ -318,7 +321,7 @@ static int key_to_spki_der_pub_bio(BIO *out, const void *key, &str, &strtype)) return 0; - xpk = key_to_pubkey(key, key_nid, str, strtype, k2d); + xpk = key_to_pubkey(key, key_nid, str, strtype, k2d, ctx); if (xpk != NULL) ret = i2d_X509_PUBKEY_bio(out, xpk); @@ -332,8 +335,8 @@ static int key_to_spki_pem_pub_bio(BIO *out, const void *key, int key_nid, ossl_unused const char *pemname, key_to_paramstring_fn *p2s, - i2d_of_void *k2d, - struct key2any_ctx_st *ctx) + OSSL_i2d_of_void_ctx *k2d, + KEY2ANY_CTX *ctx) { int ret = 0; void *str = NULL; @@ -344,7 +347,7 @@ static int key_to_spki_pem_pub_bio(BIO *out, const void *key, &str, &strtype)) return 0; - xpk = key_to_pubkey(key, key_nid, str, strtype, k2d); + xpk = key_to_pubkey(key, key_nid, str, strtype, k2d, ctx); if (xpk != NULL) ret = PEM_write_bio_X509_PUBKEY(out, xpk); @@ -372,14 +375,14 @@ static int key_to_type_specific_der_bio(BIO *out, const void *key, int key_nid, ossl_unused const char *pemname, key_to_paramstring_fn *p2s, - i2d_of_void *k2d, - struct key2any_ctx_st *ctx) + OSSL_i2d_of_void_ctx *k2d, + KEY2ANY_CTX *ctx) { unsigned char *der = NULL; int derlen; int ret; - if ((derlen = k2d(key, &der)) <= 0) { + if ((derlen = k2d(key, &der, (void *)ctx)) <= 0) { ERR_raise(ERR_LIB_PROV, ERR_R_PROV_LIB); return 0; } @@ -395,20 +398,19 @@ static int key_to_type_specific_der_bio(BIO *out, const void *key, static int key_to_type_specific_pem_bio_cb(BIO *out, const void *key, int key_nid, const char *pemname, key_to_paramstring_fn *p2s, - i2d_of_void *k2d, - struct key2any_ctx_st *ctx, + OSSL_i2d_of_void_ctx *k2d, + KEY2ANY_CTX *ctx, pem_password_cb *cb, void *cbarg) { - return - PEM_ASN1_write_bio(k2d, pemname, out, key, ctx->cipher, - NULL, 0, cb, cbarg) > 0; + return PEM_ASN1_write_bio_ctx(k2d, (void *)ctx, pemname, out, key, + ctx->cipher, NULL, 0, cb, cbarg) > 0; } static int key_to_type_specific_pem_priv_bio(BIO *out, const void *key, int key_nid, const char *pemname, key_to_paramstring_fn *p2s, - i2d_of_void *k2d, - struct key2any_ctx_st *ctx) + OSSL_i2d_of_void_ctx *k2d, + KEY2ANY_CTX *ctx) { return key_to_type_specific_pem_bio_cb(out, key, key_nid, pemname, p2s, k2d, ctx, @@ -418,8 +420,8 @@ static int key_to_type_specific_pem_priv_bio(BIO *out, const void *key, static int key_to_type_specific_pem_pub_bio(BIO *out, const void *key, int key_nid, const char *pemname, key_to_paramstring_fn *p2s, - i2d_of_void *k2d, - struct key2any_ctx_st *ctx) + OSSL_i2d_of_void_ctx *k2d, + KEY2ANY_CTX *ctx) { return key_to_type_specific_pem_bio_cb(out, key, key_nid, pemname, p2s, k2d, ctx, NULL, NULL); @@ -429,8 +431,8 @@ static int key_to_type_specific_pem_pub_bio(BIO *out, const void *key, static int key_to_type_specific_pem_param_bio(BIO *out, const void *key, int key_nid, const char *pemname, key_to_paramstring_fn *p2s, - i2d_of_void *k2d, - struct key2any_ctx_st *ctx) + OSSL_i2d_of_void_ctx *k2d, + KEY2ANY_CTX *ctx) { return key_to_type_specific_pem_bio_cb(out, key, key_nid, pemname, p2s, k2d, ctx, NULL, NULL); @@ -439,6 +441,16 @@ static int key_to_type_specific_pem_param_bio(BIO *out, const void *key, /* ---------------------------------------------------------------------- */ +#define k2d_NOCTX(n, f) \ + static int \ + n##_k2d(const void *key, unsigned char **pder, \ + ossl_unused void *ctx) \ + { \ + return f(key, pder); \ + } + +/* ---------------------------------------------------------------------- */ + #ifndef OPENSSL_NO_DH static int prepare_dh_params(const void *dh, int nid, int save, void **pstr, int *pstrtype) @@ -467,7 +479,8 @@ static int prepare_dh_params(const void *dh, int nid, int save, return 1; } -static int dh_spki_pub_to_der(const void *dh, unsigned char **pder) +static int dh_spki_pub_to_der(const void *dh, unsigned char **pder, + ossl_unused void *ctx) { const BIGNUM *bn = NULL; ASN1_INTEGER *pub_key = NULL; @@ -488,7 +501,8 @@ static int dh_spki_pub_to_der(const void *dh, unsigned char **pder) return ret; } -static int dh_pki_priv_to_der(const void *dh, unsigned char **pder) +static int dh_pki_priv_to_der(const void *dh, unsigned char **pder, + ossl_unused void *ctx) { const BIGNUM *bn = NULL; ASN1_INTEGER *priv_key = NULL; @@ -511,7 +525,9 @@ static int dh_pki_priv_to_der(const void *dh, unsigned char **pder) # define dh_epki_priv_to_der dh_pki_priv_to_der -static int dh_type_specific_params_to_der(const void *dh, unsigned char **pder) +static int +dh_type_specific_params_to_der(const void *dh, unsigned char **pder, + ossl_unused void *ctx) { if (DH_test_flags(dh, DH_FLAG_TYPE_DHX)) return i2d_DHxparams(dh, pder); @@ -580,7 +596,8 @@ static int prepare_dsa_params(const void *dsa, int nid, int save, return 1; } -static int dsa_spki_pub_to_der(const void *dsa, unsigned char **pder) +static int dsa_spki_pub_to_der(const void *dsa, unsigned char **pder, + ossl_unused void *ctx) { const BIGNUM *bn = NULL; ASN1_INTEGER *pub_key = NULL; @@ -601,7 +618,8 @@ static int dsa_spki_pub_to_der(const void *dsa, unsigned char **pder) return ret; } -static int dsa_pki_priv_to_der(const void *dsa, unsigned char **pder) +static int dsa_pki_priv_to_der(const void *dsa, unsigned char **pder, + ossl_unused void *ctx) { const BIGNUM *bn = NULL; ASN1_INTEGER *priv_key = NULL; @@ -622,11 +640,15 @@ static int dsa_pki_priv_to_der(const void *dsa, unsigned char **pder) return ret; } +k2d_NOCTX(dsa_prv, i2d_DSAPrivateKey) +k2d_NOCTX(dsa_pub, i2d_DSAPublicKey) +k2d_NOCTX(dsa_param, i2d_DSAparams) + # define dsa_epki_priv_to_der dsa_pki_priv_to_der -# define dsa_type_specific_priv_to_der (i2d_of_void *)i2d_DSAPrivateKey -# define dsa_type_specific_pub_to_der (i2d_of_void *)i2d_DSAPublicKey -# define dsa_type_specific_params_to_der (i2d_of_void *)i2d_DSAparams +# define dsa_type_specific_priv_to_der dsa_prv_k2d +# define dsa_type_specific_pub_to_der dsa_pub_k2d +# define dsa_type_specific_params_to_der dsa_param_k2d # define dsa_check_key_type NULL # define dsa_evp_type EVP_PKEY_DSA @@ -696,7 +718,8 @@ static int prepare_ec_params(const void *eckey, int nid, int save, } } -static int ec_spki_pub_to_der(const void *eckey, unsigned char **pder) +static int ec_spki_pub_to_der(const void *eckey, unsigned char **pder, + ossl_unused void *ctx) { if (EC_KEY_get0_public_key(eckey) == NULL) { ERR_raise(ERR_LIB_PROV, PROV_R_NOT_A_PUBLIC_KEY); @@ -705,7 +728,8 @@ static int ec_spki_pub_to_der(const void *eckey, unsigned char **pder) return i2o_ECPublicKey(eckey, pder); } -static int ec_pki_priv_to_der(const void *veckey, unsigned char **pder) +static int ec_pki_priv_to_der(const void *veckey, unsigned char **pder, + ossl_unused void *ctx) { EC_KEY *eckey = (EC_KEY *)veckey; unsigned int old_flags; @@ -725,11 +749,14 @@ static int ec_pki_priv_to_der(const void *veckey, unsigned char **pder) return ret; /* return the length of the der encoded data */ } +k2d_NOCTX(ec_param, i2d_ECParameters) +k2d_NOCTX(ec_prv, i2d_ECPrivateKey) + # define ec_epki_priv_to_der ec_pki_priv_to_der -# define ec_type_specific_params_to_der (i2d_of_void *)i2d_ECParameters +# define ec_type_specific_params_to_der ec_param_k2d /* No ec_type_specific_pub_to_der, there simply is no such thing */ -# define ec_type_specific_priv_to_der (i2d_of_void *)i2d_ECPrivateKey +# define ec_type_specific_priv_to_der ec_prv_k2d # define ec_check_key_type NULL # define ec_evp_type EVP_PKEY_EC @@ -754,7 +781,8 @@ static int ec_pki_priv_to_der(const void *veckey, unsigned char **pder) #ifndef OPENSSL_NO_ECX # define prepare_ecx_params NULL -static int ecx_spki_pub_to_der(const void *vecxkey, unsigned char **pder) +static int ecx_spki_pub_to_der(const void *vecxkey, unsigned char **pder, + ossl_unused void *ctx) { const ECX_KEY *ecxkey = vecxkey; unsigned char *keyblob; @@ -772,7 +800,8 @@ static int ecx_spki_pub_to_der(const void *vecxkey, unsigned char **pder) return ecxkey->keylen; } -static int ecx_pki_priv_to_der(const void *vecxkey, unsigned char **pder) +static int ecx_pki_priv_to_der(const void *vecxkey, unsigned char **pder, + ossl_unused void *ctx) { const ECX_KEY *ecxkey = vecxkey; ASN1_OCTET_STRING oct; @@ -895,6 +924,9 @@ static int prepare_rsa_params(const void *rsa, int nid, int save, return 0; } +k2d_NOCTX(rsa_prv, i2d_RSAPrivateKey) +k2d_NOCTX(rsa_pub, i2d_RSAPublicKey) + /* * RSA is extremely simple, as PKCS#1 is used for the PKCS#8 |privateKey| * field as well as the SubjectPublicKeyInfo |subjectPublicKey| field. @@ -902,8 +934,8 @@ static int prepare_rsa_params(const void *rsa, int nid, int save, #define rsa_pki_priv_to_der rsa_type_specific_priv_to_der #define rsa_epki_priv_to_der rsa_type_specific_priv_to_der #define rsa_spki_pub_to_der rsa_type_specific_pub_to_der -#define rsa_type_specific_priv_to_der (i2d_of_void *)i2d_RSAPrivateKey -#define rsa_type_specific_pub_to_der (i2d_of_void *)i2d_RSAPublicKey +#define rsa_type_specific_priv_to_der rsa_prv_k2d +#define rsa_type_specific_pub_to_der rsa_pub_k2d #define rsa_type_specific_params_to_der NULL static int rsa_check_key_type(const void *rsa, int expected_type) @@ -931,7 +963,7 @@ static OSSL_FUNC_decoder_freectx_fn key2any_freectx; static void *key2any_newctx(void *provctx) { - struct key2any_ctx_st *ctx = OPENSSL_zalloc(sizeof(*ctx)); + KEY2ANY_CTX *ctx = OPENSSL_zalloc(sizeof(*ctx)); if (ctx != NULL) { ctx->provctx = provctx; @@ -943,7 +975,7 @@ static void *key2any_newctx(void *provctx) static void key2any_freectx(void *vctx) { - struct key2any_ctx_st *ctx = vctx; + KEY2ANY_CTX *ctx = vctx; ossl_pw_clear_passphrase_data(&ctx->pwdata); EVP_CIPHER_free(ctx->cipher); @@ -963,7 +995,7 @@ static const OSSL_PARAM *key2any_settable_ctx_params(ossl_unused void *provctx) static int key2any_set_ctx_params(void *vctx, const OSSL_PARAM params[]) { - struct key2any_ctx_st *ctx = vctx; + KEY2ANY_CTX *ctx = vctx; OSSL_LIB_CTX *libctx = ossl_prov_ctx_get0_libctx(ctx->provctx); const OSSL_PARAM *cipherp = OSSL_PARAM_locate_const(params, OSSL_ENCODER_PARAM_CIPHER); @@ -1030,13 +1062,13 @@ static int key2any_check_selection(int selection, int selection_mask) return 0; } -static int key2any_encode(struct key2any_ctx_st *ctx, OSSL_CORE_BIO *cout, +static int key2any_encode(KEY2ANY_CTX *ctx, OSSL_CORE_BIO *cout, const void *key, int type, const char *pemname, check_key_type_fn *checker, key_to_der_fn *writer, OSSL_PASSPHRASE_CALLBACK *pwcb, void *pwcbarg, key_to_paramstring_fn *key2paramstring, - i2d_of_void *key2der) + OSSL_i2d_of_void_ctx *key2der) { int ret = 0; @@ -1242,7 +1274,7 @@ static int key2any_encode(struct key2any_ctx_st *ctx, OSSL_CORE_BIO *cout, impl##_to_##kind##_##output##_import_object(void *vctx, int selection, \ const OSSL_PARAM params[]) \ { \ - struct key2any_ctx_st *ctx = vctx; \ + KEY2ANY_CTX *ctx = vctx; \ \ return ossl_prov_import_key(ossl_##impl##_keymgmt_functions, \ ctx->provctx, selection, params); \ diff --git a/util/libcrypto.num b/util/libcrypto.num index 1b96c81886..d0b8f4eca7 100644 --- a/util/libcrypto.num +++ b/util/libcrypto.num @@ -5884,3 +5884,4 @@ i2d_OSSL_AA_DIST_POINT ? 3_5_0 EXIST::FUNCTION: OSSL_AA_DIST_POINT_free ? 3_5_0 EXIST::FUNCTION: OSSL_AA_DIST_POINT_new ? 3_5_0 EXIST::FUNCTION: OSSL_AA_DIST_POINT_it ? 3_5_0 EXIST::FUNCTION: +PEM_ASN1_write_bio_ctx ? 3_5_0 EXIST::FUNCTION: diff --git a/util/missingcrypto.txt b/util/missingcrypto.txt index 3dd997b192..9191854ae7 100644 --- a/util/missingcrypto.txt +++ b/util/missingcrypto.txt @@ -734,6 +734,7 @@ PEM_ASN1_read(3) PEM_ASN1_read_bio(3) PEM_ASN1_write(3) PEM_ASN1_write_bio(3) +PEM_ASN1_write_bio_ctx(3) PEM_SignFinal(3) PEM_SignInit(3) PEM_SignUpdate(3)