diff options
author | Nikos Mavrogiannopoulos <nmav@gnutls.org> | 2010-03-17 17:52:36 +0100 |
---|---|---|
committer | Nikos Mavrogiannopoulos <nmav@gnutls.org> | 2010-03-17 17:53:26 +0100 |
commit | 6e803c7631829a527497fef23084532fd83980c4 (patch) | |
tree | f275431a981ca81e58dd3f57d9c3602ebdd7d272 /lib | |
parent | fe279dc234c04712086b810567f5586b2696f79c (diff) | |
download | gnutls-6e803c7631829a527497fef23084532fd83980c4.tar.gz |
Added gnutls_certificate_set_verify_function() to allow checking (verifying)
certificate before the handshake is completed.
Diffstat (limited to 'lib')
-rw-r--r-- | lib/auth_cert.c | 26 | ||||
-rw-r--r-- | lib/auth_cert.h | 1 | ||||
-rw-r--r-- | lib/gnutls_alert.c | 1 | ||||
-rw-r--r-- | lib/gnutls_cert.c | 28 | ||||
-rw-r--r-- | lib/includes/gnutls/gnutls.h.in | 5 | ||||
-rw-r--r-- | lib/libgnutls.map | 1 |
6 files changed, 59 insertions, 3 deletions
diff --git a/lib/auth_cert.c b/lib/auth_cert.c index 8e4f4aa997..d8abec6132 100644 --- a/lib/auth_cert.c +++ b/lib/auth_cert.c @@ -1251,7 +1251,7 @@ _gnutls_proc_openpgp_server_certificate (gnutls_session_t session, gnutls_assert (); goto cleanup; } - + ret = 0; cleanup: @@ -1268,19 +1268,39 @@ int _gnutls_proc_cert_server_certificate (gnutls_session_t session, opaque * data, size_t data_size) { +int ret; +gnutls_certificate_credentials_t cred; + + cred = (gnutls_certificate_credentials_t) _gnutls_get_cred (session->key, GNUTLS_CRD_CERTIFICATE, NULL); + if (cred == NULL) + { + gnutls_assert(); + return GNUTLS_E_INSUFFICIENT_CREDENTIALS; + } + switch (session->security_parameters.cert_type) { #ifdef ENABLE_OPENPGP case GNUTLS_CRT_OPENPGP: - return _gnutls_proc_openpgp_server_certificate (session, + ret = _gnutls_proc_openpgp_server_certificate (session, data, data_size); + break; #endif case GNUTLS_CRT_X509: - return _gnutls_proc_x509_server_certificate (session, data, data_size); + ret = _gnutls_proc_x509_server_certificate (session, data, data_size); + break; default: gnutls_assert (); return GNUTLS_E_INTERNAL_ERROR; } + + if (ret == 0 && cred->verify_callback != NULL) + { + ret = cred->verify_callback (session); + if (ret != 0) ret = GNUTLS_E_CERTIFICATE_ERROR; + } + + return ret; } #define MAX_SIGN_ALGOS 2 diff --git a/lib/auth_cert.h b/lib/auth_cert.h index f7f752e2ab..40c2ce8271 100644 --- a/lib/auth_cert.h +++ b/lib/auth_cert.h @@ -93,6 +93,7 @@ typedef struct gnutls_certificate_credentials_st gnutls_certificate_client_retrieve_function *client_get_cert_callback; gnutls_certificate_server_retrieve_function *server_get_cert_callback; + gnutls_certificate_verify_function *verify_callback; } certificate_credentials_st; typedef struct rsa_info_st diff --git a/lib/gnutls_alert.c b/lib/gnutls_alert.c index 71aae45f5c..21e9017894 100644 --- a/lib/gnutls_alert.c +++ b/lib/gnutls_alert.c @@ -196,6 +196,7 @@ gnutls_error_to_alert (int err, int *level) case GNUTLS_E_ASN1_TYPE_ANY_ERROR: case GNUTLS_E_ASN1_SYNTAX_ERROR: case GNUTLS_E_ASN1_DER_OVERFLOW: + case GNUTLS_E_CERTIFICATE_ERROR: ret = GNUTLS_A_BAD_CERTIFICATE; _level = GNUTLS_AL_FATAL; break; diff --git a/lib/gnutls_cert.c b/lib/gnutls_cert.c index a74ccf0107..9f1d1b1354 100644 --- a/lib/gnutls_cert.c +++ b/lib/gnutls_cert.c @@ -425,6 +425,34 @@ void gnutls_certificate_server_set_retrieve_function cred->server_get_cert_callback = func; } +/** + * gnutls_certificate_set_verify_function: + * @cred: is a #gnutls_certificate_credentials_t structure. + * @func: is the callback function + * + * This function sets a callback to be called when peer's certificate + * has been received in order to verify it on receipt rather than + * doing after the handshake is completed. + * + * The callback's function prototype is: + * int (*callback)(gnutls_session_t); + * + * If the callback function is provided then gnutls will call it, in the + * handshake, just after the certificate message has been received. + * To verify or obtain the certificate the gnutls_certificate_verify_peers2(), + * gnutls_certificate_type_get(), gnutls_certificate_get_peers() functions + * can be used. + * + * The callback function should return 0 for the handshake to continue + * or non-zero to terminate. + **/ +void gnutls_certificate_set_verify_function + (gnutls_certificate_credentials_t cred, + gnutls_certificate_verify_function * func) +{ + cred->verify_callback = func; +} + /*- * _gnutls_x509_extract_certificate_activation_time - return the peer's certificate activation time * @cert: should contain an X.509 DER encoded certificate diff --git a/lib/includes/gnutls/gnutls.h.in b/lib/includes/gnutls/gnutls.h.in index ffe5a79416..26a979dbc6 100644 --- a/lib/includes/gnutls/gnutls.h.in +++ b/lib/includes/gnutls/gnutls.h.in @@ -1453,6 +1453,8 @@ extern "C" { typedef int gnutls_certificate_server_retrieve_function (gnutls_session_t, gnutls_retr_st *); + typedef int gnutls_certificate_verify_function( gnutls_session_t); + /* Functions that allow auth_info_t structures handling */ @@ -1507,6 +1509,9 @@ extern "C" { (gnutls_certificate_credentials_t cred, gnutls_certificate_server_retrieve_function * func); + void gnutls_certificate_set_verify_function( + gnutls_certificate_credentials_t cred, gnutls_certificate_verify_function * func); + void gnutls_certificate_server_set_request (gnutls_session_t session, gnutls_certificate_request_t req); diff --git a/lib/libgnutls.map b/lib/libgnutls.map index bec2db07b1..a69a39514f 100644 --- a/lib/libgnutls.map +++ b/lib/libgnutls.map @@ -598,6 +598,7 @@ GNUTLS_2_10 gnutls_hmac_fast; gnutls_hmac_deinit; gnutls_hmac_output; + gnutls_certificate_set_verify_function; } GNUTLS_2_8; GNUTLS_PRIVATE { |