summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikos Mavrogiannopoulos <nmav@gnutls.org>2001-08-07 13:34:50 +0000
committerNikos Mavrogiannopoulos <nmav@gnutls.org>2001-08-07 13:34:50 +0000
commit7aaa6349add1a1de05d8f8a3a8e01fce35b3f118 (patch)
tree1a9292b379dff2f7408c070ad4f85ca62b882979
parentac2a96f653a8f83bca32307aa818a7cf7097e95a (diff)
downloadgnutls_0_2_0.tar.gz
server side client authentication worksgnutls_0_2_0
-rw-r--r--NEWS3
-rw-r--r--configure.in2
-rw-r--r--doc/tex/ex3.tex17
-rw-r--r--doc/tex/serv1.tex5
-rw-r--r--lib/auth_rsa.c38
-rw-r--r--lib/ext_srp.c9
-rw-r--r--lib/gnutls_auth_int.h1
-rw-r--r--lib/gnutls_handshake.c11
-rw-r--r--lib/gnutls_int.h5
-rw-r--r--lib/gnutls_kx.c2
-rw-r--r--lib/gnutls_sig.c88
-rw-r--r--lib/gnutls_sig.h4
-rw-r--r--lib/gnutls_ui.h10
-rw-r--r--lib/x509_sig_check.c6
-rw-r--r--lib/x509_verify.c2
-rw-r--r--src/cli.c18
-rw-r--r--src/serv.c46
17 files changed, 229 insertions, 38 deletions
diff --git a/NEWS b/NEWS
index 111a8f8cba..47c02ebe8e 100644
--- a/NEWS
+++ b/NEWS
@@ -1,8 +1,9 @@
-Version 0.2.0
+Version 0.2.0 (07/08/2001)
- Partial support for X509v3 Certificate extensions.
- Added Internal memory handlers
- Removed gnutls_x509_set_cn()
- Added X509 client authentication
+- Several bug fixes and protocol fixes
Version 0.1.9 (30/07/2001)
- Corrected bug(s) in ChangeCipherSpec packet (fixes renegotiate)
diff --git a/configure.in b/configure.in
index ef6eedc90d..f2c75f7969 100644
--- a/configure.in
+++ b/configure.in
@@ -24,7 +24,7 @@ GNUTLS_MOST_RECENT_INTERFACE=$GNUTLS_MINOR_VERSION
GNUTLS_CURRENT_INTERFACE_IMPLEMENTATION_NUMBER=$GNUTLS_MICRO_VERSION
GNUTLS_OLDEST_INTERFACE=0
-AM_PATH_LIBGCRYPT(1.1.3,,
+AM_PATH_LIBGCRYPT(1.1.4,,
AC_MSG_ERROR([[
***
*** libgcrypt was not found. You may want to get it from
diff --git a/doc/tex/ex3.tex b/doc/tex/ex3.tex
index 6eec57ddc6..6aca20fbb9 100644
--- a/doc/tex/ex3.tex
+++ b/doc/tex/ex3.tex
@@ -41,17 +41,16 @@ int print_info(GNUTLS_STATE state)
break;
}
- }
- printf(" - Certificate info:\n");
- printf(" - Certificate version: #%d\n", gnutls_x509pki_client_get_peer_certificate_version(x509_info));
-
- dn = gnutls_x509pki_client_get_peer_dn( x509_info);
- PRINT_DN(dn);
+ printf(" - Certificate info:\n");
+ printf(" - Certificate version: #%d\n", gnutls_x509pki_client_get_peer_certificate_version(x509_info));
- printf(" - Certificate Issuer's info:\n");
- dn = gnutls_x509pki_client_get_issuer_dn( x509_info);
- PRINT_DN(dn);
+ dn = gnutls_x509pki_client_get_peer_dn( x509_info);
+ PRINT_DN(dn);
+ printf(" - Certificate Issuer's info:\n");
+ dn = gnutls_x509pki_client_get_issuer_dn( x509_info);
+ PRINT_DN(dn);
+ }
}
tmp = gnutls_version_get_name(gnutls_get_current_version(state));
diff --git a/doc/tex/serv1.tex b/doc/tex/serv1.tex
index 0cbdd96f5e..78cd49ca47 100644
--- a/doc/tex/serv1.tex
+++ b/doc/tex/serv1.tex
@@ -54,7 +54,10 @@ GNUTLS_STATE initialize_state()
gnutls_set_cred(state, GNUTLS_SRP, srp_cred);
gnutls_set_cred(state, GNUTLS_X509PKI, x509_cred);
-
+ /* request client certificate if any.
+ */
+ gnutls_set_certificate_request( state, GNUTLS_CERT_REQUEST);
+
return state;
}
diff --git a/lib/auth_rsa.c b/lib/auth_rsa.c
index d5876d42b3..d92ee1d22a 100644
--- a/lib/auth_rsa.c
+++ b/lib/auth_rsa.c
@@ -527,6 +527,9 @@ int proc_rsa_server_certificate(GNUTLS_STATE state, opaque * data, int data_size
verify = gnutls_verify_certificate(peer_certificate_list, peer_certificate_list_size,
cred->ca_list, cred->ncas, NULL, 0);
+ /* keep the PK algorithm */
+ state->gnutls_internals.peer_pk_algorithm = peer_certificate_list[0].subject_pk_algorithm;
+
_gnutls_copy_x509_client_auth_info(info, &peer_certificate_list[0], verify);
/* This works for the client
@@ -819,8 +822,41 @@ int gen_rsa_client_cert_vrfy(GNUTLS_STATE state, opaque ** data)
int proc_rsa_client_cert_vrfy(GNUTLS_STATE state, opaque * data, int data_size)
{
- #warning "CHECK THE CERT VERIFY MESSAGE"
+int size, ret;
+int dsize = data_size;
+opaque* pdata = data;
+gnutls_cert cert;
+gnutls_datum sig;
+
+ DECR_LEN(dsize, 2);
+ size = READuint16( pdata);
+ pdata += 2;
+
+ if ( size < data_size - 2) {
+ gnutls_assert();
+ return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
+ }
+
+ sig.data = pdata;
+ sig.size = size;
+ cert.params = gnutls_malloc( 2*sizeof(MPI));
+ if (cert.params==NULL) {
+ gnutls_assert();
+ return GNUTLS_E_MEMORY_ERROR;
+ }
+ cert.params[0] = state->gnutls_key->x;
+ cert.params[1] = state->gnutls_key->a;
+ cert.subject_pk_algorithm = state->gnutls_internals.peer_pk_algorithm;
+
+ if ( (ret=_gnutls_verify_sig( state, &cert, &sig, data_size+HANDSHAKE_HEADER_SIZE))<0) {
+ gnutls_assert();
+ gnutls_free( cert.params);
+ return ret;
+ }
+
+ gnutls_free( cert.params);
+
return 0;
}
diff --git a/lib/ext_srp.c b/lib/ext_srp.c
index 887bfbbf56..d4476b19d1 100644
--- a/lib/ext_srp.c
+++ b/lib/ext_srp.c
@@ -35,8 +35,15 @@ int _gnutls_srp_recv_params( GNUTLS_STATE state, const opaque* data, int data_si
}
if (state->security_parameters.entity == GNUTLS_SERVER) {
+ /* algorithm was not selected
+ */
+ if ( gnutls_get_auth_info_type( state) != GNUTLS_SRP)
+ return 0;
+
if (data_size > 0) {
- state->gnutls_key->auth_info = gnutls_calloc(1, sizeof(SRP_SERVER_AUTH_INFO));
+ if ( state->gnutls_key->auth_info == NULL)
+ state->gnutls_key->auth_info = gnutls_calloc(1, sizeof(SRP_SERVER_AUTH_INFO));
+
if (state->gnutls_key->auth_info==NULL) return GNUTLS_E_MEMORY_ERROR;
if (sizeof( ((SRP_SERVER_AUTH_INFO)state->gnutls_key->auth_info)->username) > data_size) {
diff --git a/lib/gnutls_auth_int.h b/lib/gnutls_auth_int.h
index 1deb4da09f..6885edeb92 100644
--- a/lib/gnutls_auth_int.h
+++ b/lib/gnutls_auth_int.h
@@ -3,3 +3,4 @@ int gnutls_set_cred( GNUTLS_STATE state, CredType type, void* cred);
const void *_gnutls_get_cred( GNUTLS_KEY key, CredType kx, int* err);
const void *_gnutls_get_kx_cred( GNUTLS_KEY key, KXAlgorithm algo, int *err);
int _gnutls_generate_key(GNUTLS_KEY key);
+CredType gnutls_get_auth_info_type( GNUTLS_STATE);
diff --git a/lib/gnutls_handshake.c b/lib/gnutls_handshake.c
index 2f425202f7..307c740284 100644
--- a/lib/gnutls_handshake.c
+++ b/lib/gnutls_handshake.c
@@ -725,7 +725,10 @@ int _gnutls_recv_handshake(SOCKET cd, GNUTLS_STATE state, uint8 ** data,
if (length32 > 0)
dataptr = gnutls_malloc(length32);
else
-fprintf(stderr, "recv_type: %d\nLenght: %d\n", recv_type, length32);
+ if (recv_type != GNUTLS_SERVER_HELLO_DONE) {
+ gnutls_assert();
+ return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
+ }
if (dataptr == NULL) {
gnutls_assert();
@@ -781,9 +784,9 @@ fprintf(stderr, "recv_type: %d\nLenght: %d\n", recv_type, length32);
ret = length32;
break;
case GNUTLS_CERTIFICATE_REQUEST:
-#ifdef HANDSHAKE_DEBUG
- _gnutls_log("Requested Client Certificate!\n");
-#endif
+ ret = length32;
+ break;
+ case GNUTLS_CERTIFICATE_VERIFY:
ret = length32;
break;
default:
diff --git a/lib/gnutls_int.h b/lib/gnutls_int.h
index 315078cec2..c3960eb335 100644
--- a/lib/gnutls_int.h
+++ b/lib/gnutls_int.h
@@ -30,9 +30,9 @@
#define BUFFERS_DEBUG
#define HARD_DEBUG
#define RECORD_DEBUG
-#define HANDSHAKE_DEBUG*/
+#define HANDSHAKE_DEBUG
#define DEBUG
-
+*/
#define SOCKET int
#define LIST ...
@@ -348,6 +348,7 @@ typedef struct {
* supports it.
*/
int send_cert_req;
+ int peer_pk_algorithm;
} GNUTLS_INTERNALS;
struct GNUTLS_STATE_INT {
diff --git a/lib/gnutls_kx.c b/lib/gnutls_kx.c
index 49786440dd..24ad5376bd 100644
--- a/lib/gnutls_kx.c
+++ b/lib/gnutls_kx.c
@@ -640,7 +640,7 @@ int _gnutls_recv_client_certificate_verify_message(SOCKET cd, GNUTLS_STATE state
ret =
_gnutls_recv_handshake(cd, state, &data,
&datasize,
- GNUTLS_CLIENT_KEY_EXCHANGE, OPTIONAL_PACKET);
+ GNUTLS_CERTIFICATE_VERIFY, OPTIONAL_PACKET);
if (ret < 0)
return ret;
diff --git a/lib/gnutls_sig.c b/lib/gnutls_sig.c
index ee206008d0..9005f51b8d 100644
--- a/lib/gnutls_sig.c
+++ b/lib/gnutls_sig.c
@@ -88,7 +88,6 @@ int ret;
}
-
int _gnutls_pkcs1_rsa_generate_sig( gnutls_private_key *pkey, const gnutls_datum *data, gnutls_datum *signature) {
int ret;
@@ -100,3 +99,90 @@ int _gnutls_pkcs1_rsa_generate_sig( gnutls_private_key *pkey, const gnutls_datum
return 0;
}
+
+int _gnutls_pkcs1_rsa_verify_sig( gnutls_cert *cert, const gnutls_datum *data, gnutls_datum *signature) {
+ int ret;
+ gnutls_datum plain;
+
+ /* decrypt signature */
+ if ( (ret=_gnutls_pkcs1_rsa_decrypt( &plain, *signature, cert->params[0], cert->params[1], 1)) < 0) {
+ gnutls_assert();
+ return ret;
+ }
+
+ if (plain.size != data->size) {
+ gnutls_assert();
+ return GNUTLS_E_PK_SIGNATURE_FAILED;
+ }
+
+ if ( memcmp(plain.data, data->data, plain.size)!=0) {
+ gnutls_assert();
+ return GNUTLS_E_PK_SIGNATURE_FAILED;
+ }
+
+ return 0;
+}
+
+
+/* Verifies a TLS signature (like the one in the client certificate
+ * verify message).
+ */
+int _gnutls_verify_sig( GNUTLS_STATE state, gnutls_cert *cert, gnutls_datum* signature, int ubuffer_size) {
+opaque digest[20+16];
+gnutls_datum data;
+GNUTLS_HASH_HANDLE td;
+int size = gnutls_getHashDataBufferSize( state) - ubuffer_size; /* do not get the last message */
+int ret;
+
+ data.data = gnutls_malloc(size);
+ data.size = size;
+ if (data.data==NULL) {
+ gnutls_assert();
+ return GNUTLS_E_MEMORY_ERROR;
+ }
+
+ gnutls_readHashDataFromBuffer( state, data.data, data.size);
+
+ switch(cert->subject_pk_algorithm) {
+ case GNUTLS_PK_RSA:
+
+ td = gnutls_hash_init( GNUTLS_MAC_MD5);
+ if (td==NULL) {
+ gnutls_assert();
+ gnutls_free_datum( &data);
+ return GNUTLS_E_MEMORY_ERROR;
+ }
+ gnutls_hash( td, data.data, data.size);
+ gnutls_hash_deinit( td, digest);
+
+ td = gnutls_hash_init( GNUTLS_MAC_SHA);
+ if (td==NULL) {
+ gnutls_assert();
+ gnutls_free_datum( &data);
+ return GNUTLS_E_MEMORY_ERROR;
+ }
+ gnutls_hash( td, data.data, data.size);
+ gnutls_hash_deinit( td, &digest[16]);
+ gnutls_free_datum( &data);
+
+
+ data.data = digest;
+ data.size = 20+16; /* md5 + sha */
+ ret = _gnutls_pkcs1_rsa_verify_sig( cert, &data, signature);
+
+ break;
+ default:
+ gnutls_assert();
+ gnutls_free_datum( &data);
+ ret = GNUTLS_E_UNIMPLEMENTED_FEATURE;
+ break;
+ }
+
+ return ret;
+
+}
+
+
+
+
+
diff --git a/lib/gnutls_sig.h b/lib/gnutls_sig.h
index 03ee658cda..95725c222d 100644
--- a/lib/gnutls_sig.h
+++ b/lib/gnutls_sig.h
@@ -1,4 +1,4 @@
-int _gnutls_pkcs1_rsa_verify_sig( gnutls_datum* signature, gnutls_datum *text, MPI m, MPI e);
-CertificateStatus gnutls_verify_signature(gnutls_cert* cert, gnutls_cert* issuer);
+CertificateStatus gnutls_x509_verify_signature(gnutls_cert* cert, gnutls_cert* issuer);
int _gnutls_pkcs1_rsa_generate_sig( gnutls_private_key *pkey, const gnutls_datum *data, gnutls_datum *signature);
int _gnutls_generate_sig( GNUTLS_STATE state, gnutls_private_key *pkey, gnutls_datum *signature);
+int _gnutls_verify_sig( GNUTLS_STATE state, gnutls_cert *cert, gnutls_datum* signature, int ubuffer_size);
diff --git a/lib/gnutls_ui.h b/lib/gnutls_ui.h
index ac8968f51f..a87bc04851 100644
--- a/lib/gnutls_ui.h
+++ b/lib/gnutls_ui.h
@@ -59,6 +59,16 @@ time_t gnutls_x509pki_client_get_peer_certificate_activation_time( X509PKI_CLIE
time_t gnutls_x509pki_client_get_peer_certificate_expiration_time( X509PKI_CLIENT_AUTH_INFO info);
unsigned char gnutls_x509pki_client_get_key_usage( X509PKI_CLIENT_AUTH_INFO info);
const char* gnutls_x509pki_client_get_subject_alt_name( X509PKI_CLIENT_AUTH_INFO info);
+
+#define gnutls_x509pki_server_get_peer_dn gnutls_x509pki_client_get_peer_dn
+#define gnutls_x509pki_server_get_issuer_dn gnutls_x509pki_client_get_issuer_dn
+#define gnutls_x509pki_server_get_peer_certificate_status gnutls_x509pki_client_get_peer_certificate_status
+#define gnutls_x509pki_server_get_peer_certificate_version gnutls_x509pki_client_get_peer_certificate_version
+#define gnutls_x509pki_server_get_peer_certificate_activation_time gnutls_x509pki_client_get_peer_certificate_activation_time
+#define gnutls_x509pki_server_get_peer_certificate_expiration_time gnutls_x509pki_client_get_peer_certificate_expiration_time
+#define gnutls_x509pki_server_get_key_usage gnutls_x509pki_client_get_key_usage
+#define gnutls_x509pki_server_get_subject_alt_name gnutls_x509pki_client_get_subject_alt_name
+
# endif /* LIBGNUTLS_VERSION */
#endif
diff --git a/lib/x509_sig_check.c b/lib/x509_sig_check.c
index bd3f09fbf4..93df424358 100644
--- a/lib/x509_sig_check.c
+++ b/lib/x509_sig_check.c
@@ -144,7 +144,7 @@ int len;
* e is public key
*/
int
-_gnutls_pkcs1_rsa_verify_sig( gnutls_datum* signature, gnutls_datum* text, MPI e, MPI m)
+_pkcs1_rsa_verify_sig( gnutls_datum* signature, gnutls_datum* text, MPI e, MPI m)
{
MACAlgorithm hash;
int ret;
@@ -187,7 +187,7 @@ _gnutls_pkcs1_rsa_verify_sig( gnutls_datum* signature, gnutls_datum* text, MPI e
return 0;
}
-CertificateStatus gnutls_verify_signature(gnutls_cert* cert, gnutls_cert* issuer) {
+CertificateStatus gnutls_x509_verify_signature(gnutls_cert* cert, gnutls_cert* issuer) {
gnutls_datum signature;
gnutls_datum* tbs;
@@ -201,7 +201,7 @@ gnutls_datum* tbs;
return GNUTLS_CERT_INVALID;
}
- if (_gnutls_pkcs1_rsa_verify_sig( &signature, tbs, issuer->params[1], issuer->params[0])!=0) {
+ if (_pkcs1_rsa_verify_sig( &signature, tbs, issuer->params[1], issuer->params[0])!=0) {
gnutls_assert();
gnutls_free_datum( tbs);
return GNUTLS_CERT_NOT_TRUSTED;
diff --git a/lib/x509_verify.c b/lib/x509_verify.c
index aa5a61c9c1..1f1f3fb39c 100644
--- a/lib/x509_verify.c
+++ b/lib/x509_verify.c
@@ -289,7 +289,7 @@ int gnutls_verify_certificate2(gnutls_cert * cert, gnutls_cert * trusted_cas, in
return GNUTLS_CERT_NOT_TRUSTED;
}
- ret = gnutls_verify_signature(cert, issuer);
+ ret = gnutls_x509_verify_signature(cert, issuer);
if (ret != GNUTLS_CERT_TRUSTED)
return ret;
diff --git a/src/cli.c b/src/cli.c
index 185110de49..d3377609de 100644
--- a/src/cli.c
+++ b/src/cli.c
@@ -85,17 +85,17 @@ const gnutls_DN* dn;
break;
}
- }
- printf(" - Certificate info:\n");
- printf(" - Certificate version: #%d\n", gnutls_x509pki_client_get_peer_certificate_version(x509_info));
+ printf(" - Certificate info:\n");
+ printf(" - Certificate version: #%d\n", gnutls_x509pki_client_get_peer_certificate_version(x509_info));
- dn = gnutls_x509pki_client_get_peer_dn( x509_info);
- PRINT_DN( dn);
+ dn = gnutls_x509pki_client_get_peer_dn( x509_info);
+ PRINT_DN( dn);
- dn = gnutls_x509pki_client_get_issuer_dn( x509_info);
- printf(" - Certificate Issuer's info:\n");
- PRINT_DN( dn);
+ dn = gnutls_x509pki_client_get_issuer_dn( x509_info);
+ printf(" - Certificate Issuer's info:\n");
+ PRINT_DN( dn);
+ }
}
tmp = gnutls_version_get_name(gnutls_get_current_version(state));
@@ -146,7 +146,7 @@ int main(int argc, char** argv)
/* X509 stuff */
- if (gnutls_allocate_x509_client_sc( &xcred, 1) < 0) {
+ if (gnutls_allocate_x509_client_sc( &xcred, 1) < 0) { /* space for 1 certificate */
fprintf(stderr, "memory error\n");
exit(1);
}
diff --git a/src/serv.c b/src/serv.c
index ab95803352..721cc7c7b9 100644
--- a/src/serv.c
+++ b/src/serv.c
@@ -105,18 +105,29 @@ GNUTLS_STATE initialize_state()
gnutls_set_mac_priority(state, GNUTLS_MAC_SHA, GNUTLS_MAC_MD5, 0);
- gnutls_set_certificate_request( state, GNUTLS_CERT_REQUIRE);
+ gnutls_set_certificate_request( state, GNUTLS_CERT_REQUEST);
return state;
}
+#define PRINTX(x,y) if (y[0]!=0) printf(" - %s %s\n", x, y)
+#define PRINT_DN(X) PRINTX( "CN:", X->common_name); \
+ PRINTX( "OU:", X->organizational_unit_name); \
+ PRINTX( "O:", X->organization); \
+ PRINTX( "L:", X->locality_name); \
+ PRINTX( "S:", X->state_or_province_name); \
+ PRINTX( "C:", X->country); \
+ PRINTX( "SAN:", gnutls_x509pki_client_get_subject_alt_name(x509_info))
+
void print_info(GNUTLS_STATE state)
{
SRP_SERVER_AUTH_INFO srp_info;
ANON_SERVER_AUTH_INFO dh_info;
+ X509PKI_SERVER_AUTH_INFO x509_info;
const char *tmp;
unsigned char sesid[32];
int sesid_size, i;
+ const gnutls_DN* dn;
/* print session_id specific data */
gnutls_get_current_session_id( state, sesid, &sesid_size);
@@ -144,6 +155,39 @@ void print_info(GNUTLS_STATE state)
gnutls_anon_server_get_dh_bits(dh_info));
}
+ if (gnutls_get_auth_info_type(state) == GNUTLS_X509PKI) {
+ x509_info = gnutls_get_auth_info(state);
+ if (x509_info != NULL) {
+ switch( gnutls_x509pki_client_get_peer_certificate_status(x509_info)) {
+ case GNUTLS_CERT_NOT_TRUSTED:
+ printf("- Peer's X509 Certificate was NOT verified\n");
+ break;
+ case GNUTLS_CERT_EXPIRED:
+ printf("- Peer's X509 Certificate was verified but is expired\n");
+ break;
+ case GNUTLS_CERT_TRUSTED:
+ printf("- Peer's X509 Certificate was verified\n");
+ break;
+ case GNUTLS_CERT_INVALID:
+ default:
+ printf("- Peer's X509 Certificate was invalid\n");
+ break;
+
+ }
+
+ printf(" - Certificate info:\n");
+ printf(" - Certificate version: #%d\n", gnutls_x509pki_client_get_peer_certificate_version(x509_info));
+
+ dn = gnutls_x509pki_client_get_peer_dn( x509_info);
+ PRINT_DN( dn);
+
+ dn = gnutls_x509pki_client_get_issuer_dn( x509_info);
+ printf(" - Certificate Issuer's info:\n");
+ PRINT_DN( dn);
+ }
+ }
+
+
/* print state information */
tmp = gnutls_version_get_name(gnutls_get_current_version(state));