summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikos Mavrogiannopoulos <nmav@redhat.com>2016-12-01 09:48:56 +0100
committerNikos Mavrogiannopoulos <nmav@redhat.com>2016-12-01 09:50:26 +0100
commit0ca04a5685d136c638d6574237144a1ee5c6830a (patch)
tree41854c0ccad775713dbd234969f3366da661a0be
parent9929402e393677b78502a67f655e1fd4b13ed3fe (diff)
downloadgnutls-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.c14
-rw-r--r--lib/cert.c54
-rw-r--r--lib/x509.c56
-rw-r--r--lib/x509.h3
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);