summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikos Mavrogiannopoulos <nmav@gnutls.org>2001-08-06 22:17:48 +0000
committerNikos Mavrogiannopoulos <nmav@gnutls.org>2001-08-06 22:17:48 +0000
commit751e12df434a2997311c278b751c235894641817 (patch)
tree86908368db11eb11e6dec7a4ec5c2dfc3789f274
parent7d3467a82b43b090ba977691950555cd62e09f26 (diff)
downloadgnutls-751e12df434a2997311c278b751c235894641817.tar.gz
updated in key usage fields
-rw-r--r--lib/auth_rsa.c17
-rw-r--r--lib/gnutls_cert.c38
-rw-r--r--lib/gnutls_errors.c1
-rw-r--r--lib/gnutls_errors_int.h1
-rw-r--r--lib/gnutls_handshake.c4
-rw-r--r--lib/gnutls_int.h4
6 files changed, 58 insertions, 7 deletions
diff --git a/lib/auth_rsa.c b/lib/auth_rsa.c
index d2ad65984e..c21e8ad3f6 100644
--- a/lib/auth_rsa.c
+++ b/lib/auth_rsa.c
@@ -447,6 +447,15 @@ int proc_rsa_certificate(GNUTLS_STATE state, opaque * data, int data_size)
_gnutls_copy_x509_client_auth_info(info, &peer_certificate_list[0], verify);
+ /* This works for the client
+ */
+ if ( peer_certificate_list[0].keyUsage != 0)
+ if ( !(peer_certificate_list[0].keyUsage & X509KEY_KEY_ENCIPHERMENT)) {
+ gnutls_assert();
+ gnutls_free(peer_certificate_list);
+ return GNUTLS_E_X509_KEY_USAGE_VIOLATION;
+ }
+
gnutls_free(peer_certificate_list);
return 0;
@@ -677,6 +686,14 @@ int gen_rsa_client_cert_vrfy(GNUTLS_STATE state, opaque ** data)
}
}
+ /* If our certificate supports signing
+ */
+ if ( apr_cert_list[0].keyUsage != 0)
+ if ( !(apr_cert_list[0].keyUsage & X509KEY_DIGITAL_SIGNATURE)) {
+ gnutls_assert();
+ return GNUTLS_E_X509_KEY_USAGE_VIOLATION;
+ }
+
if (apr_pkey != NULL) {
if ( (ret=_gnutls_generate_sig( state, apr_pkey, &signature)) < 0) {
gnutls_assert();
diff --git a/lib/gnutls_cert.c b/lib/gnutls_cert.c
index 55744768c7..6f3b74f58c 100644
--- a/lib/gnutls_cert.c
+++ b/lib/gnutls_cert.c
@@ -31,6 +31,7 @@
#include <gnutls_global.h>
#include <x509_verify.h>
#include <x509_extensions.h>
+#include <gnutls_algorithms.h>
/* KX mappings to PK algorithms */
typedef struct {
@@ -794,9 +795,40 @@ return GNUTLS_E_UNIMPLEMENTED_FEATURE;
}
+/* Returns 0 if it's ok to use the KXAlgorithm with this cert
+ * (using KeyUsage field). 1 otherwise.
+ */
+static int _gnutls_check_x509_key_usage( gnutls_cert* cert, KXAlgorithm alg) {
+ if (_gnutls_map_kx_get_cred(alg) == GNUTLS_X509PKI) {
+ switch(alg) {
+ case GNUTLS_KX_RSA:
+ if (cert->keyUsage!=0) {
+ if ( !(cert->keyUsage & X509KEY_KEY_ENCIPHERMENT))
+ return 1;
+ else
+ return 0;
+ }
+ return 0;
+ case GNUTLS_KX_DHE_RSA:
+ if (cert->keyUsage!=0) {
+ if ( !(cert->keyUsage & X509KEY_DIGITAL_SIGNATURE))
+ return 1;
+ else
+ return 0;
+ }
+ return 0;
+ default:
+ return 1;
+ }
+ }
+ return 0;
+}
+
/* returns the KX algorithms that are supported by a
* certificate. (Eg a certificate with RSA params, supports
* GNUTLS_KX_RSA algorithm).
+ * This function also uses the KeyUsage field of the certificate
+ * extensions in order to disable unneded algorithms.
*/
int _gnutls_cert_supported_kx(gnutls_cert * cert, KXAlgorithm ** alg,
int *alg_size)
@@ -810,8 +842,10 @@ int _gnutls_cert_supported_kx(gnutls_cert * cert, KXAlgorithm ** alg,
for (kx = 0; kx < 255; kx++) {
pk = _gnutls_map_pk_get_pk(kx);
if (pk == cert->subject_pk_algorithm) {
- kxlist[i] = kx;
- i++;
+ if ( _gnutls_check_x509_key_usage( cert, kx) == 0) {
+ kxlist[i] = kx;
+ i++;
+ }
}
}
diff --git a/lib/gnutls_errors.c b/lib/gnutls_errors.c
index 09e4d0ba8b..77dc4465c1 100644
--- a/lib/gnutls_errors.c
+++ b/lib/gnutls_errors.c
@@ -78,6 +78,7 @@ static gnutls_error_entry error_algorithms[] = {
GNUTLS_ERROR_ENTRY( GNUTLS_E_ASN1_ERROR, 1),
GNUTLS_ERROR_ENTRY( GNUTLS_E_X509_CERTIFICATE_ERROR, 1),
GNUTLS_ERROR_ENTRY( GNUTLS_E_X509_UNSUPPORTED_CRITICAL_EXTENSION, 1),
+ GNUTLS_ERROR_ENTRY( GNUTLS_E_X509_KEY_USAGE_VIOLATION, 1),
GNUTLS_ERROR_ENTRY( GNUTLS_E_AGAIN, 0),
GNUTLS_ERROR_ENTRY( GNUTLS_E_GOT_HELLO_REQUEST, 0),
GNUTLS_ERROR_ENTRY( GNUTLS_E_GOT_APPLICATION_DATA, 0),
diff --git a/lib/gnutls_errors_int.h b/lib/gnutls_errors_int.h
index 896fef8c14..6c9c21cfa2 100644
--- a/lib/gnutls_errors_int.h
+++ b/lib/gnutls_errors_int.h
@@ -48,5 +48,6 @@
#define GNUTLS_E_PK_DECRYPTION_FAILED -45
#define GNUTLS_E_PK_SIGNATURE_FAILED -46
#define GNUTLS_E_X509_UNSUPPORTED_CRITICAL_EXTENSION -47
+#define GNUTLS_E_X509_KEY_USAGE_VIOLATION -48
#define GNUTLS_E_UNIMPLEMENTED_FEATURE -250
diff --git a/lib/gnutls_handshake.c b/lib/gnutls_handshake.c
index 90931c38af..f763a08cf4 100644
--- a/lib/gnutls_handshake.c
+++ b/lib/gnutls_handshake.c
@@ -1232,7 +1232,6 @@ int gnutls_handshake(SOCKET cd, GNUTLS_STATE state) {
int ret;
ret = gnutls_handshake_begin(cd, state);
- /* FIXME: check certificate */
if (ret == 0)
ret = gnutls_handshake_finish(cd, state);
@@ -1361,7 +1360,7 @@ int gnutls_handshake_begin(SOCKET cd, GNUTLS_STATE state) {
gnutls_clearHashDataBuffer(state);
return ret;
}
- /* FIXME: request - and get - a client certificate */
+
return 0;
}
}
@@ -1496,7 +1495,6 @@ int gnutls_handshake_finish(SOCKET cd, GNUTLS_STATE state) {
gnutls_clearHashDataBuffer(state);
return ret;
}
- /* FIXME: receive certificate request */
/* receive the server hello done */
if (state->gnutls_internals.resumed == RESUME_FALSE) /* if we are not resuming */
diff --git a/lib/gnutls_int.h b/lib/gnutls_int.h
index ef7b03a94a..073058294d 100644
--- a/lib/gnutls_int.h
+++ b/lib/gnutls_int.h
@@ -29,8 +29,8 @@
#define WRITE_DEBUG
#define BUFFERS_DEBUG
#define HARD_DEBUG
-#define RECORD_DEBUG*/
-#define HANDSHAKE_DEBUG
+#define RECORD_DEBUG
+#define HANDSHAKE_DEBUG*/
#define DEBUG