diff options
author | Nikos Mavrogiannopoulos <nmav@gnutls.org> | 2011-04-21 00:21:56 +0200 |
---|---|---|
committer | Nikos Mavrogiannopoulos <nmav@gnutls.org> | 2011-04-21 00:21:56 +0200 |
commit | 6e4e6b0aa30acc8db68fcc19a9406abcfe44ae9c (patch) | |
tree | 60b638467e98c287fe8ba3a28340e6ddab632819 | |
parent | ce1ceebc782aa6b920ceaef7754e9f87bb0820d0 (diff) | |
download | gnutls-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.c | 98 | ||||
-rw-r--r-- | lib/auth/cert.c | 40 | ||||
-rw-r--r-- | lib/auth/cert.h | 6 | ||||
-rw-r--r-- | lib/gnutls_cert.c | 48 | ||||
-rw-r--r-- | lib/includes/gnutls/abstract.h | 22 | ||||
-rw-r--r-- | lib/includes/gnutls/gnutls.h.in | 21 | ||||
-rw-r--r-- | lib/libgnutls.map | 1 | ||||
-rw-r--r-- | src/certtool.c | 2 | ||||
-rw-r--r-- | src/cli.c | 244 | ||||
-rw-r--r-- | tests/x509dn.c | 5 |
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; @@ -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 */ |