PROV: Add a DER to RSA-PSS deserializer implementation
authorRichard Levitte <levitte@openssl.org>
Mon, 20 Jul 2020 14:13:18 +0000 (16:13 +0200)
committerRichard Levitte <levitte@openssl.org>
Mon, 27 Jul 2020 10:15:29 +0000 (12:15 +0200)
Reviewed-by: Shane Lontis <shane.lontis@oracle.com>
(Merged from https://github.com/openssl/openssl/pull/12492)

crypto/err/openssl.txt
providers/common/include/prov/providercommonerr.h
providers/common/provider_err.c
providers/defltprov.c
providers/implementations/include/prov/implementations.h
providers/implementations/keymgmt/rsa_kmgmt.c
providers/implementations/serializers/deserialize_der2rsa.c
providers/implementations/serializers/serializer_local.h
providers/implementations/serializers/serializer_rsa.c

index e5ed28bce1e20295da15579fe7106326244ed2e0..a99648a1fde090ee922f8c624d101ec9a9d7be94 100644 (file)
@@ -2878,6 +2878,7 @@ PROV_R_INVALID_MODE:125:invalid mode
 PROV_R_INVALID_MODE_INT:126:invalid mode int
 PROV_R_INVALID_PADDING_MODE:168:invalid padding mode
 PROV_R_INVALID_PSS_SALTLEN:169:invalid pss saltlen
+PROV_R_INVALID_RSA_KEY:217:invalid rsa key
 PROV_R_INVALID_SALT_LENGTH:112:invalid salt length
 PROV_R_INVALID_SEED_LENGTH:154:invalid seed length
 PROV_R_INVALID_SIGNATURE_SIZE:179:invalid signature size
index f5fd37d9cc007b1a0cb86f8f6b540df661a488f2..bdc39e4121de0c2cb4e488fa77a97f82a66b1d4f 100644 (file)
@@ -101,6 +101,7 @@ int ERR_load_PROV_strings(void);
 # define PROV_R_INVALID_MODE_INT                          126
 # define PROV_R_INVALID_PADDING_MODE                      168
 # define PROV_R_INVALID_PSS_SALTLEN                       169
+# define PROV_R_INVALID_RSA_KEY                           217
 # define PROV_R_INVALID_SALT_LENGTH                       112
 # define PROV_R_INVALID_SEED_LENGTH                       154
 # define PROV_R_INVALID_SIGNATURE_SIZE                    179
index 7a5c41bfda372058b744e315d3face1d29c9e44b..e65ce96471a9ef555f5303e52b8352d9da241228 100644 (file)
@@ -96,6 +96,7 @@ static const ERR_STRING_DATA PROV_str_reasons[] = {
     "invalid padding mode"},
     {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INVALID_PSS_SALTLEN),
     "invalid pss saltlen"},
+    {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INVALID_RSA_KEY), "invalid rsa key"},
     {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INVALID_SALT_LENGTH),
     "invalid salt length"},
     {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INVALID_SEED_LENGTH),
index 7ab006ae831ae36b3dfa4d1ef1c2ecf96915830c..466b7908a118711c3699807e3d6420cf79d55844 100644 (file)
@@ -537,6 +537,8 @@ static const OSSL_ALGORITHM deflt_serializer[] = {
 static const OSSL_ALGORITHM deflt_deserializer[] = {
     { "RSA", "provider=default,fips=yes,input=der",
       der_to_rsa_deserializer_functions },
+    { "RSA-PSS", "provider=default,fips=yes,input=der",
+      der_to_rsapss_deserializer_functions },
 
     { "DER", "provider=default,fips=yes,input=pem",
       pem_to_der_deserializer_functions },
index 4890f11969112a11bf47319b57d44b5cd1f20a53..b02f0c6476bd0255cc118abf2ce43256a2c0ba49 100644 (file)
@@ -360,4 +360,5 @@ extern const OSSL_DISPATCH ec_pub_pem_serializer_functions[];
 extern const OSSL_DISPATCH ec_param_pem_serializer_functions[];
 
 extern const OSSL_DISPATCH der_to_rsa_deserializer_functions[];
+extern const OSSL_DISPATCH der_to_rsapss_deserializer_functions[];
 extern const OSSL_DISPATCH pem_to_der_deserializer_functions[];
index 21a35d7d9a4b5d60f9072c2dc8b4d9ffcccf460b..7ed280e861f5e68cc25b1f9f4430abbf0fec5af2 100644 (file)
@@ -628,6 +628,7 @@ const OSSL_DISPATCH rsapss_keymgmt_functions[] = {
       (void (*)(void))rsapss_gen_settable_params },
     { OSSL_FUNC_KEYMGMT_GEN, (void (*)(void))rsa_gen },
     { OSSL_FUNC_KEYMGMT_GEN_CLEANUP, (void (*)(void))rsa_gen_cleanup },
+    { OSSL_FUNC_KEYMGMT_LOAD, (void (*)(void))rsa_load },
     { OSSL_FUNC_KEYMGMT_FREE, (void (*)(void))rsa_freedata },
     { OSSL_FUNC_KEYMGMT_GET_PARAMS, (void (*) (void))rsa_get_params },
     { OSSL_FUNC_KEYMGMT_GETTABLE_PARAMS, (void (*) (void))rsa_gettable_params },
index 6854c7efcbdbc111131715c6a63ed35df2c5f4aa..75066546ba8ed0510e50e089592bf670deb2eefd 100644 (file)
 #include <openssl/core_dispatch.h>
 #include <openssl/core_names.h>
 #include <openssl/crypto.h>
+#include <openssl/err.h>
 #include <openssl/params.h>
 #include <openssl/x509.h>
 #include "prov/bio.h"
 #include "prov/implementations.h"
+#include "prov/providercommonerr.h"
 #include "serializer_local.h"
 
 static OSSL_FUNC_deserializer_newctx_fn der2rsa_newctx;
@@ -37,10 +39,12 @@ static OSSL_FUNC_deserializer_export_object_fn der2rsa_export_object;
 struct der2rsa_ctx_st {
     PROV_CTX *provctx;
 
+    int type;
+
     struct pkcs8_encrypt_ctx_st sc;
 };
 
-static void *der2rsa_newctx(void *provctx)
+static struct der2rsa_ctx_st *der2rsa_newctx_int(void *provctx)
 {
     struct der2rsa_ctx_st *ctx = OPENSSL_zalloc(sizeof(*ctx));
 
@@ -52,6 +56,24 @@ static void *der2rsa_newctx(void *provctx)
     return ctx;
 }
 
+static void *der2rsa_newctx(void *provctx)
+{
+    struct der2rsa_ctx_st *ctx = der2rsa_newctx_int(provctx);
+
+    if (ctx != NULL)
+        ctx->type = EVP_PKEY_RSA;
+    return ctx;
+}
+
+static void *der2rsapss_newctx(void *provctx)
+{
+    struct der2rsa_ctx_st *ctx = der2rsa_newctx_int(provctx);
+
+    if (ctx != NULL)
+        ctx->type = EVP_PKEY_RSA_PSS;
+    return ctx;
+}
+
 static void der2rsa_freectx(void *vctx)
 {
     struct der2rsa_ctx_st *ctx = vctx;
@@ -166,7 +188,7 @@ static int der2rsa_deserialize(void *vctx, OSSL_CORE_BIO *cin,
     }
 
     derp = der;
-    if ((pkey = d2i_PrivateKey_ex(EVP_PKEY_RSA, NULL, &derp, der_len,
+    if ((pkey = d2i_PrivateKey_ex(ctx->type, NULL, &derp, der_len,
                                   libctx, NULL)) != NULL) {
         /* Tear out the RSA pointer from the pkey */
         rsa = EVP_PKEY_get1_RSA(pkey);
@@ -177,10 +199,27 @@ static int der2rsa_deserialize(void *vctx, OSSL_CORE_BIO *cin,
 
     if (rsa != NULL) {
         OSSL_PARAM params[3];
+        char *object_type = NULL;
+
+        switch (RSA_test_flags(rsa, RSA_FLAG_TYPE_MASK)) {
+        case RSA_FLAG_TYPE_RSA:
+            object_type = "RSA";
+            break;
+        case RSA_FLAG_TYPE_RSASSAPSS:
+            object_type = "RSA-PSS";
+            break;
+        default:
+            ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_RSA_KEY,
+                           "Expected the RSA type to be %d or %d, but got %d",
+                           RSA_FLAG_TYPE_RSA, RSA_FLAG_TYPE_RSASSAPSS,
+                           RSA_test_flags(rsa, RSA_FLAG_TYPE_MASK));
+            goto end;
+        }
+
 
         params[0] =
             OSSL_PARAM_construct_utf8_string(OSSL_DESERIALIZER_PARAM_DATA_TYPE,
-                                             "RSA", 0);
+                                             object_type, 0);
         /* The address of the key becomes the octet string */
         params[1] =
             OSSL_PARAM_construct_octet_string(OSSL_DESERIALIZER_PARAM_REFERENCE,
@@ -189,17 +228,18 @@ static int der2rsa_deserialize(void *vctx, OSSL_CORE_BIO *cin,
 
         ok = data_cb(params, data_cbarg);
     }
+ end:
     RSA_free(rsa);
 
     return ok;
 }
 
-static int der2rsa_export_object(void *vctx,
-                                 const void *reference, size_t reference_sz,
-                                 OSSL_CALLBACK *export_cb, void *export_cbarg)
+static int der2rsa_export_object_int(void *vctx,
+                                     const void *reference, size_t reference_sz,
+                                     OSSL_FUNC_keymgmt_export_fn *rsa_export,
+                                     OSSL_CALLBACK *export_cb,
+                                     void *export_cbarg)
 {
-    OSSL_FUNC_keymgmt_export_fn *rsa_export =
-        ossl_prov_get_keymgmt_rsa_export();
     void *keydata;
 
     if (reference_sz == sizeof(keydata) && rsa_export != NULL) {
@@ -212,6 +252,26 @@ static int der2rsa_export_object(void *vctx,
     return 0;
 }
 
+static int der2rsa_export_object(void *vctx,
+                                 const void *reference, size_t reference_sz,
+                                 OSSL_CALLBACK *export_cb,
+                                 void *export_cbarg)
+{
+    return der2rsa_export_object_int(vctx, reference, reference_sz,
+                                     ossl_prov_get_keymgmt_rsa_export(),
+                                     export_cb, export_cbarg);
+}
+
+static int der2rsapss_export_object(void *vctx,
+                                    const void *reference, size_t reference_sz,
+                                    OSSL_CALLBACK *export_cb,
+                                    void *export_cbarg)
+{
+    return der2rsa_export_object_int(vctx, reference, reference_sz,
+                                     ossl_prov_get_keymgmt_rsapss_export(),
+                                     export_cb, export_cbarg);
+}
+
 const OSSL_DISPATCH der_to_rsa_deserializer_functions[] = {
     { OSSL_FUNC_DESERIALIZER_NEWCTX, (void (*)(void))der2rsa_newctx },
     { OSSL_FUNC_DESERIALIZER_FREECTX, (void (*)(void))der2rsa_freectx },
@@ -229,3 +289,21 @@ const OSSL_DISPATCH der_to_rsa_deserializer_functions[] = {
       (void (*)(void))der2rsa_export_object },
     { 0, NULL }
 };
+
+const OSSL_DISPATCH der_to_rsapss_deserializer_functions[] = {
+    { OSSL_FUNC_DESERIALIZER_NEWCTX, (void (*)(void))der2rsapss_newctx },
+    { OSSL_FUNC_DESERIALIZER_FREECTX, (void (*)(void))der2rsa_freectx },
+    { OSSL_FUNC_DESERIALIZER_GETTABLE_PARAMS,
+      (void (*)(void))der2rsa_gettable_params },
+    { OSSL_FUNC_DESERIALIZER_GET_PARAMS,
+      (void (*)(void))der2rsa_get_params },
+    { OSSL_FUNC_DESERIALIZER_SETTABLE_CTX_PARAMS,
+      (void (*)(void))der2rsa_settable_ctx_params },
+    { OSSL_FUNC_DESERIALIZER_SET_CTX_PARAMS,
+      (void (*)(void))der2rsa_set_ctx_params },
+    { OSSL_FUNC_DESERIALIZER_DESERIALIZE,
+      (void (*)(void))der2rsa_deserialize },
+    { OSSL_FUNC_DESERIALIZER_EXPORT_OBJECT,
+      (void (*)(void))der2rsapss_export_object },
+    { 0, NULL }
+};
index a94418bb2a3df865ee505a4cdb1980fd628dbe78..f1d2fe743c6e2f6a8c0c8ac277f05c00ed82b635 100644 (file)
@@ -38,9 +38,11 @@ OSSL_FUNC_keymgmt_import_fn *ossl_prov_get_keymgmt_import(const OSSL_DISPATCH *f
 OSSL_FUNC_keymgmt_export_fn *ossl_prov_get_keymgmt_export(const OSSL_DISPATCH *fns);
 
 OSSL_FUNC_keymgmt_new_fn *ossl_prov_get_keymgmt_rsa_new(void);
+OSSL_FUNC_keymgmt_new_fn *ossl_prov_get_keymgmt_rsapss_new(void);
 OSSL_FUNC_keymgmt_free_fn *ossl_prov_get_keymgmt_rsa_free(void);
 OSSL_FUNC_keymgmt_import_fn *ossl_prov_get_keymgmt_rsa_import(void);
 OSSL_FUNC_keymgmt_export_fn *ossl_prov_get_keymgmt_rsa_export(void);
+OSSL_FUNC_keymgmt_export_fn *ossl_prov_get_keymgmt_rsapss_export(void);
 OSSL_FUNC_keymgmt_new_fn *ossl_prov_get_keymgmt_dh_new(void);
 OSSL_FUNC_keymgmt_free_fn *ossl_prov_get_keymgmt_dh_free(void);
 OSSL_FUNC_keymgmt_import_fn *ossl_prov_get_keymgmt_dh_import(void);
index d2a54598280ca81b634f7c032ac16222d56093b2..9250d497354965a1d977d196ec9c1bdc7e9e4e99 100644 (file)
@@ -27,6 +27,11 @@ OSSL_FUNC_keymgmt_new_fn *ossl_prov_get_keymgmt_rsa_new(void)
     return ossl_prov_get_keymgmt_new(rsa_keymgmt_functions);
 }
 
+OSSL_FUNC_keymgmt_new_fn *ossl_prov_get_keymgmt_rsapss_new(void)
+{
+    return ossl_prov_get_keymgmt_new(rsapss_keymgmt_functions);
+}
+
 OSSL_FUNC_keymgmt_free_fn *ossl_prov_get_keymgmt_rsa_free(void)
 {
     return ossl_prov_get_keymgmt_free(rsa_keymgmt_functions);
@@ -42,6 +47,11 @@ OSSL_FUNC_keymgmt_export_fn *ossl_prov_get_keymgmt_rsa_export(void)
     return ossl_prov_get_keymgmt_export(rsa_keymgmt_functions);
 }
 
+OSSL_FUNC_keymgmt_export_fn *ossl_prov_get_keymgmt_rsapss_export(void)
+{
+    return ossl_prov_get_keymgmt_export(rsapss_keymgmt_functions);
+}
+
 int ossl_prov_print_rsa(BIO *out, RSA *rsa, int priv)
 {
     const char *modulus_label;