summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikos Mavrogiannopoulos <nmav@gnutls.org>2001-10-10 15:53:05 +0000
committerNikos Mavrogiannopoulos <nmav@gnutls.org>2001-10-10 15:53:05 +0000
commit9743e150a3397826993ff28726af63cf20011cc9 (patch)
tree15c1c26ad1f7b57a25eb0118688c5d92b610ffbe
parent01f2ebc48ad96b8879ac101fe59e4374268a4567 (diff)
downloadgnutls-9743e150a3397826993ff28726af63cf20011cc9.tar.gz
updated name indication extension (dnsname)
-rw-r--r--NEWS2
-rw-r--r--lib/auth_x509.c9
-rw-r--r--lib/ext_dnsname.c126
-rw-r--r--lib/ext_dnsname.h9
-rw-r--r--lib/gnutls.h.in7
-rw-r--r--lib/gnutls_cert.c4
-rw-r--r--lib/gnutls_cert.h4
-rw-r--r--lib/gnutls_extensions.c39
-rw-r--r--lib/gnutls_handshake.c9
-rw-r--r--lib/gnutls_int.h10
-rw-r--r--src/cli.c5
-rw-r--r--src/crypt.c2
-rw-r--r--src/serv.c8
13 files changed, 151 insertions, 83 deletions
diff --git a/NEWS b/NEWS
index c57c56f66c..38aae03ad9 100644
--- a/NEWS
+++ b/NEWS
@@ -1,6 +1,8 @@
Version 0.2.4
- Better handling of X.509 certificate extensions
- Added DHE_RSA ciphersuites
+- Updated the Name Indication (dnsname) extension
+- Improvements in Diffie Hellman primes handling
Version 0.2.3 (19/09/2001)
- Memory optimizations in gnutls_recv()
diff --git a/lib/auth_x509.c b/lib/auth_x509.c
index 07540d831c..86b818fed2 100644
--- a/lib/auth_x509.c
+++ b/lib/auth_x509.c
@@ -35,7 +35,7 @@
#include <gnutls_record.h>
#include <x509_verify.h>
#include <gnutls_sig.h>
-
+#include <ext_dnsname.h>
/* Copies data from a internal certificate struct (gnutls_cert) to
* exported certificate struct (X509PKI_CLIENT_AUTH_INFO)
@@ -891,12 +891,13 @@ int _gnutls_find_apr_cert( GNUTLS_STATE state, gnutls_cert** apr_cert_list, int
*apr_cert_list_length = 0;
*apr_pkey = NULL;
} else {
+ const char* dnsname = gnutls_ext_get_name_ind( state, GNUTLS_DNSNAME);
+ if (dnsname==NULL) dnsname="";
+
ind =
_gnutls_find_cert_list_index(cred->cert_list,
cred->ncerts,
- state->
- security_parameters.
- extensions.dnsname);
+ dnsname);
if (ind < 0) {
*apr_cert_list = NULL;
diff --git a/lib/ext_dnsname.c b/lib/ext_dnsname.c
index e65106098a..3760fe29a4 100644
--- a/lib/ext_dnsname.c
+++ b/lib/ext_dnsname.c
@@ -24,21 +24,38 @@
#include "gnutls_errors.h"
#include "gnutls_num.h"
-int _gnutls_dnsname_recv_params( GNUTLS_STATE state, const opaque* data, int data_size) {
+/* This file should have been called ext_name_ind.c
+ *
+ * In case of a server: if a DNSNAME extension type is received then it stores
+ * into the state the value of DNSNAME. The server may use gnutls_ext_get_name_ind(),
+ * in order to access it.
+ *
+ * In case of a client: If a proper DNSNAME extension type is found in the state then
+ * it sends the extension to the peer.
+ *
+ */
+
+int _gnutls_name_ind_recv_params( GNUTLS_STATE state, const opaque* data, int data_size) {
uint16 len;
if (state->security_parameters.entity == GNUTLS_SERVER) {
if (data_size > 0) {
- 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;
- }
- /* 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 */
+ len = READuint16( data);
+ if (len > data_size || len >= MAX_DNSNAME_SIZE || len < 3) {
+ gnutls_assert();
+ return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
+ }
+
+ switch(data[2]) {
+ case 0:
+ if (sizeof( state->security_parameters.extensions.name.dnsname) > len-2) {
+ state->security_parameters.extensions.name.type = GNUTLS_DNSNAME;
+ /* note that dnsname is in UTF-8
+ * format.
+ */
+ memcpy( state->security_parameters.extensions.name.dnsname, &data[3], len-1);
+ state->security_parameters.extensions.name.dnsname[len-1]=0; /* null terminated */
+ break;
+ }
}
}
}
@@ -48,17 +65,88 @@ int _gnutls_dnsname_recv_params( GNUTLS_STATE state, const opaque* data, int dat
/* returns data_size or a negative number on failure
* data is allocated localy
*/
-int _gnutls_dnsname_send_params( GNUTLS_STATE state, opaque** data) {
+int _gnutls_name_ind_send_params( GNUTLS_STATE state, opaque** data) {
uint16 len;
/* this function sends the client extension data (dnsname) */
if (state->security_parameters.entity == GNUTLS_CLIENT) {
- 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;
+ switch (state->security_parameters.extensions.name.type) {
+ case GNUTLS_DNSNAME:
+ if ( (len = strlen(state->security_parameters.extensions.name.dnsname)) > 0) { /* send dnsname */
+ (*data) = gnutls_malloc(len+3); /* hold the size and the type also */
+
+ WRITEuint16( len+1, *data);
+ (*data)[2] = 0;
+ memcpy( &(*data)[3], state->security_parameters.extensions.name.dnsname, len);
+ return len + 3;
+ }
+ return 0;
+ default:
+ return GNUTLS_E_UNIMPLEMENTED_FEATURE;
}
}
- return 0;
+ return GNUTLS_E_UNKNOWN_ERROR;
+}
+
+/**
+ * gnutls_ext_get_name_ind - Used to get the name indicator send by a client
+ * @state: is a &GNUTLS_STATE structure.
+ * @ind: is a name indicator type
+ *
+ * This function will allow you to get the name indication (if any),
+ * a client has sent. The name indication may be any of the enumeration
+ * GNUTLS_NAME_IND.
+ *
+ * If 'ind' is GNUTLS_DNSNAME, then this function is to be used by servers
+ * that support virtual hosting.
+ * The client may give the server the dnsname they connected to.
+ *
+ * The return value depends on the 'ind' type. In case of GNUTLS_DNSNAME,
+ * it is a null terminated string. If no name indication was given (maybe the client
+ * does not support this extension) this function returns NULL.
+ *
+ **/
+const void* gnutls_ext_get_name_ind( GNUTLS_STATE state, GNUTLS_NAME_IND ind) {
+ if (state->security_parameters.entity==GNUTLS_CLIENT) return NULL;
+
+ switch( ind) {
+ case GNUTLS_DNSNAME:
+ if ( state->security_parameters.extensions.name.dnsname[0] == 0 ||
+ state->security_parameters.extensions.name.type!=ind) return NULL;
+ return state->security_parameters.extensions.name.dnsname;
+ }
+
+ return NULL;
+}
+
+/**
+ * gnutls_ext_set_name_ind - Used to set a name indicator to be sent as an extension
+ * @state: is a &GNUTLS_STATE structure.
+ * @name: is a null terminated string that contains the dns name.
+ * @ind: specified the indicator type
+ *
+ * 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.
+ *
+ * The value of 'name' depends on the 'ind' type. In case of GNUTLS_DNSNAME,
+ * a null terminated string is expected.
+ *
+ **/
+int gnutls_ext_set_name_ind( GNUTLS_STATE state, GNUTLS_NAME_IND ind, const void* name) {
+const char* dnsname;
+
+ if (state->security_parameters.entity==GNUTLS_SERVER) return GNUTLS_E_UNIMPLEMENTED_FEATURE;
+ state->security_parameters.extensions.name.type = ind;
+
+ switch(ind) {
+ case GNUTLS_DNSNAME:
+ dnsname = name;
+ if (strlen( dnsname) >= MAX_DNSNAME_SIZE) return GNUTLS_E_MEMORY_ERROR;
+ strcpy( state->security_parameters.extensions.name.dnsname, dnsname);
+ return 0;
+ }
+
+ return GNUTLS_E_UNIMPLEMENTED_FEATURE;
}
diff --git a/lib/ext_dnsname.h b/lib/ext_dnsname.h
index 89ae8bcfcc..62ba86d5e3 100644
--- a/lib/ext_dnsname.h
+++ b/lib/ext_dnsname.h
@@ -1,2 +1,7 @@
-int _gnutls_dnsname_recv_params( GNUTLS_STATE state, const opaque* data, int data_size);
-int _gnutls_dnsname_send_params( GNUTLS_STATE state, opaque** data);
+int _gnutls_name_ind_recv_params( GNUTLS_STATE state, const opaque* data, int data_size);
+int _gnutls_name_ind_send_params( GNUTLS_STATE state, opaque** data);
+
+const void* gnutls_ext_get_name_ind( GNUTLS_STATE state, GNUTLS_NAME_IND ind);
+int gnutls_ext_set_name_ind( GNUTLS_STATE state, GNUTLS_NAME_IND ind, const void* name);
+
+
diff --git a/lib/gnutls.h.in b/lib/gnutls.h.in
index e9ae8e184f..570cf9fce5 100644
--- a/lib/gnutls.h.in
+++ b/lib/gnutls.h.in
@@ -49,7 +49,7 @@ typedef enum AlertDescription { GNUTLS_CLOSE_NOTIFY, GNUTLS_UNEXPECTED_MESSAGE=1
GNUTLS_NO_RENEGOTIATION=100
} AlertDescription;
-
+typedef enum GNUTLS_NAME_IND { GNUTLS_DNSNAME=1 } GNUTLS_NAME_IND;
typedef enum CertificateStatus { GNUTLS_CERT_TRUSTED=1, GNUTLS_CERT_NOT_TRUSTED, GNUTLS_CERT_EXPIRED, GNUTLS_CERT_INVALID, GNUTLS_CERT_NONE } CertificateStatus;
typedef enum CertificateRequest { GNUTLS_CERT_REQUEST=1, GNUTLS_CERT_REQUIRE } CertificateRequest;
typedef enum CloseRequest { GNUTLS_SHUT_RDWR=0, GNUTLS_SHUT_WR=1 } CloseRequest;
@@ -154,8 +154,8 @@ void* gnutls_get_auth_info( GNUTLS_STATE);
* This will only exist if the client supports the dnsname
* TLS extension. (draft-ietf-tls-extensions)
*/
-const char* gnutls_ext_get_dnsname( GNUTLS_STATE);
-int gnutls_ext_set_dnsname( GNUTLS_STATE, const char* dnsname);
+const void* gnutls_ext_get_name_ind( GNUTLS_STATE state, GNUTLS_NAME_IND ind);
+int gnutls_ext_set_name_ind( GNUTLS_STATE state, GNUTLS_NAME_IND ind, const void* name);
/* This will set the Common Name field in case of X509PKI
* authentication. This will be used while verifying the
@@ -175,7 +175,6 @@ typedef struct DSTRUCT* SRP_CLIENT_CREDENTIALS;
typedef struct DSTRUCT* ANON_SERVER_CREDENTIALS;
typedef struct DSTRUCT* ANON_CLIENT_CREDENTIALS;
-
void gnutls_free_srp_client_sc( SRP_CLIENT_CREDENTIALS sc);
int gnutls_allocate_srp_client_sc( SRP_CLIENT_CREDENTIALS *sc);
int gnutls_set_srp_client_cred( SRP_CLIENT_CREDENTIALS res, char *username, char* password);
diff --git a/lib/gnutls_cert.c b/lib/gnutls_cert.c
index 50a24b238d..5382598b5f 100644
--- a/lib/gnutls_cert.c
+++ b/lib/gnutls_cert.c
@@ -994,7 +994,7 @@ int _gnutls_cert_supported_kx(gnutls_cert * cert, KXAlgorithm ** alg,
* common_name (or subjectAltDNSName) field similar to name
*/
gnutls_cert *_gnutls_find_cert(gnutls_cert ** cert_list,
- int cert_list_length, char *name)
+ int cert_list_length, const char *name)
{
gnutls_cert *cert = NULL;
int i;
@@ -1019,7 +1019,7 @@ gnutls_cert *_gnutls_find_cert(gnutls_cert ** cert_list,
* common_name (or subjectAltDNSName) field similar to name
*/
int _gnutls_find_cert_list_index(gnutls_cert ** cert_list,
- int cert_list_length, char *name)
+ int cert_list_length, const char *name)
{
int index = 0;
int i;
diff --git a/lib/gnutls_cert.h b/lib/gnutls_cert.h
index 2765d11229..06e416c70a 100644
--- a/lib/gnutls_cert.h
+++ b/lib/gnutls_cert.h
@@ -50,9 +50,9 @@ typedef struct {
int _gnutls_cert_supported_kx(gnutls_cert* cert, KXAlgorithm **alg, int *alg_size);
PKAlgorithm _gnutls_map_pk_get_pk(KXAlgorithm kx_algorithm);
int _gnutls_cert2gnutlsCert(gnutls_cert * gCert, gnutls_datum derCert);
-gnutls_cert* _gnutls_find_cert( gnutls_cert** cert_list, int cert_list_length, char* name);
+gnutls_cert* _gnutls_find_cert( gnutls_cert** cert_list, int cert_list_length, const char* name);
int _gnutls_find_cert_list_index(gnutls_cert ** cert_list,
- int cert_list_length, char *name);
+ int cert_list_length, const char *name);
#define MAX_INT_DIGITS 4
void _gnutls_int2str(int k, char* data);
diff --git a/lib/gnutls_extensions.c b/lib/gnutls_extensions.c
index 78f263b5b6..636fbb8f0c 100644
--- a/lib/gnutls_extensions.c
+++ b/lib/gnutls_extensions.c
@@ -39,7 +39,7 @@ 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_DNSNAME, _gnutls_name_ind_recv_params, _gnutls_name_ind_send_params),
{0}
};
@@ -164,40 +164,3 @@ int (*ext_func_send)( GNUTLS_STATE, opaque**);
}
-/**
- * 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 ( state->security_parameters.extensions.dnsname[0] == 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, const 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;
-}
diff --git a/lib/gnutls_handshake.c b/lib/gnutls_handshake.c
index bfbe5b505a..62fb2a76f1 100644
--- a/lib/gnutls_handshake.c
+++ b/lib/gnutls_handshake.c
@@ -38,6 +38,7 @@
#include "auth_x509.h"
#include "gnutls_cert.h"
#include "gnutls_constate.h"
+#include <ext_dnsname.h>
#ifdef HANDSHAKE_DEBUG
#define ERR(x, y) _gnutls_log( "GNUTLS Error: %s (%d)\n", x,y)
@@ -1738,6 +1739,7 @@ int _gnutls_remove_unwanted_ciphersuites(GNUTLS_STATE state,
KXAlgorithm *alg;
int alg_size;
KXAlgorithm kx;
+ const char* dnsname;
if (state->security_parameters.entity == GNUTLS_CLIENT)
return 0;
@@ -1758,12 +1760,13 @@ int _gnutls_remove_unwanted_ciphersuites(GNUTLS_STATE state,
*/
cert = NULL;
- if (state->security_parameters.extensions.dnsname[0] != 0) {
+ dnsname = gnutls_ext_get_name_ind(state, GNUTLS_DNSNAME);
+
+ if (dnsname!=NULL && dnsname[0] != 0) {
cert =
(gnutls_cert *) _gnutls_find_cert(x509_cred->cert_list,
x509_cred->ncerts,
- state->security_parameters.
- extensions.dnsname);
+ dnsname);
}
if (cert == NULL && x509_cred->cert_list != NULL) { /* if no such cert, use the first in the list
*/
diff --git a/lib/gnutls_int.h b/lib/gnutls_int.h
index 562e2ddd20..f23b832dbd 100644
--- a/lib/gnutls_int.h
+++ b/lib/gnutls_int.h
@@ -104,7 +104,6 @@ typedef enum HandshakeType { GNUTLS_HELLO_REQUEST, GNUTLS_CLIENT_HELLO, GNUTLS_S
GNUTLS_CERTIFICATE_REQUEST, GNUTLS_SERVER_HELLO_DONE,
GNUTLS_CERTIFICATE_VERIFY, GNUTLS_CLIENT_KEY_EXCHANGE,
GNUTLS_FINISHED=20 } HandshakeType;
-
typedef struct {
ChangeCipherSpecType type;
@@ -209,9 +208,16 @@ typedef struct {
* mechanism. (some extensions may hold parameters in AUTH_INFO
* structures instead - see SRP).
*/
+typedef enum GNUTLS_NAME_IND { GNUTLS_DNSNAME=1 } GNUTLS_NAME_IND;
+
typedef struct {
opaque dnsname[MAX_DNSNAME_SIZE];
- opaque srp_username[MAX_SRP_USERNAME];
+ GNUTLS_NAME_IND type;
+} name_ind;
+
+typedef struct {
+ name_ind name;
+ opaque srp_username[MAX_SRP_USERNAME];
} TLSExtensions;
/* AUTH_INFO structures MUST NOT contain malloced
diff --git a/src/cli.c b/src/cli.c
index 29176821ce..013c13ca06 100644
--- a/src/cli.c
+++ b/src/cli.c
@@ -227,9 +227,8 @@ int main(int argc, char** argv)
gnutls_set_cred( state, GNUTLS_X509PKI, xcred);
/* This TLS extension may break old implementations.
- *
- * gnutls_ext_set_dnsname( state, "localhost");
*/
+ gnutls_ext_set_name_ind( state, GNUTLS_DNSNAME, "localhost");
ret = gnutls_handshake(sd, state);
@@ -280,7 +279,7 @@ 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_ext_set_name_ind( state, GNUTLS_DNSNAME, "hello.server.org");
gnutls_set_mac_priority( state, GNUTLS_MAC_SHA, GNUTLS_MAC_MD5, 0);
diff --git a/src/crypt.c b/src/crypt.c
index a2f5ee7eb8..ee42fbc4ec 100644
--- a/src/crypt.c
+++ b/src/crypt.c
@@ -39,6 +39,8 @@ int crypt_int(char *username, char *passwd, int crypt, int salt,
static int read_conf_values(MPI * g, MPI * n, char *str, int str_size);
static int _verify_passwd_int(char* username, char* passwd, char* salt, MPI g, MPI n);
+int _gnutls_srp_generate_prime(unsigned char ** ret_g, unsigned char ** ret_n, int bits);
+
int generate_create_conf(char *tpasswd_conf, int bits)
{
FILE *fd;
diff --git a/src/serv.c b/src/serv.c
index f7878e0737..6efb43021d 100644
--- a/src/serv.c
+++ b/src/serv.c
@@ -128,9 +128,9 @@ void print_info(GNUTLS_STATE state)
printf("%.2X", sesid[i]);
printf("\n");
- if ( gnutls_ext_get_dnsname(state) != NULL) {
+ if ( gnutls_ext_get_name_ind(state, GNUTLS_DNSNAME) != NULL) {
printf("- DNSNAME: ");
- printf("%s\n", gnutls_ext_get_dnsname(state));
+ printf("%s\n", (char*)gnutls_ext_get_name_ind(state, GNUTLS_DNSNAME));
}
/* print srp specific data */
@@ -231,9 +231,9 @@ void peer_print_info(int cd, GNUTLS_STATE state)
/* if the client supports dnsname extension then
* print the hostname he connected to.
*/
- if (gnutls_ext_get_dnsname(state)!=NULL) {
+ if (gnutls_ext_get_name_ind(state, GNUTLS_DNSNAME)!=NULL) {
sprintf(tmp2, "\n<p>DNSNAME: ");
- sprintf(tmp2, "<b>%s</b></p>\n", gnutls_ext_get_dnsname(state));
+ sprintf(tmp2, "<b>%s</b></p>\n", (char*)gnutls_ext_get_name_ind(state, GNUTLS_DNSNAME));
}
/* print srp specific data */