cpw.ljfisher.ssl_client_auth: a83014d1: Fix compile fail caused by incorrect GNU...
lucas.fisher at gmail.com
lucas.fisher at gmail.com
Mon Oct 17 21:26:50 EDT 2011
----------------------------------------------------------------------
Revision: a83014d1baf03d346c300c20e805f13d75fc8de5
Parent: 7a978bb5fcaa2b8f8806173bb422b1d8c0f47c5e
Author: lucas.fisher at gmail.com
Date: 10/17/11 21:22:44
Branch: im.pidgin.cpw.ljfisher.ssl_client_auth
URL: http://d.pidgin.im/viewmtn/revision/info/a83014d1baf03d346c300c20e805f13d75fc8de5
Changelog:
Fix compile fail caused by incorrect GNUTLS_VERSION_* define use.
Use a callback to retrieve client certs to give us more flexibility in choosing the cert.
Changes against parent 7a978bb5fcaa2b8f8806173bb422b1d8c0f47c5e
patched libpurple/plugins/ssl/ssl-gnutls.c
-------------- next part --------------
============================================================
--- libpurple/plugins/ssl/ssl-gnutls.c e515363a3ed21b601dfeb839050beb200ca583cd
+++ libpurple/plugins/ssl/ssl-gnutls.c 973a62b7d211caecd8d885ebcd42c5dc3ce7f847
@@ -73,7 +73,7 @@ gnutls_get_default_crypt_flags()
static unsigned int
gnutls_get_default_crypt_flags()
{
-#if GNUTLS_MAJOR_VERSION >= 2 && GNUTLS_MINOR_VERSION >= 10
+#if GNUTLS_VERSION_MAJOR >= 2 && GNUTLS_VERSION_MINOR >= 10
purple_debug_info("gnutls", "Using AES 256 to encrypt.\n");
return GNUTLS_PKCS_USE_PBES2_AES_256;
#else
@@ -89,6 +89,49 @@ ssl_gnutls_log(int level, const char *st
purple_debug_misc("gnutls", "lvl %d: %s", level, str);
}
+
+/*
+ * GNUTLS doesn't offer a means to pass custom context to the certificate
+ * retrieve function (yeah, not good design) so we have to declare globals
+ * to hold the cert/key chosen by the user. We don't just set the
+ * gnutls_certificate_client_creds and let gnutls figure it out because servers
+ * aren't good about listing all intermediate CAs in the CERTIFICATE REQUEST
+ * message. This will break clients that have a cert issued by an intermediate
+ * CA. We just return whatever cert the client selected instead.
+ */
+static gnutls_x509_crt_t client_auth_certs[1] = { NULL };
+static gnutls_x509_privkey_t client_auth_key = NULL;
+
+static int
+ssl_gnutls_certificate_retrieve_function(
+ gnutls_session_t session,
+ const gnutls_datum_t* req_ca_dn, int nreqs,
+ const gnutls_pk_algorithm_t* pk_algos, int pk_algos_length,
+ gnutls_retr_st* st)
+{
+ if (NULL == client_auth_certs[0]) {
+ purple_debug_error("gnutls", "Tried to retrieve a client cert but none was set.\n");
+ return -1;
+ }
+
+ if (NULL == client_auth_key) {
+ purple_debug_error("gnutls", "Tried to retrieve a client key but none was set.\n");
+ return -1;
+ }
+
+ purple_debug_info("gnutls", "retrieving certificates for the ssl handshake\n");
+
+ /* TODO: Check that client_auth_certs algo matches pk_algos */
+
+ st->type = GNUTLS_CRT_X509;
+ st->cert.x509 = client_auth_certs;
+ st->ncerts = 1;
+ st->key.x509 = client_auth_key;
+ st->deinit_all = 0;
+
+ return 0;
+}
+
static void
ssl_gnutls_init_gnutls(void)
{
@@ -206,7 +249,8 @@ ssl_gnutls_init_gnutls(void)
/* TODO: I can likely remove this */
gnutls_certificate_set_x509_trust_file(xcred, "ca.pem",
GNUTLS_X509_FMT_PEM);
-// gnutls_certificate_set_x509_simple_pkcs12_file(xcred, "test.p12", GNUTLS_X509_FMT_DER, "abcd");
+
+ gnutls_certificate_client_set_retrieve_function(xcred, ssl_gnutls_certificate_retrieve_function);
}
static gboolean
@@ -2207,7 +2251,8 @@ static gboolean
**********************************************************************/
static gboolean
-ssl_gnutls_set_client_auth(gnutls_certificate_client_credentials cred, PurpleCertificate * pcrt, PurplePrivateKey * pkey)
+ssl_gnutls_set_client_auth(gnutls_certificate_client_credentials cred,
+ PurpleCertificate * pcrt, PurplePrivateKey * pkey)
{
gnutls_x509_crt_t cert_list[1];
int rv;
@@ -2217,8 +2262,14 @@ ssl_gnutls_set_client_auth(gnutls_certif
g_return_val_if_fail(pcrt->scheme == &x509_gnutls, FALSE);
g_return_val_if_fail(pkey->scheme == &x509_key_gnutls, FALSE);
- if (NULL != xcred) {
+ if (NULL != xcred) {
+ /* Set global state for creds to return when server
+ * requests a client certificate */
+ client_auth_certs[0] = X509_GET_GNUTLS_DATA(pcrt);
+ client_auth_key = X509_GET_GNUTLS_KEYDATA(pkey);
+
cert_list[0] = X509_GET_GNUTLS_DATA(pcrt);
+#if 0
rv = gnutls_certificate_set_x509_key(cred, cert_list, 1, X509_GET_GNUTLS_KEYDATA(pkey));
if (GNUTLS_E_SUCCESS != rv) {
purple_debug_error("gnutls/ssl",
@@ -2226,6 +2277,7 @@ ssl_gnutls_set_client_auth(gnutls_certif
gnutls_strerror(rv));
return FALSE;
}
+#endif
return TRUE;
}
More information about the Commits
mailing list