summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikos Mavrogiannopoulos <nmav@gnutls.org>2011-04-21 00:21:56 +0200
committerNikos Mavrogiannopoulos <nmav@gnutls.org>2011-04-21 00:21:56 +0200
commit6e4e6b0aa30acc8db68fcc19a9406abcfe44ae9c (patch)
tree60b638467e98c287fe8ba3a28340e6ddab632819
parentce1ceebc782aa6b920ceaef7754e9f87bb0820d0 (diff)
downloadgnutls-6e4e6b0aa30acc8db68fcc19a9406abcfe44ae9c.tar.gz
Added gnutls_certificate_set_retrieve_function2() to replace
gnutls_certificate_set_retrieve_function(). The new one is a efficient for busy servers because it eliminates the need for the server to encode the certificate to DER format.
-rw-r--r--doc/examples/ex-cert-select.c98
-rw-r--r--lib/auth/cert.c40
-rw-r--r--lib/auth/cert.h6
-rw-r--r--lib/gnutls_cert.c48
-rw-r--r--lib/includes/gnutls/abstract.h22
-rw-r--r--lib/includes/gnutls/gnutls.h.in21
-rw-r--r--lib/libgnutls.map1
-rw-r--r--src/certtool.c2
-rw-r--r--src/cli.c244
-rw-r--r--tests/x509dn.c5
10 files changed, 259 insertions, 228 deletions
diff --git a/doc/examples/ex-cert-select.c b/doc/examples/ex-cert-select.c
index 09b9a5e57c..461820cb4e 100644
--- a/doc/examples/ex-cert-select.c
+++ b/doc/examples/ex-cert-select.c
@@ -13,6 +13,7 @@
#include <unistd.h>
#include <gnutls/gnutls.h>
#include <gnutls/x509.h>
+#include <gnutls/abstract.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
@@ -30,13 +31,15 @@
extern int tcp_connect (void);
extern void tcp_close (int sd);
-static int cert_callback (gnutls_session_t session,
- const gnutls_datum_t * req_ca_rdn, int nreqs,
- const gnutls_pk_algorithm_t * sign_algos,
- int sign_algos_length, gnutls_retr2_st * st);
+static int
+cert_callback (gnutls_session_t session,
+ const gnutls_datum_t * req_ca_rdn, int nreqs,
+ const gnutls_pk_algorithm_t * sign_algos,
+ int sign_algos_length, gnutls_pcert_st** pcert,
+ unsigned int *pcert_length, gnutls_privkey_t* pkey);
-gnutls_x509_crt_t crt;
-gnutls_x509_privkey_t key;
+gnutls_pcert_st crt;
+gnutls_privkey_t key;
/* Helper functions to load a certificate and key
* files into memory.
@@ -77,19 +80,19 @@ load_keys (void)
{
int ret;
gnutls_datum_t data;
+ gnutls_x509_privkey_t x509_key;
data = load_file (CERT_FILE);
if (data.data == NULL)
{
- fprintf (stderr, "*** Error loading cert file.\n");
+ fprintf (stderr, "*** Error loading certificate file.\n");
exit (1);
}
- gnutls_x509_crt_init (&crt);
-
- ret = gnutls_x509_crt_import (crt, &data, GNUTLS_X509_FMT_PEM);
+
+ ret = gnutls_pcert_import_x509_raw(&crt, &data, GNUTLS_X509_FMT_PEM, 0);
if (ret < 0)
{
- fprintf (stderr, "*** Error loading key file: %s\n",
+ fprintf (stderr, "*** Error loading certificate file: %s\n",
gnutls_strerror (ret));
exit (1);
}
@@ -103,9 +106,9 @@ load_keys (void)
exit (1);
}
- gnutls_x509_privkey_init (&key);
+ gnutls_x509_privkey_init (&x509_key);
- ret = gnutls_x509_privkey_import (key, &data, GNUTLS_X509_FMT_PEM);
+ ret = gnutls_x509_privkey_import (x509_key, &data, GNUTLS_X509_FMT_PEM);
if (ret < 0)
{
fprintf (stderr, "*** Error loading key file: %s\n",
@@ -113,8 +116,17 @@ load_keys (void)
exit (1);
}
- unload_file (data);
+ gnutls_privkey_init (&key);
+ ret = gnutls_privkey_import_x509(key, x509_key, GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE);
+ if (ret < 0)
+ {
+ fprintf (stderr, "*** Error importing key: %s\n",
+ gnutls_strerror (ret));
+ exit (1);
+ }
+
+ unload_file (data);
}
int
@@ -143,7 +155,7 @@ main (void)
*/
gnutls_certificate_set_x509_trust_file (xcred, CAFILE, GNUTLS_X509_FMT_PEM);
- gnutls_certificate_set_retrieve_function (xcred, cert_callback);
+ gnutls_certificate_set_retrieve_function2 (xcred, cert_callback);
/* Initialize TLS session
*/
@@ -225,7 +237,8 @@ static int
cert_callback (gnutls_session_t session,
const gnutls_datum_t * req_ca_rdn, int nreqs,
const gnutls_pk_algorithm_t * sign_algos,
- int sign_algos_length, gnutls_retr2_st * st)
+ int sign_algos_length, gnutls_pcert_st** pcert,
+ unsigned int *pcert_length, gnutls_privkey_t* pkey)
{
char issuer_dn[256];
int i, ret;
@@ -255,59 +268,12 @@ cert_callback (gnutls_session_t session,
* The certificate must be of any of the "sign algorithms"
* supported by the server.
*/
-
type = gnutls_certificate_type_get (session);
if (type == GNUTLS_CRT_X509)
{
- /* check if the certificate we are sending is signed
- * with an algorithm that the server accepts */
- gnutls_sign_algorithm_t cert_algo, req_algo;
- int i, match = 0;
-
- ret = gnutls_x509_crt_get_signature_algorithm (crt);
- if (ret < 0)
- {
- /* error reading signature algorithm
- */
- return -1;
- }
- cert_algo = ret;
-
- i = 0;
- do
- {
- ret = gnutls_sign_algorithm_get_requested (session, i, &req_algo);
- if (ret >= 0 && cert_algo == req_algo)
- {
- match = 1;
- break;
- }
-
- /* server has not requested anything specific */
- if (i == 0 && ret == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
- {
- match = 1;
- break;
- }
- i++;
- }
- while (ret >= 0);
-
- if (match == 0)
- {
- printf
- ("- Could not find a suitable certificate to send to server\n");
- return -1;
- }
-
- st->cert_type = type;
- st->ncerts = 1;
-
- st->cert.x509 = &crt;
- st->key.x509 = key;
- st->key_type = GNUTLS_PRIVKEY_X509;
-
- st->deinit_all = 0;
+ *pcert_length = 1;
+ *pcert = &crt;
+ *pkey = key;
}
else
{
diff --git a/lib/auth/cert.c b/lib/auth/cert.c
index 39cf8edbd0..ac87412c48 100644
--- a/lib/auth/cert.c
+++ b/lib/auth/cert.c
@@ -459,6 +459,8 @@ call_get_cert_callback (gnutls_session_t session,
gnutls_certificate_type_t type = gnutls_certificate_type_get (session);
gnutls_certificate_credentials_t cred;
gnutls_retr2_st st2;
+ gnutls_pcert_st *pcert = NULL;
+ unsigned int pcert_length = 0;
cred = (gnutls_certificate_credentials_t)
_gnutls_get_cred (session->key, GNUTLS_CRD_CERTIFICATE, NULL);
@@ -470,7 +472,31 @@ call_get_cert_callback (gnutls_session_t session,
memset (&st2, 0, sizeof (st2));
- if (cred->get_cert_callback)
+ if (cred->get_cert_callback2)
+ {
+ /* we avoid all allocations and transformations */
+ ret = cred->get_cert_callback2 (session, issuers_dn, issuers_dn_length,
+ pk_algos, pk_algos_length,
+ &pcert, &pcert_length, &local_key);
+ if (ret < 0)
+ return gnutls_assert_val(GNUTLS_E_USER_ERROR);
+
+ if (pcert_length > 0 && type != pcert[0].type)
+ return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
+
+ if (pcert_length == 0)
+ {
+ pcert = NULL;
+ local_key = NULL;
+ }
+ _gnutls_selected_certs_set (session, pcert,
+ pcert_length,
+ local_key, 0);
+
+ return 0;
+
+ }
+ else if (cred->get_cert_callback)
{
ret = cred->get_cert_callback (session, issuers_dn, issuers_dn_length,
pk_algos, pk_algos_length, &st2);
@@ -511,7 +537,7 @@ call_get_cert_callback (gnutls_session_t session,
if (ret < 0)
{
gnutls_assert ();
- return GNUTLS_E_INTERNAL_ERROR;
+ return GNUTLS_E_USER_ERROR;
}
if (st2.ncerts == 0)
@@ -663,7 +689,7 @@ _select_client_cert (gnutls_session_t session,
}
if (cred->client_get_cert_callback != NULL
- || cred->get_cert_callback != NULL)
+ || cred->get_cert_callback != NULL || cred->get_cert_callback2 != NULL)
{
/* use a callback to get certificate
@@ -2046,7 +2072,8 @@ _gnutls_server_select_cert (gnutls_session_t session,
/* If the callback which retrieves certificate has been set,
* use it and leave.
*/
- if (cred->server_get_cert_callback != NULL)
+ if (cred->server_get_cert_callback != NULL || cred->server_get_cert_callback ||
+ cred->get_cert_callback2)
{
ret = call_get_cert_callback (session, NULL, 0, NULL, 0);
if (ret < 0)
@@ -2074,11 +2101,10 @@ _gnutls_server_select_cert (gnutls_session_t session,
if (requested_algo == GNUTLS_PK_ANY ||
requested_algo == pk)
{
- /* if cert type and signature algorithm matches
+ /* if cert type matches
*/
/* *INDENT-OFF* */
- if (session->security_parameters.cert_type == cred->cert_list[i][0].type
- && (cred->cert_list[i][0].type == GNUTLS_CRT_OPENPGP))
+ if (session->security_parameters.cert_type == cred->cert_list[i][0].type)
{
idx = i;
break;
diff --git a/lib/auth/cert.h b/lib/auth/cert.h
index d26935bdc1..d8e29ddb79 100644
--- a/lib/auth/cert.h
+++ b/lib/auth/cert.h
@@ -84,11 +84,15 @@ typedef struct gnutls_certificate_credentials_st
*/
gnutls_datum_t x509_rdn_sequence;
+ /* It's a mess here. However we need to keep the old 3 functions
+ * for compatibility */
+ gnutls_certificate_retrieve_function *get_cert_callback; /* deprecated */
gnutls_certificate_client_retrieve_function *client_get_cert_callback; /* deprecated */
gnutls_certificate_server_retrieve_function *server_get_cert_callback; /* deprecated */
+ gnutls_certificate_retrieve_function2 *get_cert_callback2;
+
gnutls_certificate_verify_function *verify_callback;
- gnutls_certificate_retrieve_function *get_cert_callback;
} certificate_credentials_st;
typedef struct rsa_info_st
diff --git a/lib/gnutls_cert.c b/lib/gnutls_cert.c
index f587f16b39..91ad7caccf 100644
--- a/lib/gnutls_cert.c
+++ b/lib/gnutls_cert.c
@@ -305,6 +305,8 @@ gnutls_certificate_server_set_request (gnutls_session_t session,
*
* This function sets a callback to be called in order to retrieve the
* certificate to be used in the handshake.
+ * You are advised to use gnutls_certificate_set_retrieve_function2() because it
+ * is much more efficient in the processing it requires from gnutls.
*
* The callback's function prototype is:
* int (*callback)(gnutls_session_t, const gnutls_datum_t* req_ca_dn, int nreqs,
@@ -343,6 +345,8 @@ void gnutls_certificate_client_set_retrieve_function
*
* This function sets a callback to be called in order to retrieve the
* certificate to be used in the handshake.
+ * You are advised to use gnutls_certificate_set_retrieve_function2() because it
+ * is much more efficient in the processing it requires from gnutls.
*
* The callback's function prototype is:
* int (*callback)(gnutls_session_t, gnutls_retr_st* st);
@@ -369,7 +373,9 @@ void gnutls_certificate_server_set_retrieve_function
* @func: is the callback function
*
* This function sets a callback to be called in order to retrieve the
- * certificate to be used in the handshake.
+ * certificate to be used in the handshake. You are advised
+ * to use gnutls_certificate_set_retrieve_function2() because it
+ * is much more efficient in the processing it requires from gnutls.
*
* The callback's function prototype is:
* int (*callback)(gnutls_session_t, const gnutls_datum_t* req_ca_dn, int nreqs,
@@ -404,6 +410,46 @@ void gnutls_certificate_set_retrieve_function
}
/**
+ * gnutls_certificate_set_retrieve_function2:
+ * @cred: is a #gnutls_certificate_credentials_t structure.
+ * @func: is the callback function
+ *
+ * This function sets a callback to be called in order to retrieve the
+ * certificate to be used in the handshake.
+ *
+ * The callback's function prototype is:
+ * int (*callback)(gnutls_session_t, const gnutls_datum_t* req_ca_dn, int nreqs,
+ * const gnutls_pk_algorithm_t* pk_algos, int pk_algos_length, gnutls_pcert_st* st);
+ *
+ * @req_ca_cert is only used in X.509 certificates.
+ * Contains a list with the CA names that the server considers trusted.
+ * Normally we should send a certificate that is signed
+ * by one of these CAs. These names are DER encoded. To get a more
+ * meaningful value use the function gnutls_x509_rdn_get().
+ *
+ * @pk_algos contains a list with server's acceptable signature algorithms.
+ * The certificate returned should support the server's given algorithms.
+ *
+ * @st should contain the certificates and private keys.
+ *
+ * If the callback function is provided then gnutls will call it, in the
+ * handshake, after the certificate request message has been received.
+ *
+ * In server side pk_algos and req_ca_dn are NULL.
+ *
+ * The callback function should set the certificate list to be sent,
+ * and return 0 on success. If no certificate was selected then the
+ * number of certificates should be set to zero. The value (-1)
+ * indicates error and the handshake will be terminated.
+ **/
+void gnutls_certificate_set_retrieve_function2
+ (gnutls_certificate_credentials_t cred,
+ gnutls_certificate_retrieve_function2 * func)
+{
+ cred->get_cert_callback2 = func;
+}
+
+/**
* gnutls_certificate_set_verify_function:
* @cred: is a #gnutls_certificate_credentials_t structure.
* @func: is the callback function
diff --git a/lib/includes/gnutls/abstract.h b/lib/includes/gnutls/abstract.h
index 85a427ff41..3c6274fc21 100644
--- a/lib/includes/gnutls/abstract.h
+++ b/lib/includes/gnutls/abstract.h
@@ -181,5 +181,27 @@ int gnutls_pcert_import_openpgp (gnutls_pcert_st* pcert,
void gnutls_pcert_deinit (gnutls_pcert_st* pcert);
+/* For certificate credentials */
+ /* This is the same as gnutls_certificate_retrieve_function()
+ * but retrieves a gnutls_pcert_st which requires much less processing
+ * within the library.
+ */
+ typedef int gnutls_certificate_retrieve_function2 (gnutls_session_t,
+ const gnutls_datum_t *
+ req_ca_rdn,
+ int nreqs,
+ const
+ gnutls_pk_algorithm_t
+ * pk_algos,
+ int pk_algos_length,
+ gnutls_pcert_st **,
+ unsigned int *pcert_length,
+ gnutls_privkey_t *privkey);
+
+
+ void gnutls_certificate_set_retrieve_function2
+ (gnutls_certificate_credentials_t cred,
+ gnutls_certificate_retrieve_function2 * func);
+
#endif
diff --git a/lib/includes/gnutls/gnutls.h.in b/lib/includes/gnutls/gnutls.h.in
index 06f6f40505..0cdbffd27a 100644
--- a/lib/includes/gnutls/gnutls.h.in
+++ b/lib/includes/gnutls/gnutls.h.in
@@ -1479,25 +1479,10 @@ extern "C"
/* These are set on the credentials structure.
*/
-
- /* This is the same as gnutls_certificate_retrieve_function()
- * but retrieves a gnutls_pcert_st which requires much less processing
- * within the library.
- */
- typedef int gnutls_certificate_retrieve_function2 (gnutls_session_t,
- const gnutls_datum_t *
- req_ca_rdn,
- int nreqs,
- const
- gnutls_pk_algorithm_t
- * pk_algos,
- int pk_algos_length,
- gnutls_pcert_st *);
-
- void gnutls_certificate_set_retrieve_function2
- (gnutls_certificate_credentials_t cred,
- gnutls_certificate_retrieve_function2 * func);
+ /* use gnutls_certificate_set_retrieve_function2() in abstract.h
+ * instead. It's much more efficient.
+ */
typedef int gnutls_certificate_retrieve_function (gnutls_session_t,
const
diff --git a/lib/libgnutls.map b/lib/libgnutls.map
index 0b93d68549..87d70cc37b 100644
--- a/lib/libgnutls.map
+++ b/lib/libgnutls.map
@@ -708,6 +708,7 @@ GNUTLS_3_0_0 {
gnutls_pcert_import_openpgp;
gnutls_pcert_import_openpgp_raw;
gnutls_pubkey_get_openpgp_key_id;
+ gnutls_certificate_set_retrieve_function2;
} GNUTLS_2_12;
GNUTLS_PRIVATE {
diff --git a/src/certtool.c b/src/certtool.c
index 9800bfb259..1809660618 100644
--- a/src/certtool.c
+++ b/src/certtool.c
@@ -1317,7 +1317,7 @@ void
pgp_privkey_info (void)
{
gnutls_openpgp_privkey_t key;
- gnutls_openpgp_keyid_t keyid;
+ unsigned char keyid[GNUTLS_OPENPGP_KEYID_SIZE];
size_t size;
int ret, i, subkeys;
gnutls_datum_t pem;
diff --git a/src/cli.c b/src/cli.c
index 31eb80e0f5..88aa645999 100644
--- a/src/cli.c
+++ b/src/cli.c
@@ -34,8 +34,8 @@
#include <error.h>
#include <gnutls/gnutls.h>
+#include <gnutls/abstract.h>
#include <gnutls/dtls.h>
-#include <gnutls/extra.h>
#include <gnutls/x509.h>
#include <gnutls/openpgp.h>
#include <gnutls/pkcs11.h>
@@ -135,13 +135,11 @@ unload_file (gnutls_datum_t data)
#define MAX_CRT 6
static unsigned int x509_crt_size;
-static gnutls_x509_crt_t x509_crt[MAX_CRT];
-static gnutls_x509_privkey_t x509_key = NULL;
+static gnutls_pcert_st x509_crt[MAX_CRT];
+static gnutls_privkey_t x509_key = NULL;
-static gnutls_pkcs11_privkey_t pkcs11_key = NULL;
-
-static gnutls_openpgp_crt_t pgp_crt = NULL;
-static gnutls_openpgp_privkey_t pgp_key = NULL;
+static gnutls_pcert_st pgp_crt;
+static gnutls_privkey_t pgp_key = NULL;
static void
get_keyid (gnutls_openpgp_keyid_t keyid, const char *str)
@@ -170,22 +168,26 @@ static void
load_keys (void)
{
unsigned int crt_num;
- int ret;
+ int ret, i;
gnutls_datum_t data;
+ gnutls_x509_crt_t crt_list[MAX_CRT];
+ gnutls_pkcs11_privkey_t pkcs11_key;
+ gnutls_x509_privkey_t tmp_key;
+ uint8_t keyid[GNUTLS_OPENPGP_KEYID_SIZE];
if (x509_certfile != NULL && x509_keyfile != NULL)
{
if (strncmp (x509_certfile, "pkcs11:", 7) == 0)
{
crt_num = 1;
- gnutls_x509_crt_init (&x509_crt[0]);
+ gnutls_x509_crt_init (&crt_list[0]);
ret =
- gnutls_x509_crt_import_pkcs11_url (x509_crt[0], x509_certfile, 0);
+ gnutls_x509_crt_import_pkcs11_url (crt_list[0], x509_certfile, 0);
if (ret == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
ret =
- gnutls_x509_crt_import_pkcs11_url (x509_crt[0], x509_certfile,
+ gnutls_x509_crt_import_pkcs11_url (crt_list[0], x509_certfile,
GNUTLS_PKCS11_OBJ_FLAG_LOGIN);
if (ret < 0)
@@ -207,7 +209,7 @@ load_keys (void)
crt_num = MAX_CRT;
ret =
- gnutls_x509_crt_list_import (x509_crt, &crt_num, &data,
+ gnutls_x509_crt_list_import (crt_list, &crt_num, &data,
GNUTLS_X509_FMT_PEM,
GNUTLS_X509_CRT_LIST_IMPORT_FAIL_IF_EXCEED);
if (ret < 0)
@@ -229,10 +231,29 @@ load_keys (void)
}
x509_crt_size = ret;
}
- fprintf (stdout, "Processed %d client certificates...\n", ret);
+
+ for (i=0;i<x509_crt_size;i++)
+ {
+ ret = gnutls_pcert_import_x509(&x509_crt[i], crt_list[i], 0);
+ if (ret < 0)
+ {
+ fprintf(stderr, "*** Error importing crt to pcert: %s\n",
+ gnutls_strerror(ret));
+ exit(1);
+ }
+ gnutls_x509_crt_deinit(crt_list[i]);
+ }
unload_file (data);
+ ret = gnutls_privkey_init(&x509_key);
+ if (ret < 0)
+ {
+ fprintf (stderr, "*** Error initializing key: %s\n",
+ gnutls_strerror (ret));
+ exit (1);
+ }
+
if (strncmp (x509_keyfile, "pkcs11:", 7) == 0)
{
gnutls_pkcs11_privkey_init (&pkcs11_key);
@@ -245,6 +266,14 @@ load_keys (void)
gnutls_strerror (ret));
exit (1);
}
+
+ ret = gnutls_privkey_import_pkcs11( x509_key, pkcs11_key, GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE);
+ if (ret < 0)
+ {
+ fprintf (stderr, "*** Error loading url: %s\n",
+ gnutls_strerror (ret));
+ exit (1);
+ }
}
else
{
@@ -255,10 +284,10 @@ load_keys (void)
exit (1);
}
- gnutls_x509_privkey_init (&x509_key);
+ gnutls_x509_privkey_init (&tmp_key);
ret =
- gnutls_x509_privkey_import (x509_key, &data, GNUTLS_X509_FMT_PEM);
+ gnutls_x509_privkey_import (tmp_key, &data, GNUTLS_X509_FMT_PEM);
if (ret < 0)
{
fprintf (stderr, "*** Error loading key file: %s\n",
@@ -266,25 +295,43 @@ load_keys (void)
exit (1);
}
+ ret = gnutls_privkey_import_x509( x509_key, tmp_key, GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE);
+ if (ret < 0)
+ {
+ fprintf (stderr, "*** Error loading url: %s\n",
+ gnutls_strerror (ret));
+ exit (1);
+ }
+
unload_file (data);
}
fprintf (stdout, "Processed %d client X.509 certificates...\n",
x509_crt_size);
}
+
+
#ifdef ENABLE_OPENPGP
+ if (info.pgp_subkey != NULL)
+ {
+ get_keyid (keyid, info.pgp_subkey);
+ }
+
if (pgp_certfile != NULL && pgp_keyfile != NULL)
{
+ gnutls_openpgp_crt_t tmp_pgp_crt;
+
data = load_file (pgp_certfile);
if (data.data == NULL)
{
fprintf (stderr, "*** Error loading PGP cert file.\n");
exit (1);
}
- gnutls_openpgp_crt_init (&pgp_crt);
+
+ gnutls_openpgp_crt_init (&tmp_pgp_crt);
ret =
- gnutls_openpgp_crt_import (pgp_crt, &data, GNUTLS_OPENPGP_FMT_BASE64);
+ gnutls_pcert_import_openpgp_raw (&pgp_crt, &data, GNUTLS_OPENPGP_FMT_BASE64, info.pgp_subkey!=NULL?keyid:NULL, 0);
if (ret < 0)
{
fprintf (stderr,
@@ -292,10 +339,17 @@ load_keys (void)
gnutls_strerror (ret));
exit (1);
}
-
-
+
unload_file (data);
+ ret = gnutls_privkey_init(&pgp_key);
+ if (ret < 0)
+ {
+ fprintf (stderr, "*** Error initializing key: %s\n",
+ gnutls_strerror (ret));
+ exit (1);
+ }
+
if (strncmp (pgp_keyfile, "pkcs11:", 7) == 0)
{
gnutls_pkcs11_privkey_init (&pkcs11_key);
@@ -307,9 +361,18 @@ load_keys (void)
gnutls_strerror (ret));
exit (1);
}
+
+ ret = gnutls_privkey_import_pkcs11( pgp_key, pkcs11_key, GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE);
+ if (ret < 0)
+ {
+ fprintf (stderr, "*** Error loading url: %s\n",
+ gnutls_strerror (ret));
+ exit (1);
+ }
}
else
{
+ gnutls_openpgp_privkey_t tmp_pgp_key;
data = load_file (pgp_keyfile);
if (data.data == NULL)
@@ -318,10 +381,10 @@ load_keys (void)
exit (1);
}
- gnutls_openpgp_privkey_init (&pgp_key);
+ gnutls_openpgp_privkey_init (&tmp_pgp_key);
ret =
- gnutls_openpgp_privkey_import (pgp_key, &data,
+ gnutls_openpgp_privkey_import (tmp_pgp_key, &data,
GNUTLS_OPENPGP_FMT_BASE64, NULL,
0);
if (ret < 0)
@@ -332,40 +395,31 @@ load_keys (void)
exit (1);
}
- unload_file (data);
- }
-
- if (info.pgp_subkey != NULL)
- {
- gnutls_openpgp_keyid_t keyid;
-
- if (strcasecmp (info.pgp_subkey, "auto") == 0)
+ if (info.pgp_subkey != NULL)
{
- ret = gnutls_openpgp_crt_get_auth_subkey (pgp_crt, keyid, 1);
+ ret =
+ gnutls_openpgp_privkey_set_preferred_key_id (tmp_pgp_key, keyid);
if (ret < 0)
{
fprintf (stderr,
- "*** Error setting preferred sub key id (%s): %s\n",
- info.pgp_subkey, gnutls_strerror (ret));
+ "*** Error setting preferred sub key id (%s): %s\n",
+ info.pgp_subkey, gnutls_strerror (ret));
exit (1);
}
}
- else
- get_keyid (keyid, info.pgp_subkey);
- ret = gnutls_openpgp_crt_set_preferred_key_id (pgp_crt, keyid);
- if (ret >= 0)
- ret =
- gnutls_openpgp_privkey_set_preferred_key_id (pgp_key, keyid);
+ ret = gnutls_privkey_import_openpgp( pgp_key, tmp_pgp_key, GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE);
if (ret < 0)
{
- fprintf (stderr,
- "*** Error setting preferred sub key id (%s): %s\n",
- info.pgp_subkey, gnutls_strerror (ret));
+ fprintf (stderr, "*** Error loading url: %s\n",
+ gnutls_strerror (ret));
exit (1);
}
+
+ unload_file (data);
}
+
fprintf (stdout, "Processed 1 client PGP certificate...\n");
}
#endif
@@ -401,10 +455,11 @@ static int
cert_callback (gnutls_session_t session,
const gnutls_datum_t * req_ca_rdn, int nreqs,
const gnutls_pk_algorithm_t * sign_algos,
- int sign_algos_length, gnutls_retr2_st * st)
+ int sign_algos_length, gnutls_pcert_st **pcert,
+ unsigned int *pcert_length, gnutls_privkey_t * pkey)
{
char issuer_dn[256];
- int i, ret;
+ int i, ret, cert_type;
size_t len;
if (verbose)
@@ -434,62 +489,17 @@ cert_callback (gnutls_session_t session,
* supported by the server.
*/
- st->cert_type = gnutls_certificate_type_get (session);
+ cert_type = gnutls_certificate_type_get (session);
- st->ncerts = 0;
+ *pcert_length = 0;
- if (st->cert_type == GNUTLS_CRT_X509)
+ if (cert_type == GNUTLS_CRT_X509)
{
- gnutls_sign_algorithm_t cert_algo, req_algo;
- int i, match = 0;
-
if (x509_crt_size > 0)
{
- ret = gnutls_x509_crt_get_signature_algorithm (x509_crt[0]);
- if (ret < 0)
- {
- /* error reading signature algorithm */
- return -1;
- }
- cert_algo = ret;
-
- i = 0;
- do
- {
- ret =
- gnutls_sign_algorithm_get_requested (session, i, &req_algo);
- if (ret >= 0 && cert_algo == req_algo)
- {
- match = 1;
- break;
- }
-
- /* server has not requested anything specific */
- if (i == 0 && ret == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
- {
- match = 1;
- break;
- }
- i++;
- }
- while (ret >= 0);
-
- if (match == 0)
- {
- printf
- ("- Could not find a suitable certificate to send to server\n");
- return -1;
- }
-
if (x509_key != NULL)
{
- st->key.x509 = x509_key;
- st->key_type = GNUTLS_PRIVKEY_X509;
- }
- else if (pkcs11_key != NULL)
- {
- st->key.pkcs11 = pkcs11_key;
- st->key_type = GNUTLS_PRIVKEY_PKCS11;
+ *pkey = x509_key;
}
else
{
@@ -497,48 +507,23 @@ cert_callback (gnutls_session_t session,
return -1;
}
- st->ncerts = x509_crt_size;
-
- st->cert.x509 = x509_crt;
-
- st->deinit_all = 0;
-
- return 0;
+ *pcert_length = x509_crt_size;
+ *pcert = x509_crt;
}
}
- else if (st->cert_type == GNUTLS_CRT_OPENPGP)
+ else if (cert_type == GNUTLS_CRT_OPENPGP)
{
- if (pgp_crt != NULL)
+ if (pgp_key != NULL)
{
+ *pkey = pgp_key;
- if (pgp_key != NULL)
- {
- st->key.pgp = pgp_key;
- st->key_type = GNUTLS_PRIVKEY_OPENPGP;
- }
- else if (pkcs11_key != NULL)
- {
- st->key.pkcs11 = pkcs11_key;
- st->key_type = GNUTLS_PRIVKEY_PKCS11;
- }
- else
- {
- printf ("- Could not find a suitable key to send to server\n");
- return -1;
- }
-
- st->ncerts = 1;
-
- st->cert.pgp = pgp_crt;
-
- st->deinit_all = 0;
-
- return 0;
+ *pcert_length = 1;
+ *pcert = &pgp_crt;
}
}
- printf ("- Successfully sent %d certificate(s) to server.\n", st->ncerts);
+ printf ("- Successfully sent %u certificate(s) to server.\n", *pcert_length);
return 0;
}
@@ -586,7 +571,7 @@ init_tls_session (const char *hostname)
gnutls_credentials_set (session, GNUTLS_CRD_PSK, psk_cred);
gnutls_credentials_set (session, GNUTLS_CRD_CERTIFICATE, xcred);
- gnutls_certificate_set_retrieve_function (xcred, cert_callback);
+ gnutls_certificate_set_retrieve_function2 (xcred, cert_callback);
gnutls_certificate_set_verify_function (xcred, cert_verify_callback);
gnutls_certificate_set_verify_flags (xcred, 0);
@@ -741,12 +726,6 @@ main (int argc, char **argv)
exit (1);
}
- if ((ret = gnutls_global_init_extra ()) < 0)
- {
- fprintf (stderr, "global_init_extra: %s\n", gnutls_strerror (ret));
- exit (1);
- }
-
pkcs11_common ();
gaa_parser (argc, argv);
if (hostname == NULL)
@@ -1490,3 +1469,4 @@ socket_open (socket_st * hd, const char *hostname, const char *service)
return;
}
+
diff --git a/tests/x509dn.c b/tests/x509dn.c
index cf6cc2ba95..4ee44c14e7 100644
--- a/tests/x509dn.c
+++ b/tests/x509dn.c
@@ -115,7 +115,8 @@ static int
cert_callback (gnutls_session_t session,
const gnutls_datum_t * req_ca_rdn, int nreqs,
const gnutls_pk_algorithm_t * sign_algos,
- int sign_algos_length, gnutls_retr2_st * st)
+ int sign_algos_length, gnutls_pcert_st ** pcert,
+ unsigned int* pcert_length, gnutls_privkey_t *pkey)
{
int result;
gnutls_x509_dn_t dn;
@@ -199,7 +200,7 @@ client (void)
*/
gnutls_certificate_set_x509_trust_mem (xcred, &ca, GNUTLS_X509_FMT_PEM);
- gnutls_certificate_set_retrieve_function (xcred, cert_callback);
+ gnutls_certificate_set_retrieve_function2 (xcred, cert_callback);
/* Initialize TLS session
*/