diff options
author | Nikos Mavrogiannopoulos <nmav@gnutls.org> | 2001-12-09 10:50:57 +0000 |
---|---|---|
committer | Nikos Mavrogiannopoulos <nmav@gnutls.org> | 2001-12-09 10:50:57 +0000 |
commit | a83a82623599e77b9df86a497fee69896b4dabfe (patch) | |
tree | b3ba164011af142a120dc02855443bce14af6c4e | |
parent | 745b110197d9a1af0354a5607bdbe49eda4012a7 (diff) | |
download | gnutls-a83a82623599e77b9df86a497fee69896b4dabfe.tar.gz |
Optimizations in server certificate callback.
-rw-r--r-- | NEWS | 1 | ||||
-rw-r--r-- | lib/auth_x509.c | 39 | ||||
-rw-r--r-- | lib/auth_x509.h | 4 | ||||
-rw-r--r-- | lib/gnutls_cert.c | 1 | ||||
-rw-r--r-- | lib/gnutls_errors_int.h | 21 | ||||
-rw-r--r-- | lib/gnutls_handshake.c | 28 | ||||
-rw-r--r-- | lib/gnutls_int.h | 4 |
7 files changed, 63 insertions, 35 deletions
@@ -2,6 +2,7 @@ Version ?.?.? - Fixes in MPI handling (fixes possible with signed integers) - Removed name indication extension - Added gnutls_transport_get_ptr() and gnutls_db_get_ptr() +- Optimizations in server certificate callback. Version 0.2.90 (7/12/2001) - gnutls_handshake(), gnutls_read() etc. functions no longer require diff --git a/lib/auth_x509.c b/lib/auth_x509.c index b2de54efc9..05a225c9a6 100644 --- a/lib/auth_x509.c +++ b/lib/auth_x509.c @@ -104,7 +104,8 @@ static int _gnutls_get_private_rsa_params(GNUTLS_KEY key, return 0; } -/* Returns the issuer's Distinguished name in odn, of the certificate specified in cert. +/* Returns the issuer's Distinguished name in odn, of the certificate + * specified in cert. */ int _gnutls_find_dn(gnutls_datum * odn, gnutls_cert * cert) { @@ -874,13 +875,9 @@ int _gnutls_find_apr_cert(GNUTLS_STATE state, gnutls_cert ** apr_cert_list, gnutls_assert(); /* this is not allowed */ return GNUTLS_E_INSUFICIENT_CRED; } else { - - ind = - _gnutls_server_find_cert_list_index(state, - cred-> - cert_list, - cred-> - ncerts); + /* find_cert_list_index() has been called before. + */ + ind = state->gnutls_internals.selected_cert_index; if (ind < 0) { *apr_cert_list = NULL; @@ -1285,30 +1282,38 @@ int gnutls_x509pki_get_peer_certificate_status(GNUTLS_STATE state) * The 'appropriate' is defined by the user. * (frontend to _gnutls_server_find_cert_index()) */ -const gnutls_cert *_gnutls_server_find_cert(GNUTLS_STATE state, - gnutls_cert ** cert_list, - int cert_list_length) +const gnutls_cert *_gnutls_server_find_x509_cert(GNUTLS_STATE state) { int i; + const X509PKI_CREDENTIALS x509_cred; + + x509_cred = + _gnutls_get_cred(state->gnutls_key, GNUTLS_X509PKI, NULL); + + if (x509_cred==NULL) + return NULL; + + i = _gnutls_server_find_x509_cert_list_index(state, x509_cred->cert_list, + x509_cred->ncerts); - i = _gnutls_server_find_cert_list_index(state, cert_list, - cert_list_length); if (i < 0) return NULL; - return &cert_list[i][0]; + return &x509_cred->cert_list[i][0]; } /* finds the most appropriate certificate in the cert list. * The 'appropriate' is defined by the user. */ -int _gnutls_server_find_cert_list_index(GNUTLS_STATE state, +int _gnutls_server_find_x509_cert_list_index(GNUTLS_STATE state, gnutls_cert ** cert_list, int cert_list_length) { int i, index = -1; const X509PKI_CREDENTIALS cred; + state->gnutls_internals.selected_cert_index = 0; + cred = _gnutls_get_cred(state->gnutls_key, GNUTLS_X509PKI, NULL); if (cred == NULL) { gnutls_assert(); @@ -1339,5 +1344,9 @@ int _gnutls_server_find_cert_list_index(GNUTLS_STATE state, gnutls_free(my_certs); } + /* store the index for future use, in the handshake. + * (This will allow not calling this callback again.) + */ + state->gnutls_internals.selected_cert_index = index; return index; } diff --git a/lib/auth_x509.h b/lib/auth_x509.h index 422f5ff35b..cd67750627 100644 --- a/lib/auth_x509.h +++ b/lib/auth_x509.h @@ -63,8 +63,8 @@ int _gnutls_proc_x509_client_cert_vrfy(GNUTLS_STATE, opaque *, int); int _gnutls_proc_x509_server_certificate(GNUTLS_STATE, opaque *, int); int _gnutls_find_apr_cert( GNUTLS_STATE state, gnutls_cert** apr_cert_list, int *apr_cert_list_length, gnutls_private_key** apr_pkey); int _gnutls_find_dn( gnutls_datum* odn, gnutls_cert* cert); -const gnutls_cert* _gnutls_server_find_cert( struct GNUTLS_STATE_INT*, gnutls_cert** cert_list, int cert_list_length); -int _gnutls_server_find_cert_list_index( struct GNUTLS_STATE_INT*, gnutls_cert ** cert_list, int cert_list_length); +const gnutls_cert* _gnutls_server_find_x509_cert( struct GNUTLS_STATE_INT*); +int _gnutls_server_find_x509_cert_list_index( struct GNUTLS_STATE_INT*, gnutls_cert ** cert_list, int cert_list_length); #define _gnutls_proc_x509_client_certificate _gnutls_proc_x509_server_certificate diff --git a/lib/gnutls_cert.c b/lib/gnutls_cert.c index 2f721813ac..d11f1a15ba 100644 --- a/lib/gnutls_cert.c +++ b/lib/gnutls_cert.c @@ -1110,6 +1110,7 @@ void gnutls_x509pki_set_client_cert_callback(GNUTLS_STATE state, * not attempt to choose the appropriate certificate and the caller function * will fail. * + * The callback function will only be called once per handshake. * The callback function should return the index of the certificate * choosen by the server (or -1 in case of an error) * diff --git a/lib/gnutls_errors_int.h b/lib/gnutls_errors_int.h index ee9ea32697..4f3c73bf2b 100644 --- a/lib/gnutls_errors_int.h +++ b/lib/gnutls_errors_int.h @@ -1,8 +1,9 @@ -/* error codes +/* Gnutls error codes. The mapping to a TLS alert is also shown in + * comments. */ #define GNUTLS_E_SUCCESS 0 -#define GNUTLS_E_MAC_FAILED -1 /* GNUTLS_BAD_RECORD_MAC */ +#define GNUTLS_E_MAC_FAILED -1 /* GNUTLS_A_BAD_RECORD_MAC */ #define GNUTLS_E_UNKNOWN_CIPHER -2 #define GNUTLS_E_UNKNOWN_COMPRESSION_ALGORITHM -3 #define GNUTLS_E_UNKNOWN_MAC_ALGORITHM -4 @@ -16,17 +17,17 @@ #define GNUTLS_E_FATAL_ALERT_RECEIVED -12 #define GNUTLS_E_RECEIVED_BAD_MESSAGE -13 #define GNUTLS_E_RECEIVED_MORE_DATA -14 -#define GNUTLS_E_UNEXPECTED_PACKET -15 /* GNUTLS_UNEXPECTED_MESSAGE */ +#define GNUTLS_E_UNEXPECTED_PACKET -15 /* GNUTLS_A_UNEXPECTED_MESSAGE */ #define GNUTLS_E_WARNING_ALERT_RECEIVED -16 #define GNUTLS_E_ERROR_IN_FINISHED_PACKET -18 #define GNUTLS_E_UNEXPECTED_HANDSHAKE_PACKET -19 #define GNUTLS_E_UNKNOWN_KX_ALGORITHM -20 -#define GNUTLS_E_UNKNOWN_CIPHER_SUITE -21 /* GNUTLS_HANDSHAKE_FAILURE */ +#define GNUTLS_E_UNKNOWN_CIPHER_SUITE -21 /* GNUTLS_A_HANDSHAKE_FAILURE */ #define GNUTLS_E_UNWANTED_ALGORITHM -22 #define GNUTLS_E_MPI_SCAN_FAILED -23 -#define GNUTLS_E_DECRYPTION_FAILED -24 /* GNUTLS_DECRYPTION_FAILED */ +#define GNUTLS_E_DECRYPTION_FAILED -24 /* GNUTLS_A_DECRYPTION_FAILED */ #define GNUTLS_E_MEMORY_ERROR -25 -#define GNUTLS_E_DECOMPRESSION_FAILED -26 /* GNUTLS_DECOMPRESSION_FAILURE */ +#define GNUTLS_E_DECOMPRESSION_FAILED -26 /* GNUTLS_A_DECOMPRESSION_FAILURE */ #define GNUTLS_E_COMPRESSION_FAILED -27 #define GNUTLS_E_AGAIN -28 #define GNUTLS_E_EXPIRED -29 @@ -36,25 +37,25 @@ #define GNUTLS_E_HASH_FAILED -33 #define GNUTLS_E_PARSING_ERROR -34 #define GNUTLS_E_MPI_PRINT_FAILED -35 -#define GNUTLS_E_REHANDSHAKE -37 /* GNUTLS_NO_RENEGOTIATION */ +#define GNUTLS_E_REHANDSHAKE -37 /* GNUTLS_A_NO_RENEGOTIATION */ #define GNUTLS_E_GOT_APPLICATION_DATA -38 #define GNUTLS_E_RECORD_LIMIT_REACHED -39 #define GNUTLS_E_ENCRYPTION_FAILED -40 #define GNUTLS_E_ASN1_ERROR -41 -#define GNUTLS_E_ASN1_PARSING_ERROR -42 /* GNUTLS_BAD_CERTIFICATE */ +#define GNUTLS_E_ASN1_PARSING_ERROR -42 /* GNUTLS_A_BAD_CERTIFICATE */ #define GNUTLS_E_X509_CERTIFICATE_ERROR -43 #define GNUTLS_E_PK_ENCRYPTION_FAILED -44 #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_NO_CERTIFICATE_FOUND -49 /* GNUTLS_BAD_CERTIFICATE */ +#define GNUTLS_E_NO_CERTIFICATE_FOUND -49 /* GNUTLS_A_BAD_CERTIFICATE */ #define GNUTLS_E_INVALID_PARAMETERS -50 #define GNUTLS_E_INVALID_REQUEST -51 #define GNUTLS_E_INTERRUPTED -52 #define GNUTLS_E_PUSH_ERROR -53 #define GNUTLS_E_PULL_ERROR -54 -#define GNUTLS_E_ILLEGAL_PARAMETER -55 /* GNUTLS_ILLEGAL_PARAMETER */ +#define GNUTLS_E_ILLEGAL_PARAMETER -55 /* GNUTLS_A_ILLEGAL_PARAMETER */ #define GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE -56 #define GNUTLS_E_PKCS1_WRONG_PAD -57 diff --git a/lib/gnutls_handshake.c b/lib/gnutls_handshake.c index 931633222e..ce195e3367 100644 --- a/lib/gnutls_handshake.c +++ b/lib/gnutls_handshake.c @@ -1894,8 +1894,7 @@ int _gnutls_remove_unwanted_ciphersuites(GNUTLS_STATE state, cert = NULL; cert = - _gnutls_server_find_cert(state, x509_cred->cert_list, - x509_cred->ncerts); + _gnutls_server_find_x509_cert(state); if (cert == NULL) { /* No certificate was found @@ -1918,29 +1917,42 @@ int _gnutls_remove_unwanted_ciphersuites(GNUTLS_STATE state, gnutls_malloc(numCipherSuites * sizeof(GNUTLS_CipherSuite)); if (newSuite==NULL) { gnutls_assert(); + gnutls_free(alg); return GNUTLS_E_MEMORY_ERROR; } for (i = 0; i < numCipherSuites; i++) { + /* finds the key exchange algorithm in + * the ciphersuite + */ kx = _gnutls_cipher_suite_get_kx_algo((*cipherSuites)[i]); keep = 0; + + /* If there was no credentials to use with the specified + * key exchange method, then just remove it. + */ if (_gnutls_map_kx_get_cred(kx) == GNUTLS_X509PKI) { keep = 1; /* do not keep */ if (x509_cred != NULL) + /* here we check if the KX algorithm + * is compatible with the X.509 certificate. + */ for (j = 0; j < alg_size; j++) { if (alg[j] == kx) { keep = 0; break; } } - } else - /* if it is defined but had no credentials - */ - if (_gnutls_get_kx_cred(state->gnutls_key, kx, NULL) == - NULL) - keep = 1; + } else { + /* if it is defined but had no credentials + */ + + if (_gnutls_get_kx_cred(state->gnutls_key, kx, NULL) == NULL) + keep = 1; + } + if (keep == 0) { memcpy(newSuite[newSuiteSize].CipherSuite, (*cipherSuites)[i].CipherSuite, 2); diff --git a/lib/gnutls_int.h b/lib/gnutls_int.h index dd271e9f13..d7e200d043 100644 --- a/lib/gnutls_int.h +++ b/lib/gnutls_int.h @@ -481,6 +481,10 @@ typedef struct { * user. */ uint16 proposed_record_size; + + /* holds the index of the selected certificate. + */ + int selected_cert_index; } GNUTLS_INTERNALS; struct GNUTLS_STATE_INT { |