ENCODER: Adapt calls to the changed OSSL_ENCODER_CTX_new_by_EVP_PKEY()
authorRichard Levitte <levitte@openssl.org>
Mon, 14 Sep 2020 08:42:05 +0000 (10:42 +0200)
committerRichard Levitte <levitte@openssl.org>
Sun, 20 Sep 2020 15:31:22 +0000 (17:31 +0200)
Reviewed-by: Shane Lontis <shane.lontis@oracle.com>
(Merged from https://github.com/openssl/openssl/pull/12873)

crypto/asn1/i2d_pr.c
crypto/evp/p_lib.c
crypto/pem/pem_local.h
crypto/pem/pem_pk8.c
crypto/x509/x_pubkey.c

index 84513db5bf2df3467602515e2d7d5db15b53a82d..e35781f4bda2bf9d312988520943a05527d1ad36 100644 (file)
@@ -31,16 +31,18 @@ int i2d_PrivateKey(const EVP_PKEY *a, unsigned char **pp)
         return ret;
     }
     if (a->keymgmt != NULL) {
-        const char *encprop = OSSL_ENCODER_PrivateKey_TO_DER_PQ;
+        /* The private key includes everything */
+        int selection =
+            OSSL_KEYMGMT_SELECT_ALL_PARAMETERS | OSSL_KEYMGMT_SELECT_KEYPAIR;
         OSSL_ENCODER_CTX *ctx =
-            OSSL_ENCODER_CTX_new_by_EVP_PKEY(a, encprop);
+            OSSL_ENCODER_CTX_new_by_EVP_PKEY(a, "DER", selection, NULL, NULL);
         BIO *out = BIO_new(BIO_s_mem());
         BUF_MEM *buf = NULL;
         int ret = -1;
 
         if (ctx != NULL
             && out != NULL
-            && OSSL_ENCODER_CTX_get_encoder(ctx) != NULL
+            && OSSL_ENCODER_CTX_get_num_encoders(ctx) != 0
             && OSSL_ENCODER_to_bio(ctx, out)
             && BIO_get_mem_ptr(out, &buf) > 0) {
             ret = buf->length;
index 5e032b40536858e08af1adf00989c9a193d8fde7..f78ff73ab783ede05e145956a3ee9588496cc808 100644 (file)
@@ -1163,6 +1163,8 @@ static int unsup_alg(BIO *out, const EVP_PKEY *pkey, int indent,
 }
 
 static int print_pkey(const EVP_PKEY *pkey, BIO *out, int indent,
+                      int selection /* For provided encoding */,
+                      OPENSSL_CTX *libctx /* For provided encoding */,
                       const char *propquery /* For provided encoding */,
                       int (*legacy_print)(BIO *out, const EVP_PKEY *pkey,
                                           int indent, ASN1_PCTX *pctx),
@@ -1176,8 +1178,9 @@ static int print_pkey(const EVP_PKEY *pkey, BIO *out, int indent,
     if (!print_set_indent(&out, &pop_f_prefix, &saved_indent, indent))
         return 0;
 
-    ctx = OSSL_ENCODER_CTX_new_by_EVP_PKEY(pkey, propquery);
-    if (OSSL_ENCODER_CTX_get_encoder(ctx) != NULL)
+    ctx = OSSL_ENCODER_CTX_new_by_EVP_PKEY(pkey, "TEXT", selection,
+                                           libctx, propquery);
+    if (OSSL_ENCODER_CTX_get_num_encoders(ctx) != 0)
         ret = OSSL_ENCODER_to_bio(ctx, out);
     OSSL_ENCODER_CTX_free(ctx);
 
@@ -1198,7 +1201,10 @@ static int print_pkey(const EVP_PKEY *pkey, BIO *out, int indent,
 int EVP_PKEY_print_public(BIO *out, const EVP_PKEY *pkey,
                           int indent, ASN1_PCTX *pctx)
 {
-    return print_pkey(pkey, out, indent, OSSL_ENCODER_PUBKEY_TO_TEXT_PQ,
+    return print_pkey(pkey, out, indent,
+                      OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS
+                      | OSSL_KEYMGMT_SELECT_PUBLIC_KEY,
+                      NULL, NULL,
                       (pkey->ameth != NULL ? pkey->ameth->pub_print : NULL),
                       pctx);
 }
@@ -1206,7 +1212,10 @@ int EVP_PKEY_print_public(BIO *out, const EVP_PKEY *pkey,
 int EVP_PKEY_print_private(BIO *out, const EVP_PKEY *pkey,
                            int indent, ASN1_PCTX *pctx)
 {
-    return print_pkey(pkey, out, indent, OSSL_ENCODER_PrivateKey_TO_TEXT_PQ,
+    return print_pkey(pkey, out, indent,
+                      OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS
+                      | OSSL_KEYMGMT_SELECT_KEYPAIR,
+                      NULL, NULL,
                       (pkey->ameth != NULL ? pkey->ameth->priv_print : NULL),
                       pctx);
 }
@@ -1214,7 +1223,8 @@ int EVP_PKEY_print_private(BIO *out, const EVP_PKEY *pkey,
 int EVP_PKEY_print_params(BIO *out, const EVP_PKEY *pkey,
                           int indent, ASN1_PCTX *pctx)
 {
-    return print_pkey(pkey, out, indent, OSSL_ENCODER_Parameters_TO_TEXT_PQ,
+    return print_pkey(pkey, out, indent, OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS,
+                      NULL, NULL,
                       (pkey->ameth != NULL ? pkey->ameth->param_print : NULL),
                       pctx);
 }
index 81d1718e327481e0684b2b03236cdb175146dfd8..39dc462e5456e65f4b239c1493b7dadd7a58b7cb 100644 (file)
  * moved here.
  */
 
+#include <openssl/core_dispatch.h>
 #include <openssl/pem.h>
 #include <openssl/encoder.h>
 
+/*
+ * Selectors, named according to the ASN.1 names used throughout libcrypto.
+ *
+ * Note that these are not absolutely mandatory, they are rather a wishlist
+ * of sorts.  The provider implementations are free to make choices that
+ * make sense for them, based on these selectors.
+ * For example, the EC backend is likely to really just output the private
+ * key to a PKCS#8 structure, even thought PEM_SELECTION_PrivateKey specifies
+ * the public key as well.  This is fine, as long as the corresponding
+ * decoding operation can return an object that contains what libcrypto
+ * expects.
+ */
+# define PEM_SELECTION_PUBKEY                                           \
+    (OSSL_KEYMGMT_SELECT_ALL_PARAMETERS | OSSL_KEYMGMT_SELECT_PUBLIC_KEY)
+# define PEM_SELECTION_PrivateKey                                       \
+    (OSSL_KEYMGMT_SELECT_ALL_PARAMETERS | OSSL_KEYMGMT_SELECT_KEYPAIR)
+# define PEM_SELECTION_Parameters OSSL_KEYMGMT_SELECT_ALL_PARAMETERS
+
 /* Alternative IMPLEMENT macros for provided encoders */
 
 # define IMPLEMENT_PEM_provided_write_body_vars(type, asn1)             \
     int ret = 0;                                                        \
-    const char *pq = OSSL_ENCODER_##asn1##_TO_PEM_PQ;                   \
-    OSSL_ENCODER_CTX *ctx = OSSL_ENCODER_CTX_new_by_##type(x, pq);      \
+    OSSL_ENCODER_CTX *ctx =                                             \
+        OSSL_ENCODER_CTX_new_by_##type(x, "PEM", PEM_SELECTION_##asn1,  \
+                                       NULL, NULL);                     \
                                                                         \
-    if (ctx != NULL && OSSL_ENCODER_CTX_get_encoder(ctx) == NULL) {     \
+    if (OSSL_ENCODER_CTX_get_num_encoders(ctx) == 0) {                  \
         OSSL_ENCODER_CTX_free(ctx);                                     \
         goto legacy;                                                    \
     }
@@ -45,8 +65,8 @@
                 && !OSSL_ENCODER_CTX_set_passphrase(ctx, kstr, klen))   \
                 ret = 0;                                                \
             else if (cb != NULL                                         \
-                     && !OSSL_ENCODER_CTX_set_passphrase_cb(ctx,        \
-                                                            cb, u))     \
+                     && !OSSL_ENCODER_CTX_set_pem_password_cb(ctx,      \
+                                                              cb, u))   \
                 ret = 0;                                                \
         }                                                               \
     }                                                                   \
index 84d431820b1524909d42e6bd320a0661316049ae..05d6c4ae83410451b85a69c321d49422e7135f36 100644 (file)
@@ -9,6 +9,7 @@
 
 #include <stdio.h>
 #include "internal/cryptlib.h"
+#include <openssl/core_dispatch.h>
 #include <openssl/buffer.h>
 #include <openssl/objects.h>
 #include <openssl/evp.h>
 static int do_pk8pkey(BIO *bp, const EVP_PKEY *x, int isder,
                       int nid, const EVP_CIPHER *enc,
                       const char *kstr, int klen,
-                      pem_password_cb *cb, void *u);
+                      pem_password_cb *cb, void *u,
+                      OPENSSL_CTX *libctx, const char *propq);
 
 #ifndef OPENSSL_NO_STDIO
 static int do_pk8pkey_fp(FILE *bp, const EVP_PKEY *x, int isder,
                          int nid, const EVP_CIPHER *enc,
                          const char *kstr, int klen,
-                         pem_password_cb *cb, void *u);
+                         pem_password_cb *cb, void *u,
+                         OPENSSL_CTX *libctx, const char *propq);
 #endif
 /*
  * These functions write a private key in PKCS#8 format: it is a "drop in"
@@ -39,39 +42,40 @@ int PEM_write_bio_PKCS8PrivateKey_nid(BIO *bp, const EVP_PKEY *x, int nid,
                                       const char *kstr, int klen,
                                       pem_password_cb *cb, void *u)
 {
-    return do_pk8pkey(bp, x, 0, nid, NULL, kstr, klen, cb, u);
+    return do_pk8pkey(bp, x, 0, nid, NULL, kstr, klen, cb, u, NULL, NULL);
 }
 
 int PEM_write_bio_PKCS8PrivateKey(BIO *bp, const EVP_PKEY *x, const EVP_CIPHER *enc,
                                   const char *kstr, int klen,
                                   pem_password_cb *cb, void *u)
 {
-    return do_pk8pkey(bp, x, 0, -1, enc, kstr, klen, cb, u);
+    return do_pk8pkey(bp, x, 0, -1, enc, kstr, klen, cb, u, NULL, NULL);
 }
 
 int i2d_PKCS8PrivateKey_bio(BIO *bp, const EVP_PKEY *x, const EVP_CIPHER *enc,
                             const char *kstr, int klen,
                             pem_password_cb *cb, void *u)
 {
-    return do_pk8pkey(bp, x, 1, -1, enc, kstr, klen, cb, u);
+    return do_pk8pkey(bp, x, 1, -1, enc, kstr, klen, cb, u, NULL, NULL);
 }
 
 int i2d_PKCS8PrivateKey_nid_bio(BIO *bp, const EVP_PKEY *x, int nid,
                                 const char *kstr, int klen,
                                 pem_password_cb *cb, void *u)
 {
-    return do_pk8pkey(bp, x, 1, nid, NULL, kstr, klen, cb, u);
+    return do_pk8pkey(bp, x, 1, nid, NULL, kstr, klen, cb, u, NULL, NULL);
 }
 
 static int do_pk8pkey(BIO *bp, const EVP_PKEY *x, int isder, int nid,
                       const EVP_CIPHER *enc, const char *kstr, int klen,
-                      pem_password_cb *cb, void *u)
+                      pem_password_cb *cb, void *u,
+                      OPENSSL_CTX *libctx, const char *propq)
 {
     int ret = 0;
-    const char *pq = isder
-        ? OSSL_ENCODER_PrivateKey_TO_DER_PQ
-        : OSSL_ENCODER_PrivateKey_TO_PEM_PQ;
-    OSSL_ENCODER_CTX *ctx = OSSL_ENCODER_CTX_new_by_EVP_PKEY(x, pq);
+    const char *outtype = isder ? "DER" : "PEM";
+    OSSL_ENCODER_CTX *ctx =
+        OSSL_ENCODER_CTX_new_by_EVP_PKEY(x, outtype, OSSL_KEYMGMT_SELECT_ALL,
+                                         libctx, propq);
 
     if (ctx == NULL)
         return 0;
@@ -90,7 +94,7 @@ static int do_pk8pkey(BIO *bp, const EVP_PKEY *x, int isder, int nid,
         }
     }
 
-    if (OSSL_ENCODER_CTX_get_encoder(ctx) != NULL) {
+    if (OSSL_ENCODER_CTX_get_num_encoders(ctx) != 0) {
         ret = 1;
         if (enc != NULL) {
             ret = 0;
@@ -108,7 +112,7 @@ static int do_pk8pkey(BIO *bp, const EVP_PKEY *x, int isder, int nid,
                     && !OSSL_ENCODER_CTX_set_passphrase(ctx, ukstr, klen))
                     ret = 0;
                 else if (cb != NULL
-                         && !OSSL_ENCODER_CTX_set_passphrase_cb(ctx, cb, u))
+                         && !OSSL_ENCODER_CTX_set_pem_password_cb(ctx, cb, u))
                     ret = 0;
             }
         }
@@ -199,33 +203,34 @@ int i2d_PKCS8PrivateKey_fp(FILE *fp, const EVP_PKEY *x, const EVP_CIPHER *enc,
                            const char *kstr, int klen,
                            pem_password_cb *cb, void *u)
 {
-    return do_pk8pkey_fp(fp, x, 1, -1, enc, kstr, klen, cb, u);
+    return do_pk8pkey_fp(fp, x, 1, -1, enc, kstr, klen, cb, u, NULL, NULL);
 }
 
 int i2d_PKCS8PrivateKey_nid_fp(FILE *fp, const EVP_PKEY *x, int nid,
                                const char *kstr, int klen,
                                pem_password_cb *cb, void *u)
 {
-    return do_pk8pkey_fp(fp, x, 1, nid, NULL, kstr, klen, cb, u);
+    return do_pk8pkey_fp(fp, x, 1, nid, NULL, kstr, klen, cb, u, NULL, NULL);
 }
 
 int PEM_write_PKCS8PrivateKey_nid(FILE *fp, const EVP_PKEY *x, int nid,
                                   const char *kstr, int klen,
                                   pem_password_cb *cb, void *u)
 {
-    return do_pk8pkey_fp(fp, x, 0, nid, NULL, kstr, klen, cb, u);
+    return do_pk8pkey_fp(fp, x, 0, nid, NULL, kstr, klen, cb, u, NULL, NULL);
 }
 
 int PEM_write_PKCS8PrivateKey(FILE *fp, const EVP_PKEY *x, const EVP_CIPHER *enc,
                               const char *kstr, int klen,
                               pem_password_cb *cb, void *u)
 {
-    return do_pk8pkey_fp(fp, x, 0, -1, enc, kstr, klen, cb, u);
+    return do_pk8pkey_fp(fp, x, 0, -1, enc, kstr, klen, cb, u, NULL, NULL);
 }
 
 static int do_pk8pkey_fp(FILE *fp, const EVP_PKEY *x, int isder, int nid,
                          const EVP_CIPHER *enc, const char *kstr, int klen,
-                         pem_password_cb *cb, void *u)
+                         pem_password_cb *cb, void *u,
+                         OPENSSL_CTX *libctx, const char *propq)
 {
     BIO *bp;
     int ret;
@@ -234,7 +239,7 @@ static int do_pk8pkey_fp(FILE *fp, const EVP_PKEY *x, int isder, int nid,
         PEMerr(PEM_F_DO_PK8PKEY_FP, ERR_R_BUF_LIB);
         return 0;
     }
-    ret = do_pk8pkey(bp, x, isder, nid, enc, kstr, klen, cb, u);
+    ret = do_pk8pkey(bp, x, isder, nid, enc, kstr, klen, cb, u, libctx, propq);
     BIO_free(bp);
     return ret;
 }
index cb47f917ad2ce0acf626fda530bcf778e98d8525..a4d3c9fa5e4ab403b8d536729d1cf4d0586eac0d 100644 (file)
@@ -23,6 +23,7 @@
 #include <openssl/rsa.h>
 #include <openssl/dsa.h>
 #include <openssl/encoder.h>
+#include "internal/provider.h"
 
 struct X509_pubkey_st {
     X509_ALGOR *algor;
@@ -96,10 +97,14 @@ int X509_PUBKEY_set(X509_PUBKEY **x, EVP_PKEY *pkey)
             goto error;
         }
     } else if (pkey->keymgmt != NULL) {
+        const OSSL_PROVIDER *pkprov = EVP_KEYMGMT_provider(pkey->keymgmt);
+        OPENSSL_CTX *libctx = ossl_provider_library_context(pkprov);
         BIO *bmem = BIO_new(BIO_s_mem());
-        const char *encprop = OSSL_ENCODER_PUBKEY_TO_DER_PQ;
+        int selection = (OSSL_KEYMGMT_SELECT_PUBLIC_KEY
+                         | OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS);
         OSSL_ENCODER_CTX *ectx =
-            OSSL_ENCODER_CTX_new_by_EVP_PKEY(pkey, encprop);
+            OSSL_ENCODER_CTX_new_by_EVP_PKEY(pkey, "DER", selection,
+                                             libctx, NULL);
 
         if (OSSL_ENCODER_to_bio(ectx, bmem)) {
             const unsigned char *der = NULL;
@@ -303,15 +308,17 @@ int i2d_PUBKEY(const EVP_PKEY *a, unsigned char **pp)
         }
         X509_PUBKEY_free(xpk);
     } else if (a->keymgmt != NULL) {
-        const char *encprop = OSSL_ENCODER_PUBKEY_TO_DER_PQ;
+        const OSSL_PROVIDER *pkprov = EVP_KEYMGMT_provider(a->keymgmt);
+        OPENSSL_CTX *libctx = ossl_provider_library_context(pkprov);
+        int selection = (OSSL_KEYMGMT_SELECT_PUBLIC_KEY
+                         | OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS);
         OSSL_ENCODER_CTX *ctx =
-            OSSL_ENCODER_CTX_new_by_EVP_PKEY(a, encprop);
+            OSSL_ENCODER_CTX_new_by_EVP_PKEY(a, "DER", selection, libctx, NULL);
         BIO *out = BIO_new(BIO_s_mem());
         BUF_MEM *buf = NULL;
 
-        if (ctx != NULL
+        if (OSSL_ENCODER_CTX_get_num_encoders(ctx) != 0
             && out != NULL
-            && OSSL_ENCODER_CTX_get_encoder(ctx) != NULL
             && OSSL_ENCODER_to_bio(ctx, out)
             && BIO_get_mem_ptr(out, &buf) > 0) {
             ret = buf->length;