]> git.ipfire.org Git - thirdparty/gnutls.git/commitdiff
spki: support RSA-OAEP parameters
authorDaiki Ueno <ueno@gnu.org>
Thu, 8 Feb 2024 06:32:37 +0000 (15:32 +0900)
committerDaiki Ueno <ueno@gnu.org>
Sun, 18 Feb 2024 07:12:43 +0000 (16:12 +0900)
This adds a new API gnutls_x509_spki_{get,set}_rsa_oaep_params to
retrieve and store RSA-OAEP parameters embedded in
SubjectPublicKeyInfo.

As RSA-OAEP labels are allocated, this also adds copy and clear method
on the gnutls_x509_spki_st struct and use them extensively instead of
memcpy and memset.

Signed-off-by: Daiki Ueno <ueno@gnu.org>
19 files changed:
devel/libgnutls.abignore
devel/symbols.last
doc/Makefile.am
doc/manpages/Makefile.am
lib/crypto-backend.h
lib/includes/gnutls/x509.h
lib/libgnutls.map
lib/nettle/pk.c
lib/pk.c
lib/privkey.c
lib/pubkey.c
lib/x509/crq.c
lib/x509/privkey.c
lib/x509/privkey_pkcs8.c
lib/x509/sign.c
lib/x509/spki.c
lib/x509/verify.c
lib/x509/x509_int.h
lib/x509/x509_write.c

index c19dce38e11a1c763a5d7bb7a17888e269dc61bf..cdc36950784ee025d2abea5682e00074e5d05e4a 100644 (file)
@@ -70,3 +70,8 @@ name = drbg_aes_reseed
 
 # The following should be removed in the new release, after updating the
 # abi-dump repository:
+[suppress_function]
+name = gnutls_x509_spki_get_rsa_oaep_params
+
+[suppress_function]
+name = gnutls_x509_spki_set_rsa_oaep_params
index 5972178b9daa2985f8540d0cf6857b3131cda699..e6dc0b3531cdc8c4078e2a2e6eb054e27a7aee50 100644 (file)
@@ -19,6 +19,7 @@ GNUTLS_3_7_5@GNUTLS_3_7_5
 GNUTLS_3_7_7@GNUTLS_3_7_7
 GNUTLS_3_8_1@GNUTLS_3_8_1
 GNUTLS_3_8_2@GNUTLS_3_8_2
+GNUTLS_3_8_4@GNUTLS_3_8_4
 _gnutls_global_init_skip@GNUTLS_3_4
 gnutls_aead_cipher_decrypt@GNUTLS_3_4
 gnutls_aead_cipher_decryptv2@GNUTLS_3_6_10
@@ -1272,8 +1273,10 @@ gnutls_x509_rdn_get@GNUTLS_3_4
 gnutls_x509_rdn_get_by_oid@GNUTLS_3_4
 gnutls_x509_rdn_get_oid@GNUTLS_3_4
 gnutls_x509_spki_deinit@GNUTLS_3_6_0
+gnutls_x509_spki_get_rsa_oaep_params@GNUTLS_3_8_4
 gnutls_x509_spki_get_rsa_pss_params@GNUTLS_3_6_0
 gnutls_x509_spki_init@GNUTLS_3_6_0
+gnutls_x509_spki_set_rsa_oaep_params@GNUTLS_3_8_4
 gnutls_x509_spki_set_rsa_pss_params@GNUTLS_3_6_0
 gnutls_x509_tlsfeatures_add@GNUTLS_3_4
 gnutls_x509_tlsfeatures_check_crt@GNUTLS_3_4
index 90fab522fe824e2ad1c9944165ecef498ff5a16a..9933d4d46f45417e6b5c233f13f249699bc6a34a 100644 (file)
@@ -2924,10 +2924,14 @@ FUNCS += functions/gnutls_x509_rdn_get_oid
 FUNCS += functions/gnutls_x509_rdn_get_oid.short
 FUNCS += functions/gnutls_x509_spki_deinit
 FUNCS += functions/gnutls_x509_spki_deinit.short
+FUNCS += functions/gnutls_x509_spki_get_rsa_oaep_params
+FUNCS += functions/gnutls_x509_spki_get_rsa_oaep_params.short
 FUNCS += functions/gnutls_x509_spki_get_rsa_pss_params
 FUNCS += functions/gnutls_x509_spki_get_rsa_pss_params.short
 FUNCS += functions/gnutls_x509_spki_init
 FUNCS += functions/gnutls_x509_spki_init.short
+FUNCS += functions/gnutls_x509_spki_set_rsa_oaep_params
+FUNCS += functions/gnutls_x509_spki_set_rsa_oaep_params.short
 FUNCS += functions/gnutls_x509_spki_set_rsa_pss_params
 FUNCS += functions/gnutls_x509_spki_set_rsa_pss_params.short
 FUNCS += functions/gnutls_x509_tlsfeatures_add
index ca3336abaa56388150849d461dbeab664139598b..bc9f36e1da7ea2d04894a0960b7e32beeca056d9 100644 (file)
@@ -1308,8 +1308,10 @@ APIMANS += gnutls_x509_rdn_get2.3
 APIMANS += gnutls_x509_rdn_get_by_oid.3
 APIMANS += gnutls_x509_rdn_get_oid.3
 APIMANS += gnutls_x509_spki_deinit.3
+APIMANS += gnutls_x509_spki_get_rsa_oaep_params.3
 APIMANS += gnutls_x509_spki_get_rsa_pss_params.3
 APIMANS += gnutls_x509_spki_init.3
+APIMANS += gnutls_x509_spki_set_rsa_oaep_params.3
 APIMANS += gnutls_x509_spki_set_rsa_pss_params.3
 APIMANS += gnutls_x509_tlsfeatures_add.3
 APIMANS += gnutls_x509_tlsfeatures_check_crt.3
index 8f11ce9036934e4dfea8e248658509d99df8ae5a..bfdcc4278dd1fb15e7e360bc566b1b5c9e8128a8 100644 (file)
@@ -188,6 +188,12 @@ typedef struct gnutls_x509_spki_st {
        /* the size of salt used by RSA-PSS */
        unsigned int salt_size;
 
+       /* the digest used by RSA-OAEP */
+       gnutls_digest_algorithm_t rsa_oaep_dig;
+
+       /* the optional label used by RSA-OAEP */
+       gnutls_datum_t rsa_oaep_label;
+
        /* if non-zero, the legacy value for PKCS#7 signatures will be
         * written for RSA signatures. */
        unsigned int legacy;
@@ -200,6 +206,10 @@ typedef struct gnutls_x509_spki_st {
        unsigned int flags;
 } gnutls_x509_spki_st;
 
+int _gnutls_x509_spki_copy(gnutls_x509_spki_st *dst,
+                          const gnutls_x509_spki_st *src);
+void _gnutls_x509_spki_clear(gnutls_x509_spki_st *spki);
+
 #define GNUTLS_MAX_PK_PARAMS 16
 
 typedef struct {
index 44661553bc616df07ec186d05b611fbab8bf5b03..c89255cb1bbaaac35b63108bba43dae161caca00 100644 (file)
@@ -410,6 +410,14 @@ void gnutls_x509_spki_set_rsa_pss_params(gnutls_x509_spki_t spki,
                                         gnutls_digest_algorithm_t dig,
                                         unsigned int salt_size);
 
+int gnutls_x509_spki_set_rsa_oaep_params(gnutls_x509_spki_t spki,
+                                        gnutls_digest_algorithm_t dig,
+                                        const gnutls_datum_t *label);
+
+int gnutls_x509_spki_get_rsa_oaep_params(gnutls_x509_spki_t spki,
+                                        gnutls_digest_algorithm_t *dig,
+                                        gnutls_datum_t *label);
+
 int gnutls_x509_crt_get_pk_algorithm(gnutls_x509_crt_t cert,
                                     unsigned int *bits);
 int gnutls_x509_crt_set_spki(gnutls_x509_crt_t crt,
index 87907f812858644f92f04cea2c41f910c4cdb8ec..b02babffe4304cc7a6d339328f50e34b5e0e77b8 100644 (file)
@@ -1432,6 +1432,15 @@ GNUTLS_3_8_2
        *;
 } GNUTLS_3_8_1;
 
+GNUTLS_3_8_4
+{
+ global:
+       gnutls_x509_spki_get_rsa_oaep_params;
+       gnutls_x509_spki_set_rsa_oaep_params;
+ local:
+       *;
+} GNUTLS_3_8_2;
+
 GNUTLS_FIPS140_3_4 {
   global:
        gnutls_cipher_self_test;
index 4ddfcffaba7d06906ecdfd4ab16ab2916ede3b54..b8622b3345ac7db8ea431d14d51d0716f8124b88 100644 (file)
@@ -2386,7 +2386,11 @@ static int pct_test(gnutls_pk_algorithm_t algo,
        gnutls_x509_spki_st spki;
        gnutls_fips140_context_t context;
 
-       memcpy(&spki, &params->spki, sizeof(spki));
+       ret = _gnutls_x509_spki_copy(&spki, &params->spki);
+       if (ret < 0) {
+               gnutls_assert();
+               goto cleanup;
+       }
 
        if (algo == GNUTLS_PK_DSA || algo == GNUTLS_PK_EC) {
                unsigned hash_len;
@@ -2537,6 +2541,7 @@ cleanup:
        if (ret == GNUTLS_E_PK_GENERATION_ERROR) {
                _gnutls_switch_lib_state(LIB_STATE_ERROR);
        }
+       gnutls_x509_spki_clear(&spki);
        gnutls_free(gen_data);
        gnutls_free(sig.data);
        gnutls_free(tmp.data);
index 95784255d6f7c4fcd953961a6db178cc53ca66de..ea788ac4b389b1122749239994631ab6d9f6dda4 100644 (file)
--- a/lib/pk.c
+++ b/lib/pk.c
@@ -506,7 +506,10 @@ int _gnutls_pk_params_copy(gnutls_pk_params_st *dst,
        }
        dst->palgo = src->palgo;
 
-       memcpy(&dst->spki, &src->spki, sizeof(gnutls_x509_spki_st));
+       if (_gnutls_x509_spki_copy(&dst->spki, &src->spki) < 0) {
+               gnutls_assert();
+               goto fail;
+       }
 
        return 0;
 
@@ -529,6 +532,7 @@ void gnutls_pk_params_release(gnutls_pk_params_st *p)
        }
        gnutls_free(p->raw_priv.data);
        gnutls_free(p->raw_pub.data);
+       _gnutls_x509_spki_clear(&p->spki);
 
        p->params_nr = 0;
 }
index 909505cbafe34dc188423b23600ec4abe43ae01f..59caa6b8aff079657113cb934ea646e0c18961b0 100644 (file)
@@ -163,7 +163,11 @@ static int privkey_to_pubkey(gnutls_pk_algorithm_t pk,
        pub->curve = priv->curve;
        pub->gost_params = priv->gost_params;
        pub->qbits = priv->qbits;
-       memcpy(&pub->spki, &priv->spki, sizeof(gnutls_x509_spki_st));
+       ret = _gnutls_x509_spki_copy(&pub->spki, &priv->spki);
+       if (ret < 0) {
+               gnutls_assert();
+               goto cleanup;
+       }
 
        switch (pk) {
        case GNUTLS_PK_RSA_PSS:
@@ -344,8 +348,8 @@ int _gnutls_privkey_get_spki_params(gnutls_privkey_t key,
        case GNUTLS_PRIVKEY_EXT:
                break;
        case GNUTLS_PRIVKEY_X509:
-               _gnutls_x509_privkey_get_spki_params(key->key.x509, params);
-               return 0;
+               return _gnutls_x509_privkey_get_spki_params(key->key.x509,
+                                                           params);
        default:
                gnutls_assert();
                return GNUTLS_E_INVALID_REQUEST;
@@ -1929,9 +1933,7 @@ int gnutls_privkey_get_spki(gnutls_privkey_t privkey, gnutls_x509_spki_t spki,
        if (p->pk == GNUTLS_PK_UNKNOWN)
                return gnutls_assert_val(GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE);
 
-       memcpy(spki, p, sizeof(gnutls_x509_spki_st));
-
-       return 0;
+       return _gnutls_x509_spki_copy(spki, p);
 }
 
 /**
index c3e4168b1f87f2d3de4e7ace8a0967f75a5f2075..095f6dee396919dc03b85c408ae64379f049cb93 100644 (file)
@@ -2142,8 +2142,6 @@ int gnutls_pubkey_verify_data2(gnutls_pubkey_t pubkey,
        if (flags & GNUTLS_VERIFY_USE_TLS1_RSA)
                return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
 
-       memcpy(&params, &pubkey->params.spki, sizeof(gnutls_x509_spki_st));
-
        se = _gnutls_sign_to_entry(algo);
        if (se == NULL)
                return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
@@ -2152,22 +2150,28 @@ int gnutls_pubkey_verify_data2(gnutls_pubkey_t pubkey,
        if (ret < 0)
                return gnutls_assert_val(ret);
 
+       me = hash_to_entry(se->hash);
+       if (me == NULL && !_gnutls_pk_is_not_prehashed(se->pk))
+               return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
+
+       ret = _gnutls_x509_spki_copy(&params, &pubkey->params.spki);
+       if (ret < 0)
+               return gnutls_assert_val(ret);
+
        params.pk = se->pk;
        if (flags & GNUTLS_VERIFY_RSA_PSS_FIXED_SALT_LENGTH) {
                params.flags |= GNUTLS_PK_FLAG_RSA_PSS_FIXED_SALT_LENGTH;
        }
 
-       me = hash_to_entry(se->hash);
-       if (me == NULL && !_gnutls_pk_is_not_prehashed(se->pk))
-               return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
-
        ret = pubkey_verify_data(se, me, data, signature, &pubkey->params,
                                 &params, flags);
        if (ret < 0) {
                gnutls_assert();
+               _gnutls_x509_spki_clear(&params);
                return ret;
        }
 
+       _gnutls_x509_spki_clear(&params);
        return 0;
 }
 
@@ -2210,40 +2214,58 @@ int gnutls_pubkey_verify_hash2(gnutls_pubkey_t key,
                return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
        }
 
-       memcpy(&params, &key->params.spki, sizeof(gnutls_x509_spki_st));
+       ret = _gnutls_x509_spki_copy(&params, &key->params.spki);
+       if (ret < 0)
+               return gnutls_assert_val(ret);
 
        if (flags & GNUTLS_VERIFY_USE_TLS1_RSA) {
-               if (!GNUTLS_PK_IS_RSA(key->params.algo))
-                       return gnutls_assert_val(
-                               GNUTLS_E_INCOMPATIBLE_SIG_WITH_KEY);
+               if (!GNUTLS_PK_IS_RSA(key->params.algo)) {
+                       gnutls_assert();
+                       ret = GNUTLS_E_INCOMPATIBLE_SIG_WITH_KEY;
+                       goto cleanup;
+               }
                params.pk = GNUTLS_PK_RSA;
                /* we do not check for insecure algorithms with this flag */
-               return _gnutls_pk_verify(params.pk, hash, signature,
-                                        &key->params, &params);
+               ret = _gnutls_pk_verify(params.pk, hash, signature,
+                                       &key->params, &params);
+               if (ret < 0) {
+                       gnutls_assert();
+                       goto cleanup;
+               }
        } else {
                se = _gnutls_sign_to_entry(algo);
-               if (se == NULL)
-                       return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
+               if (se == NULL) {
+                       gnutls_assert();
+                       ret = GNUTLS_E_INVALID_REQUEST;
+                       goto cleanup;
+               }
 
                ret = pubkey_supports_sig(key, se);
-               if (ret < 0)
-                       return gnutls_assert_val(ret);
+               if (ret < 0) {
+                       gnutls_assert();
+                       goto cleanup;
+               }
 
                params.pk = se->pk;
 
                me = hash_to_entry(se->hash);
-               if (me == NULL && !_gnutls_pk_is_not_prehashed(se->pk))
-                       return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
+               if (me == NULL && !_gnutls_pk_is_not_prehashed(se->pk)) {
+                       gnutls_assert();
+                       ret = GNUTLS_E_INVALID_REQUEST;
+                       goto cleanup;
+               }
 
                ret = pubkey_verify_hashed_data(se, me, hash, signature,
                                                &key->params, &params, flags);
                if (ret < 0) {
                        gnutls_assert();
-                       return ret;
+                       goto cleanup;
                }
        }
 
-       return 0;
+cleanup:
+       _gnutls_x509_spki_clear(&params);
+       return ret;
 }
 
 /**
@@ -2821,9 +2843,7 @@ int gnutls_pubkey_get_spki(gnutls_pubkey_t pubkey, gnutls_x509_spki_t spki,
        if (p->pk == GNUTLS_PK_UNKNOWN)
                return gnutls_assert_val(GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE);
 
-       memcpy(spki, p, sizeof(gnutls_x509_spki_st));
-
-       return 0;
+       return _gnutls_x509_spki_copy(spki, p);
 }
 
 /**
@@ -2843,6 +2863,8 @@ int gnutls_pubkey_get_spki(gnutls_pubkey_t pubkey, gnutls_x509_spki_t spki,
 int gnutls_pubkey_set_spki(gnutls_pubkey_t pubkey,
                           const gnutls_x509_spki_t spki, unsigned int flags)
 {
+       int ret;
+
        if (pubkey == NULL) {
                gnutls_assert();
                return GNUTLS_E_INVALID_REQUEST;
@@ -2851,7 +2873,9 @@ int gnutls_pubkey_set_spki(gnutls_pubkey_t pubkey,
        if (!_gnutls_pk_are_compat(pubkey->params.algo, spki->pk))
                return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
 
-       memcpy(&pubkey->params.spki, spki, sizeof(gnutls_x509_spki_st));
+       ret = _gnutls_x509_spki_copy(&pubkey->params.spki, spki);
+       if (ret < 0)
+               return gnutls_assert_val(ret);
 
        pubkey->params.algo = spki->pk;
 
index d24da17811d848b1f42ee9cd4eb21922e7d0e366..19e13623c6bd5cdcea06a149e5acc7a50c829dff 100644 (file)
@@ -2880,6 +2880,8 @@ int gnutls_x509_crq_set_spki(gnutls_x509_crq_t crq,
                return GNUTLS_E_INVALID_REQUEST;
        }
 
+       memset(&tpki, 0, sizeof(gnutls_x509_spki_st));
+
        ret = _gnutls_x509_crq_get_mpis(crq, &params);
        if (ret < 0) {
                gnutls_assert();
@@ -2905,8 +2907,6 @@ int gnutls_x509_crq_set_spki(gnutls_x509_crq_t crq,
                goto cleanup;
        }
 
-       memset(&tpki, 0, sizeof(gnutls_x509_spki_st));
-
        if (crq_pk == GNUTLS_PK_RSA) {
                const mac_entry_st *me;
 
@@ -2942,7 +2942,11 @@ int gnutls_x509_crq_set_spki(gnutls_x509_crq_t crq,
                tpki.rsa_pss_dig = spki->rsa_pss_dig;
        }
 
-       memcpy(&params.spki, &tpki, sizeof(tpki));
+       ret = _gnutls_x509_spki_copy(&params.spki, &tpki);
+       if (ret < 0) {
+               gnutls_assert();
+               goto cleanup;
+       }
        ret = _gnutls_x509_check_pubkey_params(&params);
        if (ret < 0) {
                gnutls_assert();
@@ -2962,5 +2966,6 @@ int gnutls_x509_crq_set_spki(gnutls_x509_crq_t crq,
        ret = 0;
 cleanup:
        gnutls_pk_params_release(&params);
+       _gnutls_x509_spki_clear(&tpki);
        return ret;
 }
index df784e6b403b778bc272e0bbf5f04b02685058b5..3ff882a2687b4e1d57ce0a9563adba96874c69b3 100644 (file)
@@ -1402,10 +1402,10 @@ int gnutls_x509_privkey_get_pk_algorithm2(gnutls_x509_privkey_t key,
        return key->params.algo;
 }
 
-void _gnutls_x509_privkey_get_spki_params(gnutls_x509_privkey_t key,
-                                         gnutls_x509_spki_st *params)
+int _gnutls_x509_privkey_get_spki_params(gnutls_x509_privkey_t key,
+                                        gnutls_x509_spki_st *params)
 {
-       memcpy(params, &key->params.spki, sizeof(gnutls_x509_spki_st));
+       return _gnutls_x509_spki_copy(params, &key->params.spki);
 }
 
 /**
@@ -1430,9 +1430,7 @@ int gnutls_x509_privkey_get_spki(gnutls_x509_privkey_t key,
        if (key->params.spki.pk == GNUTLS_PK_UNKNOWN)
                return gnutls_assert_val(GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE);
 
-       _gnutls_x509_privkey_get_spki_params(key, spki);
-
-       return 0;
+       return _gnutls_x509_privkey_get_spki_params(key, spki);
 }
 
 /**
@@ -1462,12 +1460,15 @@ int gnutls_x509_privkey_set_spki(gnutls_x509_privkey_t key,
                return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
 
        memcpy(&tparams, &key->params, sizeof(gnutls_pk_params_st));
+       /* No need for a deep copy, as this is only for one time check */
        memcpy(&tparams.spki, spki, sizeof(gnutls_x509_spki_st));
        ret = _gnutls_x509_check_pubkey_params(&tparams);
        if (ret < 0)
                return gnutls_assert_val(ret);
 
-       memcpy(&key->params.spki, spki, sizeof(gnutls_x509_spki_st));
+       ret = _gnutls_x509_spki_copy(&key->params.spki, spki);
+       if (ret < 0)
+               return gnutls_assert_val(ret);
 
        key->params.algo = spki->pk;
 
index ce31f412b1ac0010440453f67ce3d640d5468f68..635fba786fb4fd50a804fabc80185ea3893aebfe 100644 (file)
@@ -992,7 +992,11 @@ skip_params:
        }
 
        pkey->params.algo = GNUTLS_PK_RSA_PSS;
-       memcpy(&pkey->params.spki, &params, sizeof(gnutls_x509_spki_st));
+       ret = _gnutls_x509_spki_copy(&pkey->params.spki, &params);
+       if (ret < 0) {
+               gnutls_assert();
+               goto error;
+       }
 
        ret = 0;
 
index 5df4ba13d77a1acdf70bb389f16dc03a9540422a..d71076c9066af04e9aa2f83d85ae043ffa766c08 100644 (file)
@@ -49,8 +49,8 @@ int _gnutls_x509_get_tbs(asn1_node cert, const char *tbs_name,
 }
 
 int _gnutls_x509_crt_get_spki_params(gnutls_x509_crt_t crt,
-                                    const gnutls_x509_spki_st *key_params,
-                                    gnutls_x509_spki_st *params)
+                                    const gnutls_x509_spki_key_params,
+                                    gnutls_x509_spki_params)
 {
        int result;
        gnutls_x509_spki_st crt_params;
@@ -77,9 +77,13 @@ int _gnutls_x509_crt_get_spki_params(gnutls_x509_crt_t crt,
                        gnutls_assert();
                        return GNUTLS_E_CERTIFICATE_ERROR;
                }
-               memcpy(params, &crt_params, sizeof(gnutls_x509_spki_st));
+               result = _gnutls_x509_spki_copy(params, &crt_params);
+               if (result < 0)
+                       return gnutls_assert_val(result);
        } else {
-               memcpy(params, key_params, sizeof(gnutls_x509_spki_st));
+               result = _gnutls_x509_spki_copy(params, key_params);
+               if (result < 0)
+                       return gnutls_assert_val(result);
        }
 
        return 0;
index 61c62b006379ed36fed4517b0da9f631e4dd0edf..d65bed4220839a313f717cb5f15de7797b21b0a4 100644 (file)
@@ -68,9 +68,24 @@ int gnutls_x509_spki_init(gnutls_x509_spki_t *spki)
  **/
 void gnutls_x509_spki_deinit(gnutls_x509_spki_t spki)
 {
+       _gnutls_x509_spki_clear(spki);
        gnutls_free(spki);
 }
 
+int _gnutls_x509_spki_copy(gnutls_x509_spki_st *dst,
+                          const gnutls_x509_spki_st *src)
+{
+       memcpy(dst, src, sizeof(*src));
+       return _gnutls_set_datum(&dst->rsa_oaep_label, src->rsa_oaep_label.data,
+                                src->rsa_oaep_label.size);
+}
+
+void _gnutls_x509_spki_clear(gnutls_x509_spki_st *spki)
+{
+       gnutls_free(spki->rsa_oaep_label.data);
+       memset(spki, 0, sizeof(*spki));
+}
+
 /**
  * gnutls_x509_spki_set_rsa_pss_params:
  * @spki: the SubjectPublicKeyInfo structure
@@ -124,3 +139,74 @@ int gnutls_x509_spki_get_rsa_pss_params(gnutls_x509_spki_t spki,
 
        return 0;
 }
+
+/**
+ * gnutls_x509_spki_set_rsa_oaep_params:
+ * @spki: the SubjectPublicKeyInfo structure
+ * @dig: a digest algorithm of type #gnutls_digest_algorithm_t
+ * @label: optional label
+ *
+ * This function will set the public key parameters for
+ * an RSA-OAEP algorithm, in the SubjectPublicKeyInfo structure.
+ *
+ * Returns: zero if the parameters are present or a negative
+ *     value on error.
+ *
+ * Since: 3.8.4
+ *
+ **/
+int gnutls_x509_spki_set_rsa_oaep_params(gnutls_x509_spki_t spki,
+                                        gnutls_digest_algorithm_t dig,
+                                        const gnutls_datum_t *label)
+{
+       spki->pk = GNUTLS_PK_RSA_OAEP;
+       spki->rsa_oaep_dig = dig;
+       if (label) {
+               int ret;
+
+               ret = _gnutls_set_datum(&spki->rsa_oaep_label, label->data,
+                                       label->size);
+               if (ret < 0)
+                       return gnutls_assert_val(ret);
+       }
+       return 0;
+}
+
+/**
+ * gnutls_x509_spki_get_rsa_oaep_params:
+ * @spki: the SubjectPublicKeyInfo structure
+ * @dig: if non-NULL, it will hold the digest algorithm
+ * @label: if non-NULL, it will hold the pointer to label
+ *
+ * This function will get the public key algorithm parameters
+ * of RSA-OAEP type.
+ *
+ * Returns: zero if the parameters are present or a negative
+ *     value on error.
+ *
+ * Since: 3.8.4
+ *
+ **/
+int gnutls_x509_spki_get_rsa_oaep_params(gnutls_x509_spki_t spki,
+                                        gnutls_digest_algorithm_t *dig,
+                                        gnutls_datum_t *label)
+{
+       if (spki->pk == 0)
+               return gnutls_assert_val(GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE);
+
+       if (spki->pk != GNUTLS_PK_RSA_OAEP)
+               return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
+
+       if (dig)
+               *dig = spki->rsa_oaep_dig;
+       if (label) {
+               int ret;
+
+               ret = _gnutls_set_datum(label, spki->rsa_oaep_label.data,
+                                       spki->rsa_oaep_label.size);
+               if (ret < 0)
+                       return gnutls_assert_val(ret);
+       }
+
+       return 0;
+}
index 6bc7cb406df3c98985807b1cf06c43ea25edc159..0bf41c78be706c315f2749cdaa243323cba09398 100644 (file)
@@ -1446,6 +1446,7 @@ static int _gnutls_x509_verify_data(gnutls_sign_algorithm_t sign,
        gnutls_x509_spki_st sign_params;
        const gnutls_sign_entry_st *se;
 
+       memset(&sign_params, 0, sizeof(sign_params));
        /* Read the MPI parameters from the issuer's certificate.
         */
        ret = _gnutls_x509_crt_get_mpis(issuer, &params);
@@ -1479,7 +1480,11 @@ static int _gnutls_x509_verify_data(gnutls_sign_algorithm_t sign,
                        goto cleanup;
                }
        } else {
-               memcpy(&sign_params, &params.spki, sizeof(gnutls_x509_spki_st));
+               ret = _gnutls_x509_spki_copy(&sign_params, &params.spki);
+               if (ret < 0) {
+                       gnutls_assert();
+                       goto cleanup;
+               }
 
                sign_params.pk = se->pk;
                if (sign_params.pk == GNUTLS_PK_RSA_PSS)
@@ -1496,6 +1501,7 @@ cleanup:
        /* release all allocated MPIs
         */
        gnutls_pk_params_release(&params);
+       _gnutls_x509_spki_clear(&sign_params);
 
        return ret;
 }
index 204531f768613ef48e35c71e0f64eb6b4445377e..984dcdf1b14f94ff52011f35ce81a70d326df295 100644 (file)
@@ -169,8 +169,8 @@ int _gnutls_x509_pkix_sign(asn1_node src, const char *src_name,
                           gnutls_x509_crt_t issuer,
                           gnutls_privkey_t issuer_key);
 int _gnutls_x509_crt_get_spki_params(gnutls_x509_crt_t issuer,
-                                    const gnutls_x509_spki_st *key_params,
-                                    gnutls_x509_spki_st *params);
+                                    const gnutls_x509_spki_key_params,
+                                    gnutls_x509_spki_params);
 
 #define map_errs_to_zero(x) ((x) < 0 ? 0 : (x))
 
@@ -255,8 +255,8 @@ int _gnutls_x509_read_gost_params(uint8_t *der, int dersize,
 
 int _gnutls_asn1_encode_privkey(asn1_node *c2, gnutls_pk_params_st *params);
 
-void _gnutls_x509_privkey_get_spki_params(gnutls_x509_privkey_t key,
-                                         gnutls_x509_spki_st *params);
+int _gnutls_x509_privkey_get_spki_params(gnutls_x509_privkey_t key,
+                                        gnutls_x509_spki_st *params);
 
 int _gnutls_x509_read_rsa_pss_params(uint8_t *der, int dersize,
                                     gnutls_x509_spki_st *params);
index db7ec29ec26f2e29a10d0c01ee5ce5992ef97f46..685388cb1dc2bb42c2061407277d847b0a75050c 100644 (file)
@@ -1998,7 +1998,11 @@ int gnutls_x509_crt_set_spki(gnutls_x509_crt_t crt,
                tpki.rsa_pss_dig = spki->rsa_pss_dig;
        }
 
-       memcpy(&params.spki, &tpki, sizeof(tpki));
+       ret = _gnutls_x509_spki_copy(&params.spki, &tpki);
+       if (ret < 0) {
+               gnutls_assert();
+               goto cleanup;
+       }
        ret = _gnutls_x509_check_pubkey_params(&params);
        if (ret < 0) {
                gnutls_assert();
@@ -2019,5 +2023,6 @@ int gnutls_x509_crt_set_spki(gnutls_x509_crt_t crt,
        ret = 0;
 cleanup:
        gnutls_pk_params_release(&params);
+       _gnutls_x509_spki_clear(&tpki);
        return ret;
 }