Version 0.1.5
- Corrected bug(s) in ChangeCipherSpec packet (fixes renegotiate)
- SRP is updated to conform to the newest draft.
+- Added support for DNSNAME extension.
Version 0.1.4 (22/06/2001)
- Corrected (srp) base64 encoding.
#include "gnutls_auth_int.h"
#include "auth_x509.h"
#include "gnutls_errors.h"
+#include "gnutls_num.h"
int _gnutls_dnsname_recv_params( GNUTLS_STATE state, const opaque* data, int data_size) {
- uint8 len;
+ uint16 len;
if (state->security_parameters.entity == GNUTLS_SERVER) {
if (data_size > 0) {
- if (sizeof( state->gnutls_key->dnsname) > data_size) {
- len = data[0];
- if (len > data_size) {
+ if (sizeof( state->security_parameters.extensions.dnsname) > data_size) {
+ len = READuint16( data);
+ if (len > data_size || len >= MAX_DNSNAME_SIZE) {
gnutls_assert();
return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
}
- memcpy( state->gnutls_key->dnsname, &data[1], len);
- state->gnutls_key->dnsname[len]=0; /* null terminated */
+ /* note that dnsname is in UTF-8
+ * format.
+ */
+ memcpy( state->security_parameters.extensions.dnsname, &data[2], len);
+ state->security_parameters.extensions.dnsname[len]=0; /* null terminated */
}
}
}
* data is allocated localy
*/
int _gnutls_dnsname_send_params( GNUTLS_STATE state, opaque** data) {
- uint8 len;
+ uint16 len;
/* this function sends the client extension data (dnsname) */
if (state->security_parameters.entity == GNUTLS_CLIENT) {
- if ( (len = strlen(state->gnutls_key->dnsname)) > 0) { /* send dnsname */
- (*data) = gnutls_malloc(len+1); /* hold the size also */
- (*data)[0] = len;
- memcpy( &(*data)[1], state->gnutls_key->dnsname, len);
- return len + 1;
+ if ( (len = strlen(state->security_parameters.extensions.dnsname)) > 0) { /* send dnsname */
+ (*data) = gnutls_malloc(len+2); /* hold the size also */
+ WRITEuint16( len, *data);
+ memcpy( &(*data)[2], state->security_parameters.extensions.dnsname, len);
+ return len + 2;
}
}
return 0;
int gnutls_set_cred( GNUTLS_STATE, CredType type, void* cred);
const void* gnutls_get_auth_info( GNUTLS_STATE);
+/* A null terminated string containing the dnsname.
+ * This will only exist if the client supports the dnsname
+ * TLS extension. (draft-ietf-tls-extensions)
+ */
+const char* gnutls_ext_get_dnsname( GNUTLS_STATE);
+
/* Credential structures for SRP - used in gnutls_set_cred(); */
typedef struct {
char* username;
return _gnutls_set_keys( state, hash_size, IV_size, key_size);
}
-
-static void _gnutls_cpy_read_security_parameters( SecurityParameters * dst, SecurityParameters* src) {
- dst->entity = src->entity;
- dst->kx_algorithm = src->kx_algorithm;
-
- memcpy( &dst->current_cipher_suite, &src->current_cipher_suite, sizeof(GNUTLS_CipherSuite));
+#define CPY_COMMON dst->entity = src->entity; \
+ dst->kx_algorithm = src->kx_algorithm; \
+ memcpy( &dst->current_cipher_suite, &src->current_cipher_suite, sizeof(GNUTLS_CipherSuite)); \
+ memcpy( dst->master_secret, src->master_secret, TLS_MASTER_SIZE); \
+ memcpy( dst->client_random, src->client_random, TLS_RANDOM_SIZE); \
+ memcpy( dst->server_random, src->server_random, TLS_RANDOM_SIZE); \
+ memcpy( dst->session_id, src->session_id, TLS_MAX_SESSION_ID_SIZE); \
+ dst->session_id_size = src->session_id_size; \
+ dst->timestamp = src->timestamp; \
+ memcpy( &dst->extensions, &src->extensions, sizeof(TLSExtensions));
- memcpy( dst->master_secret, src->master_secret, TLS_MASTER_SIZE);
- memcpy( dst->client_random, src->client_random, TLS_RANDOM_SIZE);
- memcpy( dst->server_random, src->server_random, TLS_RANDOM_SIZE);
-
- memcpy( dst->session_id, src->session_id, TLS_MAX_SESSION_ID_SIZE);
+static void _gnutls_cpy_read_security_parameters( SecurityParameters * dst, SecurityParameters* src) {
+ CPY_COMMON;
- dst->session_id_size = src->session_id_size;
- dst->timestamp = src->timestamp;
-
dst->read_bulk_cipher_algorithm = src->read_bulk_cipher_algorithm;
dst->read_mac_algorithm = src->read_mac_algorithm;
dst->read_compression_algorithm = src->read_compression_algorithm;
}
static void _gnutls_cpy_write_security_parameters( SecurityParameters * dst, SecurityParameters* src) {
- dst->entity = src->entity;
- dst->kx_algorithm = src->kx_algorithm;
-
- memcpy( &dst->current_cipher_suite, &src->current_cipher_suite, sizeof(GNUTLS_CipherSuite));
-
- memcpy( dst->master_secret, src->master_secret, TLS_MASTER_SIZE);
- memcpy( dst->client_random, src->client_random, TLS_RANDOM_SIZE);
- memcpy( dst->server_random, src->server_random, TLS_RANDOM_SIZE);
-
- memcpy( dst->session_id, src->session_id, TLS_MAX_SESSION_ID_SIZE);
- dst->session_id_size = src->session_id_size;
- dst->timestamp = src->timestamp;
-
+ CPY_COMMON;
+
dst->write_bulk_cipher_algorithm = src->write_bulk_cipher_algorithm;
dst->write_mac_algorithm = src->write_mac_algorithm;
dst->write_compression_algorithm = src->write_compression_algorithm;
#define MAX_EXT 20 /* maximum supported extension */
static gnutls_extension_entry extensions[] = {
- GNUTLS_EXTENSION_ENTRY(GNUTLS_EXTENSION_SRP, _gnutls_srp_recv_params, _gnutls_srp_send_params),
- GNUTLS_EXTENSION_ENTRY(GNUTLS_EXTENSION_DNSNAME, _gnutls_dnsname_recv_params, _gnutls_dnsname_send_params),
+ GNUTLS_EXTENSION_ENTRY( GNUTLS_EXTENSION_SRP, _gnutls_srp_recv_params, _gnutls_srp_send_params),
+ GNUTLS_EXTENSION_ENTRY( GNUTLS_EXTENSION_DNSNAME, _gnutls_dnsname_recv_params, _gnutls_dnsname_send_params),
{0}
};
return size;
}
+
+/**
+ * gnutls_ext_get_dnsname - Used to get the dnsname a client connected to
+ * @state: is a &GNUTLS_STATE structure.
+ *
+ * This function is to be used by servers that support virtual hosting.
+ * The client may give the server the dnsname they connected to.
+ * if no name was given this function returns NULL.
+ *
+ **/
+const char* gnutls_ext_get_dnsname( GNUTLS_STATE state) {
+ if (state->security_parameters.entity==GNUTLS_CLIENT) return NULL;
+
+ if (strlen( state->security_parameters.extensions.dnsname) == 0) return NULL;
+
+ return state->security_parameters.extensions.dnsname;
+}
+
+/**
+ * gnutls_ext_set_dnsname - Used to set the dnsname as an extension
+ * @state: is a &GNUTLS_STATE structure.
+ * @dnsname: is a null terminated string that contains the dns name.
+ *
+ * This function is to be used by clients that want to inform
+ * ( via a TLS extension mechanism) the server of the name they
+ * connected to. This should be used by clients that connect
+ * to servers that do virtual hosting.
+ **/
+int gnutls_ext_set_dnsname( GNUTLS_STATE state, char* dnsname) {
+
+ if (state->security_parameters.entity==GNUTLS_SERVER) return GNUTLS_E_UNIMPLEMENTED_FEATURE;
+
+ if (strlen( dnsname) >= MAX_DNSNAME_SIZE) return GNUTLS_E_MEMORY_ERROR;
+
+ strcpy( state->security_parameters.extensions.dnsname, dnsname);
+
+ return 0;
+}
*/
cert = NULL;
- if (state->gnutls_key->dnsname[0] != 0) {
+ if (state->security_parameters.extensions.dnsname[0] != 0) {
cert =
(gnutls_cert *) _gnutls_find_cert(x509_cred->cert_list,
x509_cred->ncerts,
- state->gnutls_key->
- dnsname);
+ state->security_parameters.
+ extensions.dnsname);
}
if (cert == NULL) { /* if no such cert, use the first in the list
#define TLS_MAX_SESSION_ID_SIZE 32
#define TLS_MASTER_SIZE 48
+#define MAX_DNSNAME_SIZE 256
+
/* the default for TCP */
#define DEFAULT_LOWAT 1
/* STATE */
typedef enum ConnectionEnd { GNUTLS_SERVER=1, GNUTLS_CLIENT } ConnectionEnd;
typedef enum BulkCipherAlgorithm { GNUTLS_NULL_CIPHER=1, GNUTLS_ARCFOUR, GNUTLS_3DES_CBC, GNUTLS_RIJNDAEL_CBC, GNUTLS_TWOFISH_CBC, GNUTLS_RIJNDAEL256_CBC } BulkCipherAlgorithm;
-typedef enum Extensions { GNUTLS_EXTENSION_SRP=7, GNUTLS_EXTENSION_DNSNAME } Extensions;
+typedef enum Extensions { GNUTLS_EXTENSION_DNSNAME=0, GNUTLS_EXTENSION_SRP=6 } Extensions;
typedef enum KXAlgorithm { GNUTLS_KX_RSA=1, GNUTLS_KX_DHE_DSS, GNUTLS_KX_DHE_RSA, GNUTLS_KX_DH_DSS, GNUTLS_KX_DH_RSA, GNUTLS_KX_DH_ANON, GNUTLS_KX_SRP } KXAlgorithm;
typedef enum CredType { GNUTLS_X509PKI=1, GNUTLS_ANON, GNUTLS_SRP } CredType;
typedef enum CipherType { CIPHER_STREAM, CIPHER_BLOCK } CipherType;
/* this is used to hold the peers authentication data
*/
void* auth_info;
- int auth_info_size; /* needed in order to store to db for restoring */
+ int auth_info_size; /* needed in order to store to db for restoring
+ */
uint8 crypt_algo;
/* These are needed in RSA and DH signature calculation
opaque server_random[TLS_RANDOM_SIZE];
opaque client_random[TLS_RANDOM_SIZE];
ProtocolVersion version;
- opaque dnsname[256];
AUTH_CRED* cred; /* used to specify keys/certificates etc */
} GNUTLS_KEY_A;
uint8 CipherSuite[2];
} GNUTLS_CipherSuite;
+/* This structure holds parameters got from TLS extension
+ * mechanism. (some extensions may hold parameters in AUTH_INFO
+ * structures instead - see SRP).
+ */
+typedef struct {
+ opaque dnsname[MAX_DNSNAME_SIZE];
+} TLSExtensions;
+
/* This structure and AUTH_INFO, are stored in the resume database,
* and are restored, in case of resume.
* Holds all the required parameters to resume the current
opaque session_id[TLS_MAX_SESSION_ID_SIZE];
uint8 session_id_size;
time_t timestamp;
+ TLSExtensions extensions;
} SecurityParameters;
/* This structure holds the generated keys
gnutls_set_cred( state, GNUTLS_ANON, NULL);
gnutls_set_cred( state, GNUTLS_SRP, &cred);
gnutls_set_cred( state, GNUTLS_X509PKI, &xcred);
-
+ gnutls_ext_set_dnsname( state, "hello.server.org");
+
gnutls_set_mac_priority( state, GNUTLS_MAC_SHA, GNUTLS_MAC_MD5, 0);
ret = gnutls_handshake(sd, state);
gnutls_set_cred( state, GNUTLS_SRP, &cred);
gnutls_set_cred( state, GNUTLS_X509PKI, &xcred);
+ gnutls_ext_set_dnsname( state, "hello.server.org");
+
gnutls_set_mac_priority( state, GNUTLS_MAC_SHA, GNUTLS_MAC_MD5, 0);
#ifdef RESUME
printf("%.2X", sesid[i]);
printf("\n");
+ printf("- DNSNAME: ");
+ printf("%s\n", gnutls_ext_get_dnsname(state));
+
/* print srp specific data */
if (gnutls_get_current_kx(state) == GNUTLS_KX_SRP) {
srp_info = gnutls_get_auth_info(state);
sprintf(tmp2, "%.2X", sesid[i]);
sprintf(tmp2, "</i></p>\n");
+ /* if the client supports dnsname extension then
+ * print the hostname he connected to.
+ */
+ if (gnutls_ext_get_dnsname(state)!=NULL) {
+ printf("\n<p>DNSNAME: ");
+ printf("<b>%s</b></p>\n", gnutls_ext_get_dnsname(state));
+ }
+
/* print srp specific data */
if (gnutls_get_current_kx(state) == GNUTLS_KX_SRP) {
srp_info = gnutls_get_auth_info(state);