diff options
author | Nikos Mavrogiannopoulos <nmav@gnutls.org> | 2001-08-06 22:17:48 +0000 |
---|---|---|
committer | Nikos Mavrogiannopoulos <nmav@gnutls.org> | 2001-08-06 22:17:48 +0000 |
commit | 751e12df434a2997311c278b751c235894641817 (patch) | |
tree | 86908368db11eb11e6dec7a4ec5c2dfc3789f274 /lib | |
parent | 7d3467a82b43b090ba977691950555cd62e09f26 (diff) | |
download | gnutls-751e12df434a2997311c278b751c235894641817.tar.gz |
updated in key usage fields
Diffstat (limited to 'lib')
-rw-r--r-- | lib/auth_rsa.c | 17 | ||||
-rw-r--r-- | lib/gnutls_cert.c | 38 | ||||
-rw-r--r-- | lib/gnutls_errors.c | 1 | ||||
-rw-r--r-- | lib/gnutls_errors_int.h | 1 | ||||
-rw-r--r-- | lib/gnutls_handshake.c | 4 | ||||
-rw-r--r-- | lib/gnutls_int.h | 4 |
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 |