From: Daiki Ueno Date: Thu, 8 Feb 2024 06:32:37 +0000 (+0900) Subject: spki: support RSA-OAEP parameters X-Git-Tag: 3.8.5~2^2~2 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=b79e04228bd998cd438cc13cc002e92ddbbba692;p=thirdparty%2Fgnutls.git spki: support RSA-OAEP parameters 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 --- diff --git a/devel/libgnutls.abignore b/devel/libgnutls.abignore index c19dce38e1..cdc3695078 100644 --- a/devel/libgnutls.abignore +++ b/devel/libgnutls.abignore @@ -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 diff --git a/devel/symbols.last b/devel/symbols.last index 5972178b9d..e6dc0b3531 100644 --- a/devel/symbols.last +++ b/devel/symbols.last @@ -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 diff --git a/doc/Makefile.am b/doc/Makefile.am index 90fab522fe..9933d4d46f 100644 --- a/doc/Makefile.am +++ b/doc/Makefile.am @@ -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 diff --git a/doc/manpages/Makefile.am b/doc/manpages/Makefile.am index ca3336abaa..bc9f36e1da 100644 --- a/doc/manpages/Makefile.am +++ b/doc/manpages/Makefile.am @@ -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 diff --git a/lib/crypto-backend.h b/lib/crypto-backend.h index 8f11ce9036..bfdcc4278d 100644 --- a/lib/crypto-backend.h +++ b/lib/crypto-backend.h @@ -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 { diff --git a/lib/includes/gnutls/x509.h b/lib/includes/gnutls/x509.h index 44661553bc..c89255cb1b 100644 --- a/lib/includes/gnutls/x509.h +++ b/lib/includes/gnutls/x509.h @@ -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, diff --git a/lib/libgnutls.map b/lib/libgnutls.map index 87907f8128..b02babffe4 100644 --- a/lib/libgnutls.map +++ b/lib/libgnutls.map @@ -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; diff --git a/lib/nettle/pk.c b/lib/nettle/pk.c index 4ddfcffaba..b8622b3345 100644 --- a/lib/nettle/pk.c +++ b/lib/nettle/pk.c @@ -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, ¶ms->spki, sizeof(spki)); + ret = _gnutls_x509_spki_copy(&spki, ¶ms->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); diff --git a/lib/pk.c b/lib/pk.c index 95784255d6..ea788ac4b3 100644 --- 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; } diff --git a/lib/privkey.c b/lib/privkey.c index 909505cbaf..59caa6b8af 100644 --- a/lib/privkey.c +++ b/lib/privkey.c @@ -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); } /** diff --git a/lib/pubkey.c b/lib/pubkey.c index c3e4168b1f..095f6dee39 100644 --- a/lib/pubkey.c +++ b/lib/pubkey.c @@ -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(¶ms, &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(¶ms, &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, ¶ms, flags); if (ret < 0) { gnutls_assert(); + _gnutls_x509_spki_clear(¶ms); return ret; } + _gnutls_x509_spki_clear(¶ms); return 0; } @@ -2210,40 +2214,58 @@ int gnutls_pubkey_verify_hash2(gnutls_pubkey_t key, return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST); } - memcpy(¶ms, &key->params.spki, sizeof(gnutls_x509_spki_st)); + ret = _gnutls_x509_spki_copy(¶ms, &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, ¶ms); + ret = _gnutls_pk_verify(params.pk, hash, signature, + &key->params, ¶ms); + 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, ¶ms, flags); if (ret < 0) { gnutls_assert(); - return ret; + goto cleanup; } } - return 0; +cleanup: + _gnutls_x509_spki_clear(¶ms); + 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; diff --git a/lib/x509/crq.c b/lib/x509/crq.c index d24da17811..19e13623c6 100644 --- a/lib/x509/crq.c +++ b/lib/x509/crq.c @@ -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, ¶ms); 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(¶ms.spki, &tpki, sizeof(tpki)); + ret = _gnutls_x509_spki_copy(¶ms.spki, &tpki); + if (ret < 0) { + gnutls_assert(); + goto cleanup; + } ret = _gnutls_x509_check_pubkey_params(¶ms); 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(¶ms); + _gnutls_x509_spki_clear(&tpki); return ret; } diff --git a/lib/x509/privkey.c b/lib/x509/privkey.c index df784e6b40..3ff882a268 100644 --- a/lib/x509/privkey.c +++ b/lib/x509/privkey.c @@ -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; diff --git a/lib/x509/privkey_pkcs8.c b/lib/x509/privkey_pkcs8.c index ce31f412b1..635fba786f 100644 --- a/lib/x509/privkey_pkcs8.c +++ b/lib/x509/privkey_pkcs8.c @@ -992,7 +992,11 @@ skip_params: } pkey->params.algo = GNUTLS_PK_RSA_PSS; - memcpy(&pkey->params.spki, ¶ms, sizeof(gnutls_x509_spki_st)); + ret = _gnutls_x509_spki_copy(&pkey->params.spki, ¶ms); + if (ret < 0) { + gnutls_assert(); + goto error; + } ret = 0; diff --git a/lib/x509/sign.c b/lib/x509/sign.c index 5df4ba13d7..d71076c906 100644 --- a/lib/x509/sign.c +++ b/lib/x509/sign.c @@ -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_t key_params, + gnutls_x509_spki_t 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; diff --git a/lib/x509/spki.c b/lib/x509/spki.c index 61c62b0063..d65bed4220 100644 --- a/lib/x509/spki.c +++ b/lib/x509/spki.c @@ -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; +} diff --git a/lib/x509/verify.c b/lib/x509/verify.c index 6bc7cb406d..0bf41c78be 100644 --- a/lib/x509/verify.c +++ b/lib/x509/verify.c @@ -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, ¶ms); @@ -1479,7 +1480,11 @@ static int _gnutls_x509_verify_data(gnutls_sign_algorithm_t sign, goto cleanup; } } else { - memcpy(&sign_params, ¶ms.spki, sizeof(gnutls_x509_spki_st)); + ret = _gnutls_x509_spki_copy(&sign_params, ¶ms.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(¶ms); + _gnutls_x509_spki_clear(&sign_params); return ret; } diff --git a/lib/x509/x509_int.h b/lib/x509/x509_int.h index 204531f768..984dcdf1b1 100644 --- a/lib/x509/x509_int.h +++ b/lib/x509/x509_int.h @@ -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_t key_params, + gnutls_x509_spki_t 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); diff --git a/lib/x509/x509_write.c b/lib/x509/x509_write.c index db7ec29ec2..685388cb1d 100644 --- a/lib/x509/x509_write.c +++ b/lib/x509/x509_write.c @@ -1998,7 +1998,11 @@ int gnutls_x509_crt_set_spki(gnutls_x509_crt_t crt, tpki.rsa_pss_dig = spki->rsa_pss_dig; } - memcpy(¶ms.spki, &tpki, sizeof(tpki)); + ret = _gnutls_x509_spki_copy(¶ms.spki, &tpki); + if (ret < 0) { + gnutls_assert(); + goto cleanup; + } ret = _gnutls_x509_check_pubkey_params(¶ms); 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(¶ms); + _gnutls_x509_spki_clear(&tpki); return ret; }