summaryrefslogtreecommitdiff
path: root/lib
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 /lib
parentac2a96f653a8f83bca32307aa818a7cf7097e95a (diff)
downloadgnutls-7aaa6349add1a1de05d8f8a3a8e01fce35b3f118.tar.gz
server side client authentication worksgnutls_0_2_0
Diffstat (limited to 'lib')
-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
11 files changed, 160 insertions, 16 deletions
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;