summaryrefslogtreecommitdiff
path: root/lib/x509
diff options
context:
space:
mode:
authorNikos Mavrogiannopoulos <nmav@redhat.com>2017-07-24 10:12:54 +0200
committerNikos Mavrogiannopoulos <nmav@redhat.com>2017-08-03 11:57:52 +0200
commit67fac0f4ccb43c983c110060639de95168ca04a1 (patch)
tree9b1d8a5d10039a2ba9657d630652b9e10a551426 /lib/x509
parent7ee95dc1c31133f6dde92f4b104359061bfeb700 (diff)
downloadgnutls-67fac0f4ccb43c983c110060639de95168ca04a1.tar.gz
Clarified the purpose of the spki params related functions
_gnutls_privkey_get_sign_params was renamed to _gnutls_privkey_get_spki_params, _gnutls_privkey_update_sign_params to _gnutls_privkey_update_spki_params, and the dig entry of gnutls_x509_spki_st was renamed to rsa_pss_dig. The reason is that there could be a confusion on the purpose of the 'dig' entry, as it could be assumed to be the signature's hash algorithm in the general case. That could not be because the SPKI parameters do not contain it for any other algorithm than RSA-PSS. As such, make a logical separation from SPKI reading functions with the signature reading functions and try to use the gnutls_sign_entry_st when signature information is required. Signed-off-by: Nikos Mavrogiannopoulos <nmav@redhat.com>
Diffstat (limited to 'lib/x509')
-rw-r--r--lib/x509/common.c2
-rw-r--r--lib/x509/crq.c28
-rw-r--r--lib/x509/key_decode.c4
-rw-r--r--lib/x509/key_encode.c2
-rw-r--r--lib/x509/mpi.c100
-rw-r--r--lib/x509/output.c8
-rw-r--r--lib/x509/pkcs7.c28
-rw-r--r--lib/x509/privkey.c8
-rw-r--r--lib/x509/sign.c21
-rw-r--r--lib/x509/spki.c14
-rw-r--r--lib/x509/verify.c17
-rw-r--r--lib/x509/x509.c4
-rw-r--r--lib/x509/x509_int.h37
-rw-r--r--lib/x509/x509_write.c10
14 files changed, 169 insertions, 114 deletions
diff --git a/lib/x509/common.c b/lib/x509/common.c
index b1be062c54..bd78b24b35 100644
--- a/lib/x509/common.c
+++ b/lib/x509/common.c
@@ -1285,7 +1285,7 @@ _gnutls_x509_get_signature_algorithm(ASN1_TYPE src, const char *src_name)
_gnutls_free_datum(&der);
if (result == 0)
- result = gnutls_pk_to_sign(params.pk, params.dig);
+ result = gnutls_pk_to_sign(params.pk, params.rsa_pss_dig);
else if (result == GNUTLS_E_UNKNOWN_ALGORITHM)
result = GNUTLS_SIGN_UNKNOWN;
} else {
diff --git a/lib/x509/crq.c b/lib/x509/crq.c
index fc90e3296d..8fa172ac14 100644
--- a/lib/x509/crq.c
+++ b/lib/x509/crq.c
@@ -1,6 +1,7 @@
/*
* Copyright (C) 2003-2016 Free Software Foundation, Inc.
* Copyright (C) 2012-2016 Nikos Mavrogiannopoulos
+ * Copyright (C) 2016-2017 Red Hat, Inc.
*
* Author: Nikos Mavrogiannopoulos
*
@@ -1325,13 +1326,13 @@ gnutls_x509_crq_get_pk_algorithm2(gnutls_x509_crq_t crq,
spki->pk = result;
- result = _gnutls_x509_crq_read_sign_params(crq, &params);
+ result = _gnutls_x509_crq_read_spki_params(crq, &params);
if (result < 0) {
gnutls_assert();
return result;
}
- spki->dig = params.dig;
+ spki->rsa_pss_dig = params.rsa_pss_dig;
spki->salt_size = params.salt_size;
return spki->pk;
@@ -2822,6 +2823,7 @@ gnutls_x509_crq_privkey_sign(gnutls_x509_crq_t crq, gnutls_privkey_t key,
gnutls_datum_t tbs;
gnutls_pk_algorithm_t pk;
gnutls_x509_spki_st params;
+ const gnutls_sign_entry_st *se;
if (crq == NULL) {
gnutls_assert();
@@ -2838,14 +2840,14 @@ gnutls_x509_crq_privkey_sign(gnutls_x509_crq_t crq, gnutls_privkey_t key,
}
}
- result = _gnutls_privkey_get_sign_params(key, &params);
+ result = _gnutls_privkey_get_spki_params(key, &params);
if (result < 0) {
gnutls_assert();
return result;
}
pk = gnutls_privkey_get_pk_algorithm(key, NULL);
- result = _gnutls_privkey_update_sign_params(key, pk, dig, 0, &params);
+ result = _gnutls_privkey_update_spki_params(key, pk, dig, 0, &params);
if (result < 0) {
gnutls_assert();
return result;
@@ -2862,7 +2864,11 @@ gnutls_x509_crq_privkey_sign(gnutls_x509_crq_t crq, gnutls_privkey_t key,
return result;
}
- result = privkey_sign_and_hash_data(key, _gnutls_pk_to_sign_entry(params.pk, dig),
+ se = _gnutls_pk_to_sign_entry(params.pk, dig);
+ if (se == NULL)
+ return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
+
+ result = privkey_sign_and_hash_data(key, se,
&tbs, &signature, &params);
gnutls_free(tbs.data);
@@ -2888,7 +2894,7 @@ gnutls_x509_crq_privkey_sign(gnutls_x509_crq_t crq, gnutls_privkey_t key,
*/
result =
_gnutls_x509_write_sign_params(crq->crq, "signatureAlgorithm",
- &params);
+ se, &params);
if (result < 0) {
gnutls_assert();
return result;
@@ -3244,7 +3250,7 @@ gnutls_x509_crq_set_pk_algorithm(gnutls_x509_crq_t crq,
if (crq_pk == GNUTLS_PK_RSA) {
const mac_entry_st *me;
- me = hash_to_entry(spki->dig);
+ me = hash_to_entry(spki->rsa_pss_dig);
if (unlikely(me == NULL)) {
gnutls_assert();
return GNUTLS_E_INVALID_REQUEST;
@@ -3252,7 +3258,7 @@ gnutls_x509_crq_set_pk_algorithm(gnutls_x509_crq_t crq,
memset(&params, 0, sizeof(gnutls_x509_spki_st));
params.pk = spki->pk;
- params.dig = spki->dig;
+ params.rsa_pss_dig = spki->rsa_pss_dig;
/* If salt size is zero, find the optimal salt size. */
if (spki->salt_size == 0) {
@@ -3262,13 +3268,13 @@ gnutls_x509_crq_set_pk_algorithm(gnutls_x509_crq_t crq,
} else
params.salt_size = spki->salt_size;
} else if (crq_pk == GNUTLS_PK_RSA_PSS) {
- result = _gnutls_x509_crq_read_sign_params(crq, &params);
+ result = _gnutls_x509_crq_read_spki_params(crq, &params);
if (result < 0) {
gnutls_assert();
return result;
}
- if (params.dig != spki->dig ||
+ if (params.rsa_pss_dig != spki->rsa_pss_dig ||
params.salt_size > spki->salt_size) {
gnutls_assert();
return GNUTLS_E_INVALID_REQUEST;
@@ -3277,7 +3283,7 @@ gnutls_x509_crq_set_pk_algorithm(gnutls_x509_crq_t crq,
params.salt_size = spki->salt_size;
}
- result = _gnutls_x509_write_sign_params(crq->crq,
+ result = _gnutls_x509_write_spki_params(crq->crq,
"certificationRequestInfo."
"subjectPKInfo."
"algorithm",
diff --git a/lib/x509/key_decode.c b/lib/x509/key_decode.c
index a9b59d125b..7e9d05a887 100644
--- a/lib/x509/key_decode.c
+++ b/lib/x509/key_decode.c
@@ -346,7 +346,7 @@ _gnutls_x509_read_rsa_pss_params(uint8_t * der, int dersize,
memset(params, 0, sizeof(gnutls_x509_spki_st));
params->pk = GNUTLS_PK_RSA_PSS;
- params->dig = digest;
+ params->rsa_pss_dig = digest;
result = _gnutls_x509_read_uint(spk, "saltLength", &params->salt_size);
if (result == GNUTLS_E_ASN1_ELEMENT_NOT_FOUND ||
@@ -451,7 +451,7 @@ int _gnutls_x509_check_pubkey_params(gnutls_pk_algorithm_t algo,
switch (algo) {
case GNUTLS_PK_RSA_PSS: {
unsigned bits = pubkey_to_bits(algo, params);
- const mac_entry_st *me = hash_to_entry(params->sign.dig);
+ const mac_entry_st *me = hash_to_entry(params->sign.rsa_pss_dig);
size_t hash_size;
if (unlikely(me == NULL))
diff --git a/lib/x509/key_encode.c b/lib/x509/key_encode.c
index 58b1362c58..c1072cf08f 100644
--- a/lib/x509/key_encode.c
+++ b/lib/x509/key_encode.c
@@ -344,7 +344,7 @@ _gnutls_x509_write_rsa_pss_params(gnutls_x509_spki_st *params,
goto cleanup;
}
- oid = gnutls_digest_get_oid(params->dig);
+ oid = gnutls_digest_get_oid(params->rsa_pss_dig);
if ((result = asn1_write_value(spk, "hashAlgorithm.algorithm", oid, 1))
!= ASN1_SUCCESS) {
diff --git a/lib/x509/mpi.c b/lib/x509/mpi.c
index 1f562229e3..9b3ded189e 100644
--- a/lib/x509/mpi.c
+++ b/lib/x509/mpi.c
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2003-2012 Free Software Foundation, Inc.
+ * Copyright (C) 2015-2017 Red Hat, Inc.
*
* Author: Nikos Mavrogiannopoulos
*
@@ -260,65 +261,27 @@ _gnutls_x509_read_sign_params(ASN1_TYPE src, const char *src_name,
return result;
} else {
+ const gnutls_sign_entry_st *se;
+
memset(params, 0, sizeof(gnutls_x509_spki_st));
- result = gnutls_oid_to_sign(oid);
- if (result != GNUTLS_SIGN_UNKNOWN) {
- params->pk = gnutls_sign_get_pk_algorithm(result);
- params->dig = gnutls_sign_get_hash_algorithm(result);
+ se = _gnutls_oid_to_sign_entry(oid);
+ if (se != NULL) {
+ params->pk = se->pk;
}
}
return 0;
}
-int
-_gnutls_x509_crt_read_sign_params(gnutls_x509_crt_t crt,
- gnutls_x509_spki_st *params)
-{
- return _gnutls_x509_read_sign_params(crt->cert,
- "tbsCertificate."
- "subjectPublicKeyInfo."
- "algorithm",
- params);
-}
-
-int
-_gnutls_x509_crq_read_sign_params(gnutls_x509_crq_t crt,
- gnutls_x509_spki_st *params)
-{
- return _gnutls_x509_read_sign_params(crt->crq,
- "certificationRequestInfo."
- "subjectPKInfo."
- "algorithm",
- params);
-}
-
-int
-_gnutls_x509_write_sign_params(ASN1_TYPE dst, const char *dst_name,
- gnutls_x509_spki_st *params)
+static int write_oid_and_params(ASN1_TYPE dst, const char *dst_name, const char *oid, gnutls_x509_spki_st *params)
{
int result;
char name[128];
- const char *oid;
_gnutls_str_cpy(name, sizeof(name), dst_name);
_gnutls_str_cat(name, sizeof(name), ".algorithm");
- if (params->legacy && params->pk == GNUTLS_PK_RSA)
- oid = PK_PKIX1_RSA_OID;
- else if (params->pk == GNUTLS_PK_RSA_PSS)
- oid = PK_PKIX1_RSA_PSS_OID;
- else
- oid = gnutls_sign_get_oid(gnutls_pk_to_sign(params->pk,
- params->dig));
- if (oid == NULL) {
- gnutls_assert();
- _gnutls_debug_log
- ("Cannot find OID for sign algorithm pk: %d dig: %d\n",
- (int) params->pk, (int) params->dig);
- return GNUTLS_E_INVALID_REQUEST;
- }
/* write the OID.
*/
@@ -328,7 +291,6 @@ _gnutls_x509_write_sign_params(ASN1_TYPE dst, const char *dst_name,
return _gnutls_asn2err(result);
}
-
_gnutls_str_cpy(name, sizeof(name), dst_name);
_gnutls_str_cat(name, sizeof(name), ".parameters");
@@ -363,6 +325,54 @@ _gnutls_x509_write_sign_params(ASN1_TYPE dst, const char *dst_name,
return 0;
}
+int
+_gnutls_x509_write_spki_params(ASN1_TYPE dst, const char *dst_name,
+ gnutls_x509_spki_st *params)
+{
+ const char *oid;
+
+ if (params->legacy && params->pk == GNUTLS_PK_RSA)
+ oid = PK_PKIX1_RSA_OID;
+ else if (params->pk == GNUTLS_PK_RSA_PSS)
+ oid = PK_PKIX1_RSA_PSS_OID;
+ else
+ oid = gnutls_pk_get_oid(params->pk);
+
+ if (oid == NULL) {
+ gnutls_assert();
+ _gnutls_debug_log
+ ("Cannot find OID for public key algorithm %s\n",
+ gnutls_pk_get_name(params->pk));
+ return GNUTLS_E_INVALID_REQUEST;
+ }
+
+ return write_oid_and_params(dst, dst_name, oid, params);
+}
+
+int
+_gnutls_x509_write_sign_params(ASN1_TYPE dst, const char *dst_name,
+ const gnutls_sign_entry_st *se, gnutls_x509_spki_st *params)
+{
+ const char *oid;
+
+ if (params->legacy && params->pk == GNUTLS_PK_RSA)
+ oid = PK_PKIX1_RSA_OID;
+ else if (params->pk == GNUTLS_PK_RSA_PSS)
+ oid = PK_PKIX1_RSA_PSS_OID;
+ else
+ oid = se->oid;
+
+ if (oid == NULL) {
+ gnutls_assert();
+ _gnutls_debug_log
+ ("Cannot find OID for sign algorithm %s\n",
+ se->name);
+ return GNUTLS_E_INVALID_REQUEST;
+ }
+
+ return write_oid_and_params(dst, dst_name, oid, params);
+}
+
/* this function reads a (small) unsigned integer
* from asn1 structs. Combines the read and the convertion
* steps.
diff --git a/lib/x509/output.c b/lib/x509/output.c
index ac652fee18..7e1cc18f15 100644
--- a/lib/x509/output.c
+++ b/lib/x509/output.c
@@ -1440,12 +1440,12 @@ print_crt_pubkey_params(gnutls_buffer_st * str, const char *key_name,
pk = ret;
if (pk == GNUTLS_PK_RSA_PSS) {
- ret = _gnutls_x509_crt_read_sign_params(crt, &params);
+ ret = _gnutls_x509_crt_read_spki_params(crt, &params);
if (ret < 0)
return ret;
addf(str, _("\t%sPublic Key Parameters:\n"), key_name);
addf(str, "\t\tHash Algorithm: %s\n",
- gnutls_digest_get_name(params.dig));
+ gnutls_digest_get_name(params.rsa_pss_dig));
addf(str, "\t\tSalt Length: %d\n", params.salt_size);
}
@@ -2385,12 +2385,12 @@ print_crq_pubkey_params(gnutls_buffer_st * str, const char *key_name,
pk = ret;
if (pk == GNUTLS_PK_RSA_PSS) {
- ret = _gnutls_x509_crq_read_sign_params(crt, &params);
+ ret = _gnutls_x509_crq_read_spki_params(crt, &params);
if (ret < 0)
return ret;
addf(str, _("\t%sPublic Key Parameters:\n"), key_name);
addf(str, "\t\tHash Algorithm: %s\n",
- gnutls_digest_get_name(params.dig));
+ gnutls_digest_get_name(params.rsa_pss_dig));
addf(str, "\t\tSalt Length: %d\n", params.salt_size);
}
diff --git a/lib/x509/pkcs7.c b/lib/x509/pkcs7.c
index 4bb8d863a8..b22a1cf65b 100644
--- a/lib/x509/pkcs7.c
+++ b/lib/x509/pkcs7.c
@@ -2349,6 +2349,7 @@ int gnutls_pkcs7_sign(gnutls_pkcs7_t pkcs7,
const mac_entry_st *me = hash_to_entry(dig);
unsigned pk, sigalgo;
gnutls_x509_spki_st key_params, params;
+ const gnutls_sign_entry_st *se;
if (pkcs7 == NULL || me == NULL)
return GNUTLS_E_INVALID_REQUEST;
@@ -2486,23 +2487,29 @@ int gnutls_pkcs7_sign(gnutls_pkcs7_t pkcs7,
/* write the signature algorithm */
pk = gnutls_x509_crt_get_pk_algorithm(signer, NULL);
- ret = _gnutls_privkey_get_sign_params(signer_key, &key_params);
+ ret = _gnutls_privkey_get_spki_params(signer_key, &key_params);
if (ret < 0) {
gnutls_assert();
goto cleanup;
}
- ret = _gnutls_x509_crt_get_sign_params(signer, &key_params, &params);
+ ret = _gnutls_x509_crt_get_spki_params(signer, &key_params, &params);
if (ret < 0) {
gnutls_assert();
goto cleanup;
}
- result = _gnutls_privkey_update_sign_params(signer_key, pk, dig, 0,
+ ret = _gnutls_privkey_update_spki_params(signer_key, pk, dig, 0,
&params);
- if (result < 0) {
+ if (ret < 0) {
gnutls_assert();
- return result;
+ goto cleanup;
+ }
+
+ se = _gnutls_pk_to_sign_entry(params.pk, dig);
+ if (se == NULL) {
+ ret = gnutls_assert_val(GNUTLS_E_UNSUPPORTED_SIGNATURE_ALGORITHM);
+ goto cleanup;
}
/* RFC5652 is silent on what the values would be and initially I assumed that
@@ -2514,18 +2521,13 @@ int gnutls_pkcs7_sign(gnutls_pkcs7_t pkcs7,
ret =
_gnutls_x509_write_sign_params(pkcs7->signed_data,
"signerInfos.?LAST.signatureAlgorithm",
- &params);
+ se, &params);
if (ret < 0) {
gnutls_assert();
goto cleanup;
}
- sigalgo = gnutls_pk_to_sign(pk, dig);
- if (sigalgo == GNUTLS_SIGN_UNKNOWN) {
- gnutls_assert();
- ret = GNUTLS_E_INVALID_REQUEST;
- goto cleanup;
- }
+ sigalgo = se->id;
/* sign the data */
ret =
@@ -2536,7 +2538,7 @@ int gnutls_pkcs7_sign(gnutls_pkcs7_t pkcs7,
goto cleanup;
}
- ret = privkey_sign_and_hash_data(signer_key, _gnutls_pk_to_sign_entry(params.pk, dig),
+ ret = privkey_sign_and_hash_data(signer_key, se,
&sigdata, &signature, &params);
if (ret < 0) {
gnutls_assert();
diff --git a/lib/x509/privkey.c b/lib/x509/privkey.c
index b4af486dfc..23bc50a152 100644
--- a/lib/x509/privkey.c
+++ b/lib/x509/privkey.c
@@ -1629,11 +1629,11 @@ gnutls_x509_privkey_generate2(gnutls_x509_privkey_t key,
key->params.sign.pk = GNUTLS_PK_RSA_PSS;
if (key->params.palgo != GNUTLS_DIG_UNKNOWN)
- key->params.sign.dig = key->params.palgo;
+ key->params.sign.rsa_pss_dig = key->params.palgo;
else
- key->params.sign.dig = GNUTLS_DIG_SHA256;
+ key->params.sign.rsa_pss_dig = GNUTLS_DIG_SHA256;
- me = hash_to_entry(key->params.sign.dig);
+ me = hash_to_entry(key->params.sign.rsa_pss_dig);
if (unlikely(me == NULL)) {
gnutls_assert();
ret = GNUTLS_E_INVALID_REQUEST;
@@ -2157,7 +2157,7 @@ void gnutls_x509_privkey_set_flags(gnutls_x509_privkey_t key,
}
int
-_gnutls_x509_privkey_get_sign_params(gnutls_x509_privkey_t key,
+_gnutls_x509_privkey_get_spki_params(gnutls_x509_privkey_t key,
gnutls_x509_spki_st *params)
{
memcpy(params, &key->params.sign, sizeof(gnutls_x509_spki_st));
diff --git a/lib/x509/sign.c b/lib/x509/sign.c
index 8a00d77411..343b6eb969 100644
--- a/lib/x509/sign.c
+++ b/lib/x509/sign.c
@@ -50,14 +50,14 @@ _gnutls_x509_get_tbs(ASN1_TYPE cert, const char *tbs_name,
}
int
-_gnutls_x509_crt_get_sign_params(gnutls_x509_crt_t crt,
+_gnutls_x509_crt_get_spki_params(gnutls_x509_crt_t crt,
const gnutls_x509_spki_st *key_params,
gnutls_x509_spki_st *params)
{
int result;
gnutls_x509_spki_st crt_params;
- result = _gnutls_x509_crt_read_sign_params(crt, &crt_params);
+ result = _gnutls_x509_crt_read_spki_params(crt, &crt_params);
if (result < 0) {
gnutls_assert();
return result;
@@ -65,7 +65,7 @@ _gnutls_x509_crt_get_sign_params(gnutls_x509_crt_t crt,
if (crt_params.pk == GNUTLS_PK_RSA_PSS) {
if (key_params->pk == GNUTLS_PK_RSA_PSS) {
- if (crt_params.dig != key_params->dig) {
+ if (crt_params.rsa_pss_dig != key_params->rsa_pss_dig) {
gnutls_assert();
return GNUTLS_E_CERTIFICATE_ERROR;
}
@@ -117,19 +117,19 @@ _gnutls_x509_pkix_sign(ASN1_TYPE src, const char *src_name,
if (pk == GNUTLS_PK_UNKNOWN)
pk = gnutls_privkey_get_pk_algorithm(issuer_key, NULL);
- result = _gnutls_privkey_get_sign_params(issuer_key, &key_params);
+ result = _gnutls_privkey_get_spki_params(issuer_key, &key_params);
if (result < 0) {
gnutls_assert();
return result;
}
- result = _gnutls_x509_crt_get_sign_params(issuer, &key_params, &params);
+ result = _gnutls_x509_crt_get_spki_params(issuer, &key_params, &params);
if (result < 0) {
gnutls_assert();
return result;
}
- result = _gnutls_privkey_update_sign_params(issuer_key, pk, dig, flags,
+ result = _gnutls_privkey_update_spki_params(issuer_key, pk, dig, flags,
&params);
if (result < 0) {
gnutls_assert();
@@ -154,7 +154,11 @@ _gnutls_x509_pkix_sign(ASN1_TYPE src, const char *src_name,
_gnutls_str_cpy(name, sizeof(name), src_name);
_gnutls_str_cat(name, sizeof(name), ".signature");
- result = _gnutls_x509_write_sign_params(src, name, &params);
+ se = _gnutls_pk_to_sign_entry(params.pk, dig);
+ if (se == NULL)
+ return gnutls_assert_val(GNUTLS_E_UNSUPPORTED_SIGNATURE_ALGORITHM);
+
+ result = _gnutls_x509_write_sign_params(src, name, se, &params);
if (result < 0) {
gnutls_assert();
return result;
@@ -169,7 +173,6 @@ _gnutls_x509_pkix_sign(ASN1_TYPE src, const char *src_name,
return result;
}
- se = _gnutls_pk_to_sign_entry(params.pk, dig);
if (_gnutls_pk_is_not_prehashed(params.pk)) {
result = privkey_sign_raw_data(issuer_key, se, &tbs, &signature, &params);
} else {
@@ -201,7 +204,7 @@ _gnutls_x509_pkix_sign(ASN1_TYPE src, const char *src_name,
*/
result = _gnutls_x509_write_sign_params(src, "signatureAlgorithm",
- &params);
+ se, &params);
if (result < 0) {
gnutls_assert();
return result;
diff --git a/lib/x509/spki.c b/lib/x509/spki.c
index af94ea4a2a..ea4814a448 100644
--- a/lib/x509/spki.c
+++ b/lib/x509/spki.c
@@ -113,10 +113,12 @@ gnutls_x509_spki_get_pk_algorithm(gnutls_x509_spki_t spki)
/**
* gnutls_x509_spki_set_digest_algorithm:
* @spki: the SubjectPublicKeyInfo structure
- * @dig: the digest algorithm of type #gnutls_digest_algorithm_t
+ * @dig: a digest algorithm of type #gnutls_digest_algorithm_t
*
* This function will set the digest algorithm of a
- * SubjectPublicKeyInfo structure.
+ * SubjectPublicKeyInfo structure. This is relevant for
+ * RSA-PSS signatures which store the digest algorithm
+ * in the SubjectPublicKeyInfo.
*
* Since: 3.6.0
*
@@ -125,7 +127,7 @@ void
gnutls_x509_spki_set_digest_algorithm(gnutls_x509_spki_t spki,
gnutls_digest_algorithm_t dig)
{
- spki->dig = dig;
+ spki->rsa_pss_dig = dig;
}
/**
@@ -133,7 +135,9 @@ gnutls_x509_spki_set_digest_algorithm(gnutls_x509_spki_t spki,
* @spki: the SubjectPublicKeyInfo structure
*
* This function will get the digest algorithm of a
- * SubjectPublicKeyInfo structure.
+ * SubjectPublicKeyInfo structure. This is relevant for
+ * RSA-PSS signatures which store the digest algorithm
+ * in the SubjectPublicKeyInfo.
*
* Returns: a member of the #gnutls_digest_algorithm_t enumeration on
* success, or a %GNUTLS_DIG_UNKNOWN on error.
@@ -144,7 +148,7 @@ gnutls_x509_spki_set_digest_algorithm(gnutls_x509_spki_t spki,
int
gnutls_x509_spki_get_digest_algorithm(gnutls_x509_spki_t spki)
{
- return spki->dig;
+ return spki->rsa_pss_dig;
}
/**
diff --git a/lib/x509/verify.c b/lib/x509/verify.c
index 002fac6f2a..0b8760254a 100644
--- a/lib/x509/verify.c
+++ b/lib/x509/verify.c
@@ -1295,7 +1295,7 @@ _gnutls_x509_validate_sign_params(gnutls_pk_algorithm_t pk_algorithm,
}
} else {
/* Check if the underlying hash algorithms are same. */
- if (sig_params->dig != params.dig) {
+ if (sig_params->rsa_pss_dig != params.rsa_pss_dig) {
gnutls_assert();
return GNUTLS_E_INVALID_REQUEST;
}
@@ -1330,6 +1330,7 @@ _gnutls_x509_verify_data(gnutls_sign_algorithm_t sign,
int ret;
gnutls_x509_spki_st sign_params;
const mac_entry_st * me;
+ const gnutls_sign_entry_st *se;
/* Read the MPI parameters from the issuer's certificate.
*/
@@ -1341,6 +1342,10 @@ _gnutls_x509_verify_data(gnutls_sign_algorithm_t sign,
issuer_pk = gnutls_x509_crt_get_pk_algorithm(issuer, NULL);
+ se = _gnutls_sign_to_entry(sign);
+ if (se == NULL)
+ return gnutls_assert_val(GNUTLS_E_UNSUPPORTED_SIGNATURE_ALGORITHM);
+
if (cert != NULL) {
ret = _gnutls_x509_read_sign_params(cert->cert,
"signatureAlgorithm",
@@ -1363,18 +1368,20 @@ _gnutls_x509_verify_data(gnutls_sign_algorithm_t sign,
} else {
memcpy(&sign_params, &params.sign,
sizeof(gnutls_x509_spki_st));
- sign_params.pk = gnutls_sign_get_pk_algorithm(sign);
- sign_params.dig = gnutls_sign_get_hash_algorithm(sign);
+
+ sign_params.pk = se->pk;
+ if (sign_params.pk == GNUTLS_PK_RSA_PSS)
+ sign_params.rsa_pss_dig = se->hash;
}
- me = hash_to_entry(sign_params.dig);
+ me = hash_to_entry(se->hash);
if (unlikely(me == NULL)) {
gnutls_assert();
ret = GNUTLS_E_CERTIFICATE_ERROR;
goto cleanup;
}
- ret = pubkey_verify_data(sign_params.pk, me, data, signature, &params,
+ ret = pubkey_verify_data(se->pk, me, data, signature, &params,
&sign_params);
if (ret < 0) {
gnutls_assert();
diff --git a/lib/x509/x509.c b/lib/x509/x509.c
index f779cd97b4..073e7fcdbb 100644
--- a/lib/x509/x509.c
+++ b/lib/x509/x509.c
@@ -1605,13 +1605,13 @@ gnutls_x509_crt_get_pk_algorithm2(gnutls_x509_crt_t cert,
spki->pk = result;
- result = _gnutls_x509_crt_read_sign_params(cert, &params);
+ result = _gnutls_x509_crt_read_spki_params(cert, &params);
if (result < 0) {
gnutls_assert();
return result;
}
- spki->dig = params.dig;
+ spki->rsa_pss_dig = params.rsa_pss_dig;
spki->salt_size = params.salt_size;
return spki->pk;
diff --git a/lib/x509/x509_int.h b/lib/x509/x509_int.h
index 6160a50e0c..2d7e881997 100644
--- a/lib/x509/x509_int.h
+++ b/lib/x509/x509_int.h
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2003-2012 Free Software Foundation, Inc.
+ * Copyright (C) 2017 Red Hat, Inc.
*
* Author: Nikos Mavrogiannopoulos
*
@@ -159,7 +160,7 @@ int _gnutls_x509_pkix_sign(ASN1_TYPE src, const char *src_name,
unsigned int flags,
gnutls_x509_crt_t issuer,
gnutls_privkey_t issuer_key);
-int _gnutls_x509_crt_get_sign_params(gnutls_x509_crt_t issuer,
+int _gnutls_x509_crt_get_spki_params(gnutls_x509_crt_t issuer,
const gnutls_x509_spki_st *key_params,
gnutls_x509_spki_st *params);
@@ -256,7 +257,7 @@ _gnutls_x509_read_ecc_params(uint8_t * der, int dersize,
int _gnutls_asn1_encode_privkey(gnutls_pk_algorithm_t pk, ASN1_TYPE * c2,
gnutls_pk_params_st * params, unsigned compat);
-int _gnutls_x509_privkey_get_sign_params(gnutls_x509_privkey_t key,
+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,
@@ -324,11 +325,6 @@ int _gnutls_x509_crq_get_mpis(gnutls_x509_crq_t cert,
int _gnutls_x509_crt_get_mpis(gnutls_x509_crt_t cert,
gnutls_pk_params_st * params);
-int _gnutls_x509_crt_read_sign_params(gnutls_x509_crt_t crt,
- gnutls_x509_spki_st *params);
-int _gnutls_x509_crq_read_sign_params(gnutls_x509_crq_t crt,
- gnutls_x509_spki_st *params);
-
int _gnutls_x509_read_pubkey_params(gnutls_pk_algorithm_t, uint8_t * der,
int dersize,
gnutls_pk_params_st * params);
@@ -381,8 +377,35 @@ int _gnutls_x509_write_key_int(ASN1_TYPE node, const char *value, bigint_t mpi,
int _gnutls_x509_read_sign_params(ASN1_TYPE src, const char *src_name,
gnutls_x509_spki_st *params);
int _gnutls_x509_write_sign_params(ASN1_TYPE dst, const char *dst_name,
+ const gnutls_sign_entry_st *se, gnutls_x509_spki_st *params);
+
+#define _gnutls_x509_read_spki_params _gnutls_x509_read_sign_params
+int _gnutls_x509_write_spki_params(ASN1_TYPE dst, const char *dst_name,
gnutls_x509_spki_st *params);
+inline static int
+_gnutls_x509_crt_read_spki_params(gnutls_x509_crt_t crt,
+ gnutls_x509_spki_st *params)
+{
+ return _gnutls_x509_read_spki_params(crt->cert,
+ "tbsCertificate."
+ "subjectPublicKeyInfo."
+ "algorithm",
+ params);
+}
+
+inline static int
+_gnutls_x509_crq_read_spki_params(gnutls_x509_crq_t crt,
+ gnutls_x509_spki_st *params)
+{
+ return _gnutls_x509_read_spki_params(crt->crq,
+ "certificationRequestInfo."
+ "subjectPKInfo."
+ "algorithm",
+ params);
+}
+
+
/* pkcs12.h */
#include <gnutls/pkcs12.h>
diff --git a/lib/x509/x509_write.c b/lib/x509/x509_write.c
index da12905c71..cd72204b7b 100644
--- a/lib/x509/x509_write.c
+++ b/lib/x509/x509_write.c
@@ -2043,7 +2043,7 @@ gnutls_x509_crt_set_pk_algorithm(gnutls_x509_crt_t crt,
if (crt_pk == GNUTLS_PK_RSA) {
const mac_entry_st *me;
- me = hash_to_entry(spki->dig);
+ me = hash_to_entry(spki->rsa_pss_dig);
if (unlikely(me == NULL)) {
gnutls_assert();
return GNUTLS_E_INVALID_REQUEST;
@@ -2051,7 +2051,7 @@ gnutls_x509_crt_set_pk_algorithm(gnutls_x509_crt_t crt,
memset(&params, 0, sizeof(gnutls_x509_spki_st));
params.pk = spki->pk;
- params.dig = spki->dig;
+ params.rsa_pss_dig = spki->rsa_pss_dig;
/* If salt size is zero, find the optimal salt size. */
if (spki->salt_size == 0) {
@@ -2061,13 +2061,13 @@ gnutls_x509_crt_set_pk_algorithm(gnutls_x509_crt_t crt,
} else
params.salt_size = spki->salt_size;
} else if (crt_pk == GNUTLS_PK_RSA_PSS) {
- result = _gnutls_x509_crt_read_sign_params(crt, &params);
+ result = _gnutls_x509_crt_read_spki_params(crt, &params);
if (result < 0) {
gnutls_assert();
return result;
}
- if (params.dig != spki->dig ||
+ if (params.rsa_pss_dig != spki->rsa_pss_dig ||
params.salt_size > spki->salt_size) {
gnutls_assert();
return GNUTLS_E_INVALID_REQUEST;
@@ -2078,7 +2078,7 @@ gnutls_x509_crt_set_pk_algorithm(gnutls_x509_crt_t crt,
MODIFIED(crt);
- result = _gnutls_x509_write_sign_params(crt->cert,
+ result = _gnutls_x509_write_spki_params(crt->cert,
"tbsCertificate."
"subjectPublicKeyInfo.algorithm",
&params);