summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorNikos Mavrogiannopoulos <nmav@gnutls.org>2010-03-17 17:52:36 +0100
committerNikos Mavrogiannopoulos <nmav@gnutls.org>2010-03-17 17:53:26 +0100
commit6e803c7631829a527497fef23084532fd83980c4 (patch)
treef275431a981ca81e58dd3f57d9c3602ebdd7d272 /lib
parentfe279dc234c04712086b810567f5586b2696f79c (diff)
downloadgnutls-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.c26
-rw-r--r--lib/auth_cert.h1
-rw-r--r--lib/gnutls_alert.c1
-rw-r--r--lib/gnutls_cert.c28
-rw-r--r--lib/includes/gnutls/gnutls.h.in5
-rw-r--r--lib/libgnutls.map1
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 {