]> git.ipfire.org Git - thirdparty/gnutls.git/commitdiff
added support for DNSNAME extension (draft-ietf-tls-extensions)
authorNikos Mavrogiannopoulos <nmav@gnutls.org>
Sun, 24 Jun 2001 21:42:34 +0000 (21:42 +0000)
committerNikos Mavrogiannopoulos <nmav@gnutls.org>
Sun, 24 Jun 2001 21:42:34 +0000 (21:42 +0000)
NEWS
lib/ext_dnsname.c
lib/gnutls.h.in
lib/gnutls_constate.c
lib/gnutls_extensions.c
lib/gnutls_handshake.c
lib/gnutls_int.h
src/cli.c
src/serv.c

diff --git a/NEWS b/NEWS
index 43c72b480dce1f7e3b27e7f4087aa564686bfd89..59440bcf274190d7864420c403ea2b27580ba9e6 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -1,6 +1,7 @@
 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.
index 40027968891a54cd0b04ad56a92ba2d9f270f7f4..e65106098ac7dcee2f61ec1f27bcbd4caaec8933 100644 (file)
 #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 */
                        }
                }
        }
@@ -45,15 +49,15 @@ int _gnutls_dnsname_recv_params( GNUTLS_STATE state, const opaque* data, int dat
  * 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;
index 73de6ca5f48943c9bec394cf17ab15c2b3a7017a..75e0f71a77b2dae485306207441887aaa542b9e6 100644 (file)
@@ -130,6 +130,12 @@ int gnutls_clear_creds( GNUTLS_STATE state);
 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;
index c11f7610a453d0ab0c2f0b1a683d936e536aeee8..e7498f46d241d48ead62b05e6db0a1cfbcec95da 100644 (file)
@@ -142,41 +142,28 @@ int _gnutls_set_write_keys(GNUTLS_STATE state)
        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;
index ef3a8de0b90c7966b5d2f5f8376c21f8c435fa84..7a68efe61948e9225dc22f8ad0bad2eb3de0a1b5 100644 (file)
@@ -38,8 +38,8 @@ typedef struct {
 
 #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}
 };
 
@@ -171,3 +171,41 @@ int (*ext_func_send)( GNUTLS_STATE, opaque**);
        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;
+}
index 35e67bb6d5ecf4705c0600cde9414bb3eb2c0005..8bba1ec2253df8d5ba0a7378e97953c57a5649be 100644 (file)
@@ -1746,12 +1746,12 @@ int _gnutls_remove_unwanted_ciphersuites(GNUTLS_STATE state,
         */
 
        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 
index 83c8f36b4dcdb6260da9d1ef04eefa81a89e68f5..d6f100947c997ba90af366793c0e5dce6ebc97ec 100644 (file)
@@ -45,6 +45,8 @@
 #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
 
@@ -118,7 +120,7 @@ typedef struct {
 /* 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;
@@ -167,7 +169,8 @@ typedef struct {
        /* 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 
@@ -175,7 +178,6 @@ typedef struct {
        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;
@@ -192,6 +194,14 @@ typedef struct {
        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 
@@ -223,6 +233,7 @@ typedef struct {
        opaque                  session_id[TLS_MAX_SESSION_ID_SIZE];
        uint8                   session_id_size;
        time_t                  timestamp;
+       TLSExtensions           extensions;
 } SecurityParameters;
 
 /* This structure holds the generated keys
index e69b5178b453f392713b033887326a72a6caf458..f28936083d936d7e41cdf791b2e5c4d46e3fbe26 100644 (file)
--- a/src/cli.c
+++ b/src/cli.c
@@ -144,7 +144,8 @@ int main(int argc, char** argv)
        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);
 
@@ -195,6 +196,8 @@ int main(int argc, char** argv)
        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
index ac68f1632d05fd1784f3dfeaf24289776d23264d..8505508cb3a46f1fe5f5b34ff6fc34d626515b9f 100644 (file)
@@ -115,6 +115,9 @@ void print_info(GNUTLS_STATE state)
                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);
@@ -171,6 +174,14 @@ void peer_print_info(int cd, GNUTLS_STATE 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);