diff options
author | Nikos Mavrogiannopoulos <nmav@gnutls.org> | 2004-03-25 09:35:59 +0000 |
---|---|---|
committer | Nikos Mavrogiannopoulos <nmav@gnutls.org> | 2004-03-25 09:35:59 +0000 |
commit | 81ce41810c0c508a8f5fca995d003ab348d63c18 (patch) | |
tree | da72b59df451c150123cad9db524b4b7722e31f2 | |
parent | f31b8e682e28b826ad75d36ccbfbd574efdd2bb0 (diff) | |
download | gnutls-81ce41810c0c508a8f5fca995d003ab348d63c18.tar.gz |
Deprecated: gnutls_srp_server_set_select_function(),
gnutls_certificate_client_set_select_function(), gnutls_srp_server_set_select_function().
-rw-r--r-- | NEWS | 2 | ||||
-rw-r--r-- | configure.in | 2 | ||||
-rw-r--r-- | includes/gnutls/extra.h | 4 | ||||
-rw-r--r-- | lib/auth_cert.c | 199 | ||||
-rw-r--r-- | lib/gnutls_cert.c | 78 | ||||
-rw-r--r-- | lib/gnutls_global.c | 8 | ||||
-rw-r--r-- | lib/gnutls_int.h | 17 | ||||
-rw-r--r-- | lib/gnutls_ui.h | 15 | ||||
-rw-r--r-- | libextra/auth_srp_passwd.c | 14 | ||||
-rw-r--r-- | libextra/gnutls_srp.c | 34 | ||||
-rw-r--r-- | src/cli.c | 329 | ||||
-rw-r--r-- | src/tests.c | 8 |
12 files changed, 279 insertions, 431 deletions
@@ -6,6 +6,8 @@ Version 1.1.7 and gnutls_x509_privkey_cpy(). - Corrected a compilation issue when opencdk was installed in a non standard directory. +- Deprecated: gnutls_srp_server_set_select_function(), + gnutls_certificate_client_set_select_function(), gnutls_srp_server_set_select_function(). Version 1.1.6 (24/02/2004) - Several bug fixes, by Arne Thomassen. diff --git a/configure.in b/configure.in index 705def525b..910b1eaaf2 100644 --- a/configure.in +++ b/configure.in @@ -28,7 +28,7 @@ AM_CONFIG_HEADER(config.h) AM_MAINTAINER_MODE dnl This is the library version -GNUTLS_MOST_RECENT_INTERFACE=12 +GNUTLS_MOST_RECENT_INTERFACE=13 GNUTLS_CURRENT_INTERFACE_IMPLEMENTATION_NUMBER=$GNUTLS_MICRO_VERSION GNUTLS_OLDEST_INTERFACE=11 diff --git a/includes/gnutls/extra.h b/includes/gnutls/extra.h index ebfdcfd273..7df49b8d41 100644 --- a/includes/gnutls/extra.h +++ b/includes/gnutls/extra.h @@ -44,10 +44,6 @@ int gnutls_srp_set_server_credentials_file( gnutls_srp_server_credentials res, const char* gnutls_srp_server_get_username( gnutls_session state); -typedef int gnutls_srp_server_select_function(gnutls_session, const char **, const char**, unsigned int); -void gnutls_srp_server_set_select_function( gnutls_session, gnutls_srp_server_select_function *); - - int gnutls_srp_verifier( const char* username, const char* password, const gnutls_datum *salt, const gnutls_datum* g, const gnutls_datum* n, gnutls_datum * res); diff --git a/lib/auth_cert.c b/lib/auth_cert.c index f35bfaeeef..e54051254f 100644 --- a/lib/auth_cert.c +++ b/lib/auth_cert.c @@ -310,93 +310,6 @@ uint size; } -/* Calls the client_cert_callback() to select an index for the - * certificate to use. - */ -static int call_client_cert_callback(gnutls_session session, - const gnutls_certificate_credentials cred, gnutls_pk_algorithm * pk_algos, - int pk_algos_length, gnutls_datum * issuers_dn, uint issuers_dn_len) -{ - uint i, j; - int indx, result; - int *ij_map = NULL; - gnutls_datum *my_certs = NULL; - - if (cred->ncerts != 0) { - my_certs = - gnutls_alloca(cred->ncerts * - sizeof(gnutls_datum)); - if (my_certs == NULL) { - result = GNUTLS_E_MEMORY_ERROR; - gnutls_assert(); - goto error; - } - - - /* maps j -> i - */ - ij_map = gnutls_alloca(sizeof(int) * cred->ncerts); - if (ij_map == NULL) { - result = GNUTLS_E_MEMORY_ERROR; - gnutls_assert(); - goto error; - } - } - - /* put our certificate's issuer and dn into cdn, idn - * Note that the certificates we provide to the callback - * are not all the certificates we have. Only the certificates - * that are requested by the server (certificate type - and sign - * algorithm matches), are provided. - */ - for (j = i = 0; i < cred->ncerts; i++) { - if ((cred->cert_list[i][0].cert_type == - gnutls_certificate_type_get(session)) && - (_gnutls_check_pk_algo_in_list(pk_algos, - pk_algos_length, - cred-> - cert_list[i][0]. - subject_pk_algorithm) - == 0)) { - /* Add a certificate ONLY if it is allowed - * by the peer. - */ - ij_map[j] = i; - my_certs[j++] = cred->cert_list[i][0].raw; - } - } - - indx = - session->internals.client_cert_callback(session, - my_certs, - j, - issuers_dn, - issuers_dn_len); - - /* the indx returned by the user is relative - * to the certificates we provided him. - * This will make it relative to the certificates - * we've got. - */ - if (indx != -1 && cred->ncerts != 0) - indx = ij_map[indx]; - else - indx = -1; - - - result = indx; - - error: - if (my_certs != NULL) { - gnutls_afree(my_certs); - } - if (ij_map != NULL) { - gnutls_afree(ij_map); - } - return result; - -} - OPENPGP_KEY_DEINIT _E_gnutls_openpgp_key_deinit; OPENPGP_PRIVKEY_DEINIT _E_gnutls_openpgp_privkey_deinit; @@ -522,8 +435,7 @@ static int _select_client_cert(gnutls_session session, return GNUTLS_E_INSUFFICIENT_CREDENTIALS; } - if (cred->client_get_cert_callback != NULL || - session->internals.client_cert_callback != NULL) { + if (cred->client_get_cert_callback != NULL) { /* use a callback to get certificate */ @@ -547,16 +459,9 @@ static int _select_client_cert(gnutls_session session, } } - if (cred->client_get_cert_callback) { - result = call_get_cert_callback( session, issuers_dn, issuers_dn_length, - pk_algos, pk_algos_length); - goto cleanup; - } - - /* in case of the callback that returns an index: - */ - indx = call_client_cert_callback(session, cred, pk_algos, - pk_algos_length, issuers_dn, issuers_dn_length); + result = call_get_cert_callback( session, issuers_dn, issuers_dn_length, + pk_algos, pk_algos_length); + goto cleanup; } else { /* If we have no callbacks, try to guess. @@ -581,18 +486,18 @@ static int _select_client_cert(gnutls_session session, gnutls_assert(); return result; } - } - if (indx >= 0) { - _gnutls_selected_certs_set(session, + if (indx >= 0) { + _gnutls_selected_certs_set(session, &cred->cert_list[indx][0], cred->cert_list_length[indx], &cred->pkey[indx], 0); - } else { - _gnutls_selected_certs_set(session, NULL, 0, NULL, 0); - } + } else { + _gnutls_selected_certs_set(session, NULL, 0, NULL, 0); + } - result = 0; + result = 0; + } cleanup: gnutls_free( issuers_dn); @@ -1587,10 +1492,9 @@ void _gnutls_selected_certs_set(gnutls_session session, int _gnutls_server_select_cert(gnutls_session session, gnutls_pk_algorithm requested_algo) { - uint i, j; + uint i; int index, ret; const gnutls_certificate_credentials cred; - int my_certs_length; cred = _gnutls_get_cred(session->key, GNUTLS_CRD_CERTIFICATE, NULL); @@ -1599,6 +1503,16 @@ int _gnutls_server_select_cert(gnutls_session session, return GNUTLS_E_INSUFFICIENT_CREDENTIALS; } + /* If the callback which retrieves certificate has been + * set use it and leave. + */ + if (cred->server_get_cert_callback != NULL) { + + return call_get_cert_callback( session, NULL, 0, NULL, 0); + } + + /* Otherwise... */ + ret = 0; index = -1; /* default is use no certificate */ @@ -1615,75 +1529,8 @@ int _gnutls_server_select_cert(gnutls_session session, break; } } - } - - /* If the callback which retrieves certificate has been - * set use it. - */ - if (cred->server_get_cert_callback != NULL) { - - return call_get_cert_callback( session, NULL, 0, NULL, 0); - - } else if (session->internals.server_cert_callback != NULL - && cred->ncerts > 0) { - /* use the callback to get certificate - */ - gnutls_datum *my_certs; - int *ij_map; - - my_certs_length = cred->ncerts; - my_certs = - gnutls_malloc(my_certs_length * sizeof(gnutls_datum)); - if (my_certs == NULL) { - ret = GNUTLS_E_MEMORY_ERROR; - goto out; - } - - /* put our certificate's issuer and dn into cdn, idn - */ - ij_map = gnutls_malloc(my_certs_length * sizeof(int)); - if (ij_map == NULL) { - ret = GNUTLS_E_MEMORY_ERROR; - goto cleanup_certs; - } - - j = 0; - for (i = 0; i < cred->ncerts; i++) { - /* Add compatible certificates */ - if (requested_algo == (gnutls_pk_algorithm) - 1 || - requested_algo == - cred->cert_list[i][0].subject_pk_algorithm) { - - /* if cert type matches */ - if (session->security_parameters. - cert_type == - cred->cert_list[i][0].cert_type) { - - ij_map[j] = i; - my_certs[j++] = - cred->cert_list[i][0].raw; - } - } - } - my_certs_length = j; - - index = - session->internals.server_cert_callback(session, - my_certs, - my_certs_length); - - if (index != -1) - index = ij_map[index]; - ret = 0; - - gnutls_free(ij_map); - cleanup_certs: - gnutls_free(my_certs); - - } - - out: + /* store the index for future use, in the handshake. * (This will allow not calling this callback again.) */ diff --git a/lib/gnutls_cert.c b/lib/gnutls_cert.c index 67d1520da2..b611a9b9a5 100644 --- a/lib/gnutls_cert.c +++ b/lib/gnutls_cert.c @@ -303,84 +303,6 @@ void gnutls_certificate_server_set_request(gnutls_session session, session->internals.send_cert_req = req; } - -#define gnutls_certificate_client_select_function certificate_client_select_func - -/** - * gnutls_certificate_client_set_select_function - Used to set a callback while selecting the proper (client) certificate - * @session: is a &gnutls_session structure. - * @func: is the callback function - * - * This function sets a callback to be called while selecting the (client) certificate. - * The callback's function prototype is: - * int (*callback)(gnutls_session, const gnutls_datum *client_cert, int ncerts, const gnutls_datum* req_ca_dn, int nreqs); - * - * @client_cert contains @ncerts gnutls_datum structures which hold - * the raw certificates (DER for X.509 or binary for OpenPGP), of the - * client. - * - * @req_ca_dn, 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(). - * - * This function specifies what we, in case of a client, are going - * to do when we have to send a certificate. If this callback - * function is not provided then gnutls will automatically try to - * find an appropriate certificate to send. The appropriate certificate - * is chosen based on the CAs sent by the server, and the requested - * public key algorithms. - * - * If the callback function is provided then gnutls will call it, in the - * handshake, after the certificate request message has been received. - * - * The callback function should return the index of the certificate - * choosen by the user. The index is relative to the certificates in the - * callback's parameter. The value (-1) indicates that the user - * does not want to use client authentication. - **/ -void gnutls_certificate_client_set_select_function(gnutls_session session, - gnutls_certificate_client_select_function - * func) -{ - session->internals.client_cert_callback = func; -} - -#define gnutls_certificate_server_select_function certificate_server_select_func -/** - * gnutls_certificate_server_set_select_function - Used to set a callback while selecting the proper (server) certificate - * @session: is a &gnutls_session structure. - * @func: is the callback function - * - * This function sets a callback to be called while selecting the (server) certificate. - * The callback's function form is: - * int (*callback)(gnutls_session, gnutls_datum *server_cert, int ncerts); - * - * @server_cert contains @ncerts gnutls_datum structures which hold - * the raw certificate (DER encoded in X.509) of the server. - * - * This function specifies what we, in case of a server, are going - * to do when we have to send a certificate. If this callback - * function is not provided then gnutls will automatically try to - * find an appropriate certificate to send. (actually send the first in the list) - * - * In case the callback returned a negative number then gnutls will - * not attempt to choose the appropriate certificate and the caller function - * will fail. - * - * The callback function will only be called once per handshake. - * The callback function should return the index of the certificate - * choosen by the server. -1 indicates an error. - * - **/ -void gnutls_certificate_server_set_select_function(gnutls_session session, - gnutls_certificate_server_select_function - * func) -{ - session->internals.server_cert_callback = func; -} - /** * gnutls_certificate_client_set_retrieve_function - Used to set a callback to retrieve the certificate * @cred: is a &gnutls_certificate_credentials structure. diff --git a/lib/gnutls_global.c b/lib/gnutls_global.c index 0c6bf8525a..9a5c98b1ab 100644 --- a/lib/gnutls_global.c +++ b/lib/gnutls_global.c @@ -168,8 +168,14 @@ int gnutls_global_init( void) _gnutls_init++; if (gcry_control( GCRYCTL_ANY_INITIALIZATION_P) == 0) { - if (gcry_check_version(GNUTLS_GCRYPT_VERSION)==NULL) { + const char* p; + p = strchr( GNUTLS_GCRYPT_VERSION, ':'); + if (p==NULL) p = GNUTLS_GCRYPT_VERSION; + else p++; + + if (gcry_check_version(p)==NULL) { gnutls_assert(); + _gnutls_debug_log("Checking for libgcrypt failed '%s'\n", p); return GNUTLS_E_INCOMPATIBLE_GCRYPT_LIBRARY; } diff --git a/lib/gnutls_int.h b/lib/gnutls_int.h index 09d9f6faba..7d5c8df3f0 100644 --- a/lib/gnutls_int.h +++ b/lib/gnutls_int.h @@ -424,13 +424,6 @@ typedef struct { unsigned int algorithms; } GNUTLS_Priority; -typedef int certificate_client_select_func(struct gnutls_session_int*, - const gnutls_datum *, unsigned int, const gnutls_datum *, unsigned int); -typedef int certificate_server_select_func(struct gnutls_session_int*, - const gnutls_datum *, unsigned int); -typedef int srp_server_select_func(struct gnutls_session_int*, - const char**, const char**, unsigned int); - /* DH and RSA parameters types. */ typedef struct { @@ -576,16 +569,6 @@ typedef struct { */ int send_cert_req; - /* this is a callback function to call if no appropriate - * client certificates were found. - */ - certificate_client_select_func* client_cert_callback; - certificate_server_select_func* server_cert_callback; - - /* Callback to select the proper password file - */ - srp_server_select_func* server_srp_callback; - /* bits to use for DHE and DHA * use _gnutls_dh_get_prime_bits() and gnutls_dh_set_prime_bits() * to access it. diff --git a/lib/gnutls_ui.h b/lib/gnutls_ui.h index 4e04e832d4..2a97209d8d 100644 --- a/lib/gnutls_ui.h +++ b/lib/gnutls_ui.h @@ -8,16 +8,6 @@ typedef enum gnutls_x509_subject_alt_name { # ifdef LIBGNUTLS_VERSION /* These are defined only in gnutls.h */ -/* Callback prototypes for the certificate authentication - * callbacks. - */ -typedef int gnutls_certificate_client_select_function(gnutls_session, - const gnutls_datum * client_cert, int ncerts, - const gnutls_datum * req_ca_cert, int nreqs); -typedef int gnutls_certificate_server_select_function(gnutls_session, - const gnutls_datum * server_certs, int ncerts); - - struct gnutls_openpgp_key_int; typedef struct gnutls_openpgp_key_int *gnutls_openpgp_key; @@ -65,11 +55,6 @@ int gnutls_rsa_export_get_modulus_bits(gnutls_session session); /* X509PKI */ -void gnutls_certificate_client_set_select_function(gnutls_session, - gnutls_certificate_client_select_function *); -void gnutls_certificate_server_set_select_function(gnutls_session, - gnutls_certificate_server_select_function *); - /* These are set on the credentials structure. */ void gnutls_certificate_client_set_retrieve_function(gnutls_certificate_client_credentials, diff --git a/libextra/auth_srp_passwd.c b/libextra/auth_srp_passwd.c index 580cc7f438..43d83832b5 100644 --- a/libextra/auth_srp_passwd.c +++ b/libextra/auth_srp_passwd.c @@ -280,20 +280,6 @@ int _gnutls_srp_pwd_read_entry( gnutls_session state, char* username, return GNUTLS_E_SRP_PWD_ERROR; } - /* use the callback to select a password file. If set. - */ - if (state->internals.server_srp_callback!=NULL) { - pwd_index = state->internals.server_srp_callback( - state, (const char**)cred->password_file, - (const char**)cred->password_conf_file, - cred->password_files); - - if (pwd_index < 0) { - gnutls_assert(); - return GNUTLS_E_SRP_PWD_ERROR; - } - } - /* Open the selected password file. */ fd = fopen( cred->password_file[pwd_index], "r"); diff --git a/libextra/gnutls_srp.c b/libextra/gnutls_srp.c index 4b5d34b09d..7f6867b7f2 100644 --- a/libextra/gnutls_srp.c +++ b/libextra/gnutls_srp.c @@ -513,40 +513,6 @@ int i; return 0; } -#define gnutls_srp_server_select_function srp_server_select_func - -/** - * gnutls_srp_server_set_select_function - Used to set a callback to assist in selecting the proper password file - * @session: is a &gnutls_session structure. - * @func: is the callback function - * - * This function sets a callback to assist in selecting the proper password file, - * in case there are more than one. The callback's function form is: - * int (*callback)(gnutls_session, const char** pfiles, const char** pconffiles, int npfiles); - * - * @pfiles contains @npfiles char* structures which hold - * the password file name. @pconffiles contain the corresponding - * conf files. - * - * This function specifies what we, in case of a server, are going - * to do when we have to use a password file. If this callback - * function is not provided then gnutls will automatically select the - * first password file - * - * In case the callback returned a negative number then gnutls will - * terminate this handshake. - * - * The callback function will only be called once per handshake. - * The callback function should return the index of the password file - * that will be used by the server. -1 indicates an error. - * - **/ -void gnutls_srp_server_set_select_function(gnutls_session session, - gnutls_srp_server_select_function - * func) -{ - session->internals.server_srp_callback = func; -} /** * gnutls_srp_set_server_credentials_function - Used to set a callback to retrieve the user's SRP credentials @@ -26,10 +26,17 @@ #include <stdlib.h> #include <sys/types.h> #include <string.h> +#include <sys/time.h> +#include <sys/mman.h> +#include <sys/stat.h> +#include <unistd.h> +#include <fcntl.h> + #include <gnutls/gnutls.h> #include <gnutls/extra.h> #include <gnutls/x509.h> -#include <sys/time.h> +#include <gnutls/openpgp.h> + #include "common.h" #include "cli-gaa.h" @@ -70,11 +77,13 @@ static int x509ctype; static int disable_extensions; static int debug; + static gnutls_srp_client_credentials srp_cred; static gnutls_anon_client_credentials anon_cred; static gnutls_certificate_credentials xcred; -int protocol_priority[PRI_MAX] = { GNUTLS_TLS1_1, GNUTLS_TLS1_0, GNUTLS_SSL3, 0 }; +int protocol_priority[PRI_MAX] = + { GNUTLS_TLS1_1, GNUTLS_TLS1_0, GNUTLS_SSL3, 0 }; int kx_priority[PRI_MAX] = { GNUTLS_KX_RSA, GNUTLS_KX_DHE_DSS, GNUTLS_KX_DHE_RSA, GNUTLS_KX_SRP, /* Do not use anonymous authentication, unless you know what that means */ @@ -86,9 +95,10 @@ int cipher_priority[PRI_MAX] = GNUTLS_CIPHER_ARCFOUR_40, 0 }; int comp_priority[PRI_MAX] = { GNUTLS_COMP_ZLIB, GNUTLS_COMP_NULL, 0 }; -int mac_priority[PRI_MAX] = - { GNUTLS_MAC_SHA, GNUTLS_MAC_MD5, GNUTLS_MAC_RMD160, 0 }; -int cert_type_priority[PRI_MAX] = { GNUTLS_CRT_X509, GNUTLS_CRT_OPENPGP, 0 }; +int mac_priority[PRI_MAX] = + { GNUTLS_MAC_SHA, GNUTLS_MAC_MD5, GNUTLS_MAC_RMD160, 0 }; +int cert_type_priority[PRI_MAX] = + { GNUTLS_CRT_X509, GNUTLS_CRT_OPENPGP, 0 }; /* end of global stuff */ @@ -97,7 +107,7 @@ typedef struct { int fd; gnutls_session session; int secure; - const char* hostname; + const char *hostname; } socket_st; ssize_t socket_recv(socket_st socket, void *buffer, int buffer_size); @@ -111,21 +121,157 @@ static void init_global_tls_stuff(void); #undef MAX #define MAX(X,Y) (X >= Y ? X : Y); -/* A callback function to be used at the certificate selection time. + +/* Helper functions to load a certificate and key + * files into memory. They use mmap for simplicity. + */ +static gnutls_datum mmap_file(const char *file) +{ + int fd; + gnutls_datum mmaped_file = { NULL, 0 }; + struct stat stat_st; + void *ptr; + + fd = open(file, 0); + if (fd == -1) + return mmaped_file; + + fstat(fd, &stat_st); + + if ((ptr = + mmap(NULL, stat_st.st_size, PROT_READ, MAP_SHARED, fd, + 0)) == MAP_FAILED) + return mmaped_file; + + mmaped_file.data = ptr; + mmaped_file.size = stat_st.st_size; + + return mmaped_file; +} + +static void munmap_file(gnutls_datum data) +{ + munmap(data.data, data.size); +} + +static gnutls_x509_crt x509_crt; +static gnutls_x509_privkey x509_key; + +static gnutls_openpgp_key pgp_crt; +static gnutls_openpgp_privkey pgp_key; + +/* Load the certificate and the private key. + */ +static void load_keys(void) +{ + int ret; + gnutls_datum data; + + if (x509_certfile != NULL && x509_keyfile != NULL) { + data = mmap_file(x509_certfile); + if (data.data == NULL) { + fprintf(stderr, "*** Error loading cert file.\n"); + exit(1); + } + gnutls_x509_crt_init(&x509_crt); + + ret = + gnutls_x509_crt_import(x509_crt, &data, + GNUTLS_X509_FMT_PEM); + if (ret < 0) { + fprintf(stderr, + "*** Error loading cert file: %s\n", + gnutls_strerror(ret)); + exit(1); + } + + munmap_file(data); + + data = mmap_file(x509_keyfile); + if (data.data == NULL) { + fprintf(stderr, "*** Error loading key file.\n"); + exit(1); + } + + gnutls_x509_privkey_init(&x509_key); + + ret = + gnutls_x509_privkey_import(x509_key, &data, + GNUTLS_X509_FMT_PEM); + if (ret < 0) { + fprintf(stderr, "*** Error loading key file: %s\n", + gnutls_strerror(ret)); + exit(1); + } + + munmap_file(data); + } + +#ifdef HAVE_LIBOPENCDK + if (pgp_certfile != NULL && pgp_keyfile != NULL) { + data = mmap_file(pgp_certfile); + if (data.data == NULL) { + fprintf(stderr, "*** Error loading PGP cert file.\n"); + exit(1); + } + gnutls_openpgp_key_init(&pgp_crt); + + ret = + gnutls_openpgp_key_import(pgp_crt, &data, + GNUTLS_OPENPGP_FMT_BASE64); + if (ret < 0) { + fprintf(stderr, + "*** Error loading PGP cert file: %s\n", + gnutls_strerror(ret)); + exit(1); + } + + munmap_file(data); + + data = mmap_file(x509_keyfile); + if (data.data == NULL) { + fprintf(stderr, "*** Error loading PGP key file.\n"); + exit(1); + } + + gnutls_openpgp_privkey_init(&pgp_key); + + ret = + gnutls_openpgp_privkey_import(pgp_key, &data, + GNUTLS_OPENPGP_FMT_BASE64, NULL, 0); + if (ret < 0) { + fprintf(stderr, "*** Error loading PGP key file: %s\n", + gnutls_strerror(ret)); + exit(1); + } + + munmap_file(data); + } +#endif + +} + + + +/* This callback should be associated with a session by calling + * gnutls_certificate_client_set_retrieve_function( session, cert_callback), + * before a handshake. */ + static int cert_callback(gnutls_session session, - const gnutls_datum * client_certs, - int client_certs_num, - const gnutls_datum * req_ca_rdn, int nreqs) + const gnutls_datum * req_ca_rdn, int nreqs, + const gnutls_pk_algorithm * sign_algos, + int sign_algos_length, gnutls_retr_st * st) { char issuer_dn[256]; int i, ret; size_t len; + gnutls_certificate_type type; /* Print the server's trusted CAs */ if (nreqs > 0) - printf("- Server's trusted authorities (%d):\n", nreqs); + printf("- Server's trusted authorities:\n"); else printf ("- Server did not send us any trusted authorities names.\n"); @@ -140,14 +286,36 @@ static int cert_callback(gnutls_session session, } } - if (client_certs_num > 0) - return 0; /* use the first one */ + /* Select a certificate and return it. + * 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) { + st->type = type; + st->ncerts = 1; - return -1; + st->cert.x509 = &x509_crt; + st->key.x509 = x509_key; + + st->deinit_all = 0; + } else { + st->type = type; + st->ncerts = 1; + + st->cert.pgp = pgp_crt; + st->key.pgp = pgp_key; + + st->deinit_all = 0; + } + + return 0; } + /* initializes a gnutls_session with some defaults. */ static gnutls_session init_tls_session(const char *hostname) @@ -162,7 +330,8 @@ static gnutls_session init_tls_session(const char *hostname) gnutls_handshake_set_private_extensions(session, 1); gnutls_server_name_set(session, GNUTLS_NAME_DNS, hostname, strlen(hostname)); - gnutls_certificate_type_set_priority(session, cert_type_priority); + gnutls_certificate_type_set_priority(session, + cert_type_priority); } gnutls_cipher_set_priority(session, cipher_priority); @@ -178,8 +347,8 @@ static gnutls_session init_tls_session(const char *hostname) gnutls_credentials_set(session, GNUTLS_CRD_SRP, srp_cred); gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, xcred); - gnutls_certificate_client_set_select_function(session, - cert_callback); + gnutls_certificate_client_set_retrieve_function(xcred, + cert_callback); /* send the fingerprint */ if (fingerprint != 0) @@ -211,7 +380,8 @@ static int handle_error(socket_st hd, int err) int alert, ret; const char *err_type, *str; - if (err >= 0) return 0; + if (err >= 0) + return 0; if (gnutls_error_is_fatal(err) == 0) { ret = 0; @@ -222,15 +392,16 @@ static int handle_error(socket_st hd, int err) } str = gnutls_strerror(err); - if (str == NULL) str = str_unknown; - fprintf(stderr, - "*** %s error: %s\n", err_type, str); + if (str == NULL) + str = str_unknown; + fprintf(stderr, "*** %s error: %s\n", err_type, str); if (err == GNUTLS_E_WARNING_ALERT_RECEIVED || err == GNUTLS_E_FATAL_ALERT_RECEIVED) { alert = gnutls_alert_get(hd.session); str = gnutls_alert_get_name(alert); - if (str == NULL) str = str_unknown; + if (str == NULL) + str = str_unknown; printf("*** Received alert [%d]: %s\n", alert, str); /* In SRP if the alert is MISSING_SRP_USERNAME, @@ -247,9 +418,9 @@ static int handle_error(socket_st hd, int err) int starttls_alarmed = 0; -void starttls_alarm (int signum) +void starttls_alarm(int signum) { - starttls_alarmed = 1; + starttls_alarmed = 1; } int main(int argc, char **argv) @@ -274,7 +445,7 @@ int main(int argc, char **argv) fprintf(stderr, "No hostname given\n"); exit(1); } - + sockets_init(); #ifndef _WIN32 @@ -303,7 +474,7 @@ int main(int argc, char **argv) if (inet_ntop(AF_INET, &sa.sin_addr, buffer, MAX_BUF) == NULL) { perror("inet_ntop()"); - return(1); + return (1); } fprintf(stderr, "Connecting to '%s:%d'...\n", buffer, port); @@ -385,7 +556,7 @@ int main(int argc, char **argv) printf("\n- Simple Client Mode:\n\n"); #ifndef _WIN32 - signal (SIGALRM, &starttls_alarm); + signal(SIGALRM, &starttls_alarm); #endif /* do not buffer */ @@ -404,22 +575,22 @@ int main(int argc, char **argv) err = select(maxfd + 1, &rset, NULL, NULL, &tv); if (err < 0) { - if (errno == EINTR && starttls_alarmed) { - if (hd.secure == 0) { - fprintf(stderr, - "*** Starting TLS handshake\n"); - ret = do_handshake(&hd); - if (ret < 0) { - fprintf(stderr, - "*** Handshake has failed\n"); - socket_bye(&hd); - user_term = 1; - } - } else { - user_term = 1; - } - } - continue; + if (errno == EINTR && starttls_alarmed) { + if (hd.secure == 0) { + fprintf(stderr, + "*** Starting TLS handshake\n"); + ret = do_handshake(&hd); + if (ret < 0) { + fprintf(stderr, + "*** Handshake has failed\n"); + socket_bye(&hd); + user_term = 1; + } + } else { + user_term = 1; + } + } + continue; } if (FD_ISSET(sd, &rset)) { @@ -604,7 +775,8 @@ ssize_t socket_send(socket_st socket, const void *buffer, int buffer_size) if (ret > 0 && ret != buffer_size && quiet) fprintf(stderr, - "*** Only sent %d bytes instead of %d.\n", ret, buffer_size); + "*** Only sent %d bytes instead of %d.\n", ret, + buffer_size); return ret; } @@ -619,7 +791,8 @@ void socket_bye(socket_st * socket) while (ret == GNUTLS_E_INTERRUPTED || ret == GNUTLS_E_AGAIN); if (ret < 0) - fprintf(stderr, "*** gnutls_bye() error: %s\n", gnutls_strerror(ret)); + fprintf(stderr, "*** gnutls_bye() error: %s\n", + gnutls_strerror(ret)); gnutls_deinit(socket->session); socket->session = NULL; } @@ -674,10 +847,11 @@ static int do_handshake(socket_st * socket) return ret; } -static int srp_username_callback( gnutls_session session, unsigned int times, - char** username, char** password) +static int srp_username_callback(gnutls_session session, + unsigned int times, char **username, + char **password) { - if (srp_username == NULL || srp_passwd ==NULL) { + if (srp_username == NULL || srp_passwd == NULL) { return -1; } @@ -685,24 +859,26 @@ static int srp_username_callback( gnutls_session session, unsigned int times, * and password. */ if (times == 1) { - *username = gnutls_strdup( srp_username); - *password = gnutls_strdup( srp_passwd); - + *username = gnutls_strdup(srp_username); + *password = gnutls_strdup(srp_passwd); + return 0; } else /* At the first time return username and password, if * the kx_priority[0] is an SRP method. */ - if (times == 0 && (kx_priority[0] == GNUTLS_KX_SRP || - kx_priority[0] == GNUTLS_KX_SRP_RSA || - kx_priority[0] == GNUTLS_KX_SRP_DSS)) { - - *username = gnutls_strdup( srp_username); - *password = gnutls_strdup( srp_passwd); - - return 0; - } - + if (times == 0 && (kx_priority[0] == GNUTLS_KX_SRP || + kx_priority[0] == + GNUTLS_KX_SRP_RSA + || kx_priority[0] == + GNUTLS_KX_SRP_DSS)) { + + *username = gnutls_strdup(srp_username); + *password = gnutls_strdup(srp_passwd); + + return 0; + } + return -1; } @@ -715,7 +891,7 @@ static void init_global_tls_stuff(void) { int ret; - if ((ret=gnutls_global_init()) < 0) { + if ((ret = gnutls_global_init()) < 0) { fprintf(stderr, "global_init: %s\n", gnutls_strerror(ret)); exit(1); } @@ -723,7 +899,7 @@ static void init_global_tls_stuff(void) gnutls_global_set_log_function(tls_log_func); gnutls_global_set_log_level(debug); - if ((ret=gnutls_global_init_extra()) < 0) { + if ((ret = gnutls_global_init_extra()) < 0) { fprintf(stderr, "global_init_extra: %s\n", gnutls_strerror(ret)); exit(1); @@ -767,32 +943,9 @@ static void init_global_tls_stuff(void) } #endif - if (x509_certfile != NULL) { - ret = - gnutls_certificate_set_x509_key_file(xcred, - x509_certfile, - x509_keyfile, - x509ctype); - if (ret < 0) { - fprintf(stderr, - "Error setting the x509 key files ('%s', '%s')\n", - x509_certfile, x509_keyfile); - } - } + load_keys(); #ifdef HAVE_LIBOPENCDK - if (pgp_certfile != NULL) { - ret = - gnutls_certificate_set_openpgp_key_file(xcred, - pgp_certfile, - pgp_keyfile); - if (ret < 0) { - fprintf(stderr, - "Error setting the x509 key files ('%s', '%s')\n", - pgp_certfile, pgp_keyfile); - } - } - if (pgp_keyring != NULL) { ret = gnutls_certificate_set_openpgp_keyring_file(xcred, @@ -822,7 +975,7 @@ static void init_global_tls_stuff(void) gnutls_srp_set_client_credentials_function(srp_cred, - srp_username_callback); + srp_username_callback); #endif diff --git a/src/tests.c b/src/tests.c index 220094a87b..f67ff61f6b 100644 --- a/src/tests.c +++ b/src/tests.c @@ -809,8 +809,10 @@ int ret; /* A callback function to be used at the certificate selection time. */ -static int cert_callback( gnutls_session session, const gnutls_datum* client_certs, - int client_certs_num, const gnutls_datum * req_ca_rdn, int nreqs) +static int cert_callback(gnutls_session session, + const gnutls_datum * req_ca_rdn, int nreqs, + const gnutls_pk_algorithm * sign_algos, + int sign_algos_length, gnutls_retr_st * st) { char issuer_dn[256]; int i, ret; @@ -853,7 +855,7 @@ int ret; ADD_ALL_KX(session); gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, xcred); - gnutls_certificate_client_set_select_function( session, cert_callback); + gnutls_certificate_client_set_retrieve_function( session, cert_callback); ret = do_handshake( session); if (ret ==GFAILED) return ret; |