# 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
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
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
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
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
/* 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;
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 {
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,
*;
} 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;
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;
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);
}
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;
}
gnutls_free(p->raw_priv.data);
gnutls_free(p->raw_pub.data);
+ _gnutls_x509_spki_clear(&p->spki);
p->params_nr = 0;
}
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:
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;
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);
}
/**
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);
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;
}
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;
}
/**
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);
}
/**
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;
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;
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();
goto cleanup;
}
- memset(&tpki, 0, sizeof(gnutls_x509_spki_st));
-
if (crq_pk == GNUTLS_PK_RSA) {
const mac_entry_st *me;
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();
ret = 0;
cleanup:
gnutls_pk_params_release(¶ms);
+ _gnutls_x509_spki_clear(&tpki);
return ret;
}
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);
}
/**
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);
}
/**
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;
}
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;
}
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;
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;
**/
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
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;
+}
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);
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)
/* release all allocated MPIs
*/
gnutls_pk_params_release(¶ms);
+ _gnutls_x509_spki_clear(&sign_params);
return ret;
}
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))
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);
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();
ret = 0;
cleanup:
gnutls_pk_params_release(¶ms);
+ _gnutls_x509_spki_clear(&tpki);
return ret;
}