diff options
author | Nikos Mavrogiannopoulos <nmav@redhat.com> | 2017-07-27 16:53:57 +0200 |
---|---|---|
committer | Nikos Mavrogiannopoulos <nmav@redhat.com> | 2017-08-03 11:57:52 +0200 |
commit | 4256ef71a7842830f7a27061c31c36554a6b97cc (patch) | |
tree | 0ed46372269b378c67093afe6eaa8fbb046f02f4 /lib/x509 | |
parent | 86da29a32b34bd2f84f914f5749c260d9ff11add (diff) | |
download | gnutls-4256ef71a7842830f7a27061c31c36554a6b97cc.tar.gz |
Added convention for missing SubjectPublicKeyInfo params field
That is, when that field is missing, the spki_st structure field
pk will be set to GNUTLS_PK_UNKNOWN. In that case other fields
are undefined.
Signed-off-by: Nikos Mavrogiannopoulos <nmav@redhat.com>
Diffstat (limited to 'lib/x509')
-rw-r--r-- | lib/x509/crq.c | 3 | ||||
-rw-r--r-- | lib/x509/key_decode.c | 10 | ||||
-rw-r--r-- | lib/x509/key_encode.c | 3 | ||||
-rw-r--r-- | lib/x509/mpi.c | 32 | ||||
-rw-r--r-- | lib/x509/privkey.c | 23 | ||||
-rw-r--r-- | lib/x509/privkey_pkcs8.c | 6 | ||||
-rw-r--r-- | lib/x509/sign.c | 2 | ||||
-rw-r--r-- | lib/x509/x509.c | 4 | ||||
-rw-r--r-- | lib/x509/x509_int.h | 11 |
9 files changed, 60 insertions, 34 deletions
diff --git a/lib/x509/crq.c b/lib/x509/crq.c index f3b50923b5..6088ef9ac6 100644 --- a/lib/x509/crq.c +++ b/lib/x509/crq.c @@ -1332,6 +1332,9 @@ gnutls_x509_crq_get_spki(gnutls_x509_crq_t crq, return result; } + if (params.pk == GNUTLS_PK_UNKNOWN) + return gnutls_assert_val(GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE); + spki->rsa_pss_dig = params.rsa_pss_dig; spki->salt_size = params.salt_size; diff --git a/lib/x509/key_decode.c b/lib/x509/key_decode.c index 97f240e783..6f5f9eadb5 100644 --- a/lib/x509/key_decode.c +++ b/lib/x509/key_decode.c @@ -450,10 +450,16 @@ int _gnutls_x509_check_pubkey_params(gnutls_pk_algorithm_t algo, { switch (algo) { case GNUTLS_PK_RSA_PSS: { - unsigned bits = pubkey_to_bits(params); - const mac_entry_st *me = hash_to_entry(params->spki.rsa_pss_dig); + unsigned bits; + const mac_entry_st *me; size_t hash_size; + if (params->spki.pk == GNUTLS_PK_UNKNOWN) /* no params present */ + return 0; + + bits = pubkey_to_bits(params); + + me = hash_to_entry(params->spki.rsa_pss_dig); if (unlikely(me == NULL)) return gnutls_assert_val(GNUTLS_E_CERTIFICATE_ERROR); diff --git a/lib/x509/key_encode.c b/lib/x509/key_encode.c index 24e7750536..77923a130d 100644 --- a/lib/x509/key_encode.c +++ b/lib/x509/key_encode.c @@ -334,6 +334,9 @@ _gnutls_x509_write_rsa_pss_params(gnutls_x509_spki_st *params, der->data = NULL; der->size = 0; + if (params->pk != GNUTLS_PK_RSA_PSS) + return 0; + if ((result = asn1_create_element (_gnutls_get_gnutls_asn(), "GNUTLS.RSAPSSParameters", &spk)) != ASN1_SUCCESS) { diff --git a/lib/x509/mpi.c b/lib/x509/mpi.c index 4574deead8..c6a240dff3 100644 --- a/lib/x509/mpi.c +++ b/lib/x509/mpi.c @@ -141,6 +141,10 @@ _gnutls_get_asn_mpis(ASN1_TYPE asn, const char *root, if (pk_algorithm != GNUTLS_PK_RSA && pk_algorithm != GNUTLS_PK_EDDSA_ED25519 && pk_algorithm != GNUTLS_PK_ECDH_X25519) { /* RSA and EdDSA do not use parameters */ result = _gnutls_x509_read_value(asn, name, &tmp); + if (pk_algorithm == GNUTLS_PK_RSA_PSS && + (result == GNUTLS_E_ASN1_VALUE_NOT_FOUND || result == GNUTLS_E_ASN1_ELEMENT_NOT_FOUND)) { + goto skip_params; + } if (result < 0) { gnutls_assert(); goto error; @@ -158,6 +162,7 @@ _gnutls_get_asn_mpis(ASN1_TYPE asn, const char *root, _gnutls_free_datum(&tmp); } + skip_params: /* Now read the public key */ _asnstr_append_name(name, sizeof(name), root, ".subjectPublicKey"); @@ -220,8 +225,8 @@ _gnutls_x509_crq_get_mpis(gnutls_x509_crq_t cert, * This is the "signatureAlgorithm" fields. */ int -_gnutls_x509_read_sign_params(ASN1_TYPE src, const char *src_name, - gnutls_x509_spki_st *params) +_gnutls_x509_read_pkalgo_params(ASN1_TYPE src, const char *src_name, + gnutls_x509_spki_st *params, unsigned is_sig) { int result; char name[128]; @@ -246,10 +251,16 @@ _gnutls_x509_read_sign_params(ASN1_TYPE src, const char *src_name, _gnutls_str_cat(name, sizeof(name), ".parameters"); result = _gnutls_x509_read_value(src, name, &tmp); - if (result < 0 && - result != GNUTLS_E_ASN1_ELEMENT_NOT_FOUND && - result != GNUTLS_E_ASN1_VALUE_NOT_FOUND) { - _gnutls_free_datum(&tmp); + if (result < 0) { + if (!is_sig) { + if (result == GNUTLS_E_ASN1_ELEMENT_NOT_FOUND || + result != GNUTLS_E_ASN1_VALUE_NOT_FOUND) { + /* it is ok to not have parameters in SPKI, but + * not in signatures */ + return 0; + } + } + return gnutls_assert_val(result); } @@ -261,15 +272,6 @@ _gnutls_x509_read_sign_params(ASN1_TYPE src, const char *src_name, gnutls_assert(); return result; - } else { - const gnutls_sign_entry_st *se; - - memset(params, 0, sizeof(gnutls_x509_spki_st)); - - se = _gnutls_oid_to_sign_entry(oid); - if (se != NULL) { - params->pk = se->pk; - } } return 0; diff --git a/lib/x509/privkey.c b/lib/x509/privkey.c index 7a6904a5cf..7b8423c47e 100644 --- a/lib/x509/privkey.c +++ b/lib/x509/privkey.c @@ -1243,6 +1243,13 @@ 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) +{ + memcpy(params, &key->params.spki, sizeof(gnutls_x509_spki_st)); +} + /** * gnutls_x509_privkey_get_spki: * @key: should contain a #gnutls_x509_privkey_t type @@ -1262,7 +1269,10 @@ gnutls_x509_privkey_get_spki(gnutls_x509_privkey_t key, gnutls_x509_spki_t spki, return GNUTLS_E_INVALID_REQUEST; } - memcpy(spki, &key->params.spki, sizeof (gnutls_x509_spki_st)); + 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; } @@ -1650,7 +1660,7 @@ gnutls_x509_privkey_generate2(gnutls_x509_privkey_t key, return ret; } - if (algo == GNUTLS_PK_RSA_PSS) { + if (algo == GNUTLS_PK_RSA_PSS && (flags & GNUTLS_PRIVKEY_FLAG_CA)) { const mac_entry_st *me; key->params.spki.pk = GNUTLS_PK_RSA_PSS; @@ -2181,12 +2191,3 @@ void gnutls_x509_privkey_set_flags(gnutls_x509_privkey_t key, key->flags |= flags; } -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)); - params->pk = key->params.algo; - return 0; -} - diff --git a/lib/x509/privkey_pkcs8.c b/lib/x509/privkey_pkcs8.c index 7042cca997..b8d9b80a7f 100644 --- a/lib/x509/privkey_pkcs8.c +++ b/lib/x509/privkey_pkcs8.c @@ -958,9 +958,14 @@ _decode_pkcs8_rsa_pss_key(ASN1_TYPE pkcs8_asn, gnutls_x509_privkey_t pkey) gnutls_datum_t tmp; gnutls_x509_spki_st params; + memset(¶ms, 0, sizeof(params)); + ret = _gnutls_x509_read_value(pkcs8_asn, "privateKeyAlgorithm.parameters", &tmp); if (ret < 0) { + if (ret == GNUTLS_E_ASN1_VALUE_NOT_FOUND || ret == GNUTLS_E_ASN1_ELEMENT_NOT_FOUND) + goto skip_params; + gnutls_assert(); goto error; } @@ -973,6 +978,7 @@ _decode_pkcs8_rsa_pss_key(ASN1_TYPE pkcs8_asn, gnutls_x509_privkey_t pkey) goto error; } + skip_params: ret = _decode_pkcs8_rsa_key(pkcs8_asn, pkey); if (ret < 0) { gnutls_assert(); diff --git a/lib/x509/sign.c b/lib/x509/sign.c index 343b6eb969..c081a92c00 100644 --- a/lib/x509/sign.c +++ b/lib/x509/sign.c @@ -74,7 +74,7 @@ _gnutls_x509_crt_get_spki_params(gnutls_x509_crt_t crt, gnutls_assert(); return GNUTLS_E_CERTIFICATE_ERROR; } - } else if (key_params->pk != GNUTLS_PK_RSA) { + } else if (key_params->pk != GNUTLS_PK_RSA && key_params->pk != GNUTLS_PK_UNKNOWN) { gnutls_assert(); return GNUTLS_E_CERTIFICATE_ERROR; } diff --git a/lib/x509/x509.c b/lib/x509/x509.c index 8e5a15c2c2..1da05109d8 100644 --- a/lib/x509/x509.c +++ b/lib/x509/x509.c @@ -1594,6 +1594,7 @@ gnutls_x509_crt_get_spki(gnutls_x509_crt_t cert, gnutls_x509_spki_t spki, unsign return GNUTLS_E_INVALID_REQUEST; } + spki->pk = gnutls_x509_crt_get_pk_algorithm(cert, NULL); memset(¶ms, 0, sizeof(params)); @@ -1604,6 +1605,9 @@ gnutls_x509_crt_get_spki(gnutls_x509_crt_t cert, gnutls_x509_spki_t spki, unsign return result; } + if (params.pk == GNUTLS_PK_UNKNOWN) + return gnutls_assert_val(GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE); + spki->rsa_pss_dig = params.rsa_pss_dig; spki->salt_size = params.salt_size; diff --git a/lib/x509/x509_int.h b/lib/x509/x509_int.h index c80a79fd11..6a7e5fcc96 100644 --- a/lib/x509/x509_int.h +++ b/lib/x509/x509_int.h @@ -256,8 +256,8 @@ _gnutls_x509_read_ecc_params(uint8_t * der, int dersize, int _gnutls_asn1_encode_privkey(ASN1_TYPE * c2, gnutls_pk_params_st * params, unsigned compat); -int _gnutls_x509_privkey_get_spki_params(gnutls_x509_privkey_t key, - gnutls_x509_spki_st * params); +void _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); @@ -371,12 +371,13 @@ int _gnutls_x509_read_key_int(ASN1_TYPE node, const char *value, int _gnutls_x509_write_key_int(ASN1_TYPE node, const char *value, bigint_t mpi, int lz); -int _gnutls_x509_read_sign_params(ASN1_TYPE src, const char *src_name, - gnutls_x509_spki_st *params); +int _gnutls_x509_read_pkalgo_params(ASN1_TYPE src, const char *src_name, + gnutls_x509_spki_st *params, unsigned is_sig); 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 +#define _gnutls_x509_read_sign_params(src,name,params) _gnutls_x509_read_pkalgo_params(src,name,params,1) +#define _gnutls_x509_read_spki_params(src,name,params) _gnutls_x509_read_pkalgo_params(src,name,params,0) int _gnutls_x509_write_spki_params(ASN1_TYPE dst, const char *dst_name, gnutls_x509_spki_st *params); |