]> git.ipfire.org Git - thirdparty/openssl.git/commitdiff
Make the provider context available to encoders
authorViktor Dukhovni <openssl-users@dukhovni.org>
Sun, 19 Jan 2025 15:51:07 +0000 (02:51 +1100)
committerViktor Dukhovni <openssl-users@dukhovni.org>
Tue, 21 Jan 2025 06:19:07 +0000 (17:19 +1100)
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 <tjh@openssl.org>
Reviewed-by: Shane Lontis <shane.lontis@oracle.com>
(Merged from https://github.com/openssl/openssl/pull/26475)

crypto/pem/pem_lib.c
doc/man3/PEM_read.pod
include/openssl/asn1.h.in
include/openssl/pem.h
providers/implementations/encode_decode/encode_key2any.c
util/libcrypto.num
util/missingcrypto.txt

index 9d8ad35ad39ff55600368f830a9bc84328bc7f7e..5eff44dbbbaeaf0d041c63ae5ac3ba4a3db7b12b 100644 (file)
@@ -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)
 {
index c76039f711c20fa32f7956be114dbc5e9bd6900e..3a46af230045e8a1b7bd052f7c4e4f8cfdcb1f7f 100644 (file)
@@ -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 <openssl/pem.h>
 
- 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<PEM_R_NO_START_LINE>, which indicates that no more
 PEM objects were found.  See L<ERR_peek_last_error(3)>, L<ERR_GET_REASON(3)>.
 
@@ -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<i2d> function that serialises the input ASN.1 object.
+
 =head1 SEE ALSO
 
 L<ERR_peek_last_error(3)>, L<ERR_GET_LIB(3)>,
 L<d2i_PKCS8PrivateKey_bio(3)>,
 L<passphrase-encoding(7)>
 
+=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.
index 862ec740a92b1406bb892f8dbfe9c7589811ad82..b8c498986271ea95becbc7b0ccf21c8b005b2d2e 100644 (file)
@@ -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
index 6b7b66a2be4b23164b3b8007b834bb4c23e49e62..92da0aa357aa92589df5c661521719f8fcf304da 100644 (file)
@@ -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);
index e77cb22e8c2fb0cae5a93e15d7959b328c56017f..42336ce78179354fdef729c357b029a5c148a6c1 100644 (file)
@@ -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);       \
index 1b96c81886fbc548783a41dd115085d9ea91c9a3..d0b8f4eca7eb7a0e6a2c7591215d21f857af4c5b 100644 (file)
@@ -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:
index 3dd997b1927b3cd29302fc341cdd218fdd6b1bf0..9191854ae77ade1a1bd4ee41b9117d40c59ba8f9 100644 (file)
@@ -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)