diff options
author | Nikos Mavrogiannopoulos <nmav@redhat.com> | 2016-12-01 09:48:56 +0100 |
---|---|---|
committer | Nikos Mavrogiannopoulos <nmav@redhat.com> | 2016-12-01 09:50:26 +0100 |
commit | 0ca04a5685d136c638d6574237144a1ee5c6830a (patch) | |
tree | 41854c0ccad775713dbd234969f3366da661a0be | |
parent | 9929402e393677b78502a67f655e1fd4b13ed3fe (diff) | |
download | gnutls-0ca04a5685d136c638d6574237144a1ee5c6830a.tar.gz |
Removed redundant certificate key usage checks.
There were redundant checks when a certificate was obtained, as
well as prior to performing operations with certificates/pubkeys.
Kept the checks prior to operations.
-rw-r--r-- | lib/auth/cert.c | 14 | ||||
-rw-r--r-- | lib/cert.c | 54 | ||||
-rw-r--r-- | lib/x509.c | 56 | ||||
-rw-r--r-- | lib/x509.h | 3 |
4 files changed, 53 insertions, 74 deletions
diff --git a/lib/auth/cert.c b/lib/auth/cert.c index 2501ff0bd6..eefeb892b9 100644 --- a/lib/auth/cert.c +++ b/lib/auth/cert.c @@ -1094,13 +1094,6 @@ _gnutls_proc_x509_server_crt(gnutls_session_t session, goto cleanup; } - if ((ret = - _gnutls_check_key_usage(&peer_certificate_list[0], - gnutls_kx_get(session))) < 0) { - gnutls_assert(); - goto cleanup; - } - ret = 0; cleanup: @@ -1289,13 +1282,6 @@ _gnutls_proc_openpgp_server_crt(gnutls_session_t session, goto cleanup; } - if ((ret = - _gnutls_check_key_usage(&peer_certificate_list[0], - gnutls_kx_get(session))) < 0) { - gnutls_assert(); - goto cleanup; - } - ret = 0; cleanup: diff --git a/lib/cert.c b/lib/cert.c index d93b2f6cba..9e42de1c51 100644 --- a/lib/cert.c +++ b/lib/cert.c @@ -245,6 +245,58 @@ gnutls_certificate_allocate_credentials(gnutls_certificate_credentials_t * return 0; } +/* Returns 0 if it's ok to use the gnutls_kx_algorithm_t with this + * certificate (uses the KeyUsage field). + */ +static int +check_key_usage(const gnutls_pcert_st * cert, + gnutls_kx_algorithm_t alg) +{ + unsigned int key_usage = 0; + int encipher_type; + + if (cert == NULL || alg == GNUTLS_KX_UNKNOWN) { + gnutls_assert(); + return GNUTLS_E_INTERNAL_ERROR; + } + + if (_gnutls_map_kx_get_cred(alg, 1) == GNUTLS_CRD_CERTIFICATE || + _gnutls_map_kx_get_cred(alg, 0) == GNUTLS_CRD_CERTIFICATE) { + + gnutls_pubkey_get_key_usage(cert->pubkey, &key_usage); + + encipher_type = _gnutls_kx_encipher_type(alg); + + if (key_usage != 0 && encipher_type != CIPHER_IGN) { + /* If key_usage has been set in the certificate + */ + + if (encipher_type == CIPHER_ENCRYPT) { + /* If the key exchange method requires an encipher + * type algorithm, and key's usage does not permit + * encipherment, then fail. + */ + if (!(key_usage & GNUTLS_KEY_KEY_ENCIPHERMENT)) { + gnutls_assert(); + return + GNUTLS_E_KEY_USAGE_VIOLATION; + } + } + + if (encipher_type == CIPHER_SIGN) { + /* The same as above, but for sign only keys + */ + if (!(key_usage & GNUTLS_KEY_DIGITAL_SIGNATURE)) { + gnutls_assert(); + return + GNUTLS_E_KEY_USAGE_VIOLATION; + } + } + } + } + return 0; +} + /* returns the KX algorithms that are supported by a * certificate. (Eg a certificate with RSA params, supports @@ -275,7 +327,7 @@ _gnutls_selected_cert_supported_kx(gnutls_session_t session, pk = _gnutls_map_kx_get_pk(kx); if (pk == cert_pk) { /* then check key usage */ - if (_gnutls_check_key_usage(cert, kx) == 0 || + if (check_key_usage(cert, kx) == 0 || unlikely(session->internals.priorities.allow_server_key_usage_violation != 0)) { alg[i] = kx; i++; diff --git a/lib/x509.c b/lib/x509.c index 2c335cd6ff..d764939092 100644 --- a/lib/x509.c +++ b/lib/x509.c @@ -1616,62 +1616,6 @@ gnutls_certificate_set_x509_key_file2(gnutls_certificate_credentials_t res, CRED_RET_SUCCESS(res); } -/* Returns 0 if it's ok to use the gnutls_kx_algorithm_t with this - * certificate (uses the KeyUsage field). - */ -int -_gnutls_check_key_usage(const gnutls_pcert_st * cert, - gnutls_kx_algorithm_t alg) -{ - unsigned int key_usage = 0; - int encipher_type; - - if (cert == NULL || alg == GNUTLS_KX_UNKNOWN) { - gnutls_assert(); - return GNUTLS_E_INTERNAL_ERROR; - } - - if (_gnutls_map_kx_get_cred(alg, 1) == GNUTLS_CRD_CERTIFICATE || - _gnutls_map_kx_get_cred(alg, 0) == GNUTLS_CRD_CERTIFICATE) { - - gnutls_pubkey_get_key_usage(cert->pubkey, &key_usage); - - encipher_type = _gnutls_kx_encipher_type(alg); - - if (key_usage != 0 && encipher_type != CIPHER_IGN) { - /* If key_usage has been set in the certificate - */ - - if (encipher_type == CIPHER_ENCRYPT) { - /* If the key exchange method requires an encipher - * type algorithm, and key's usage does not permit - * encipherment, then fail. - */ - if (! - (key_usage & - GNUTLS_KEY_KEY_ENCIPHERMENT)) { - gnutls_assert(); - return - GNUTLS_E_KEY_USAGE_VIOLATION; - } - } - - if (encipher_type == CIPHER_SIGN) { - /* The same as above, but for sign only keys - */ - if (! - (key_usage & - GNUTLS_KEY_DIGITAL_SIGNATURE)) { - gnutls_assert(); - return - GNUTLS_E_KEY_USAGE_VIOLATION; - } - } - } - } - return 0; -} - /** * gnutls_certificate_set_x509_trust_mem: * @res: is a #gnutls_certificate_credentials_t type. diff --git a/lib/x509.h b/lib/x509.h index 8048416691..4da17761cd 100644 --- a/lib/x509.h +++ b/lib/x509.h @@ -33,9 +33,6 @@ int _gnutls_x509_cert_verify_peers(gnutls_session_t session, #define PEM_CRL_SEP "-----BEGIN X509 CRL" -int _gnutls_check_key_usage(const gnutls_pcert_st * cert, - gnutls_kx_algorithm_t alg); - int _gnutls_x509_raw_privkey_to_gkey(gnutls_privkey_t * privkey, const gnutls_datum_t * raw_key, gnutls_x509_crt_fmt_t type); |