summaryrefslogtreecommitdiff
path: root/src/ne_gnutls.c
diff options
context:
space:
mode:
authorjoe <joe@61a7d7f5-40b7-0310-9c16-bb0ea8cb1845>2008-02-06 21:31:30 +0000
committerjoe <joe@61a7d7f5-40b7-0310-9c16-bb0ea8cb1845>2008-02-06 21:31:30 +0000
commit6128883f676a8ecf9aa918eb8d3523a895bed6a8 (patch)
treece0ef015db165af94c85ddc8658632686f524854 /src/ne_gnutls.c
parentf4a8bb343cad90605e113abb7d8778cca1d7c1bc (diff)
downloadneon-6128883f676a8ecf9aa918eb8d3523a895bed6a8.tar.gz
Initial support for PKCS#11, based on the pakchois PKCS#11 library:
* src/ne_pkcs11.c, src/ne_pkcs11: New files. * src/ne_gnutls.c (struct ne_ssl_client_cert_s): Add keyless flag. (dup_client_cert): Support keyless clicerts. (ne__ssl_clicert_exkey_import): New function. (provide_client_cert): Use proper GnuTLS error codes in failure cases. * src/ne_privssl.h (ne__ssl_clicert_exkey_import) [HAVE_GNUTLS]: Add prototype. * src/ne_private.h: Include ne_pkcs11.h. (struct ne_session_s): Add pin callback and userdata. * src/ne_session.c (ne_ssl_set_pkcs11_pin): New function. * src/Makefile.in, neon.mak: Build ne_pkcs11.c. * macros/neon.m4 (NEON_SSL): Check for pakchois. git-svn-id: http://svn.webdav.org/repos/projects/neon/trunk@1329 61a7d7f5-40b7-0310-9c16-bb0ea8cb1845
Diffstat (limited to 'src/ne_gnutls.c')
-rw-r--r--src/ne_gnutls.c48
1 files changed, 39 insertions, 9 deletions
diff --git a/src/ne_gnutls.c b/src/ne_gnutls.c
index 0a1fe33..1dfbe52 100644
--- a/src/ne_gnutls.c
+++ b/src/ne_gnutls.c
@@ -1,6 +1,6 @@
/*
neon SSL/TLS support using GNU TLS
- Copyright (C) 2002-2007, Joe Orton <joe@manyfish.co.uk>
+ Copyright (C) 2002-2008, Joe Orton <joe@manyfish.co.uk>
Copyright (C) 2004, Aleix Conchillo Flaque <aleix@member.fsf.org>
This library is free software; you can redistribute it and/or
@@ -69,6 +69,7 @@ struct ne_ssl_certificate_s {
struct ne_ssl_client_cert_s {
gnutls_pkcs12 p12;
int decrypted; /* non-zero if successfully decrypted. */
+ int keyless;
ne_ssl_certificate cert;
gnutls_x509_privkey pkey;
char *friendly_name;
@@ -502,13 +503,18 @@ static ne_ssl_client_cert *dup_client_cert(const ne_ssl_client_cert *cc)
ne_ssl_client_cert *newcc = ne_calloc(sizeof *newcc);
newcc->decrypted = 1;
-
- ret = gnutls_x509_privkey_init(&newcc->pkey);
- if (ret != 0) goto dup_error;
-
- ret = gnutls_x509_privkey_cpy(newcc->pkey, cc->pkey);
- if (ret != 0) goto dup_error;
+ if (cc->keyless) {
+ newcc->keyless = 1;
+ }
+ else {
+ ret = gnutls_x509_privkey_init(&newcc->pkey);
+ if (ret != 0) goto dup_error;
+
+ ret = gnutls_x509_privkey_cpy(newcc->pkey, cc->pkey);
+ if (ret != 0) goto dup_error;
+ }
+
newcc->cert.subject = x509_crt_copy(cc->cert.subject);
if (!newcc->cert.subject) goto dup_error;
@@ -533,7 +539,7 @@ static int provide_client_cert(gnutls_session session,
ne_session *sess = gnutls_session_get_ptr(session);
if (!sess) {
- return -1;
+ return GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER;
}
if (!sess->client_cert && sess->ssl_provide_fn) {
@@ -558,10 +564,11 @@ static int provide_client_cert(gnutls_session session,
/* tell GNU TLS not to deallocate the certs. */
st->deinit_all = 0;
} else {
- return -1;
+ return GNUTLS_E_UNSUPPORTED_CERTIFICATE_TYPE;
}
} else {
NE_DEBUG(NE_DBG_SSL, "No client certificate supplied.\n");
+ return GNUTLS_E_NO_CERTIFICATE_FOUND;
}
return 0;
@@ -938,6 +945,29 @@ ne_ssl_client_cert *ne_ssl_clicert_read(const char *filename)
}
}
+ne_ssl_client_cert *ne__ssl_clicert_exkey_import(const unsigned char *der,
+ size_t der_len)
+{
+ ne_ssl_client_cert *cc;
+ gnutls_x509_crt x5;
+ gnutls_datum datum;
+
+ datum.data = (unsigned char *)der;
+ datum.size = der_len;
+
+ if (gnutls_x509_crt_init(&x5)
+ || gnutls_x509_crt_import(x5, &datum, GNUTLS_X509_FMT_DER)) {
+ NE_DEBUG(NE_DBG_SSL, "ssl: crt_import failed.\n");
+ return NULL;
+ }
+
+ cc = ne_calloc(sizeof *cc);
+ cc->keyless = 1;
+ populate_cert(&cc->cert, x5);
+
+ return cc;
+}
+
int ne_ssl_clicert_encrypted(const ne_ssl_client_cert *cc)
{
return !cc->decrypted;