diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/auth_rsa.c | 38 | ||||
-rw-r--r-- | lib/ext_srp.c | 9 | ||||
-rw-r--r-- | lib/gnutls_auth_int.h | 1 | ||||
-rw-r--r-- | lib/gnutls_handshake.c | 11 | ||||
-rw-r--r-- | lib/gnutls_int.h | 5 | ||||
-rw-r--r-- | lib/gnutls_kx.c | 2 | ||||
-rw-r--r-- | lib/gnutls_sig.c | 88 | ||||
-rw-r--r-- | lib/gnutls_sig.h | 4 | ||||
-rw-r--r-- | lib/gnutls_ui.h | 10 | ||||
-rw-r--r-- | lib/x509_sig_check.c | 6 | ||||
-rw-r--r-- | lib/x509_verify.c | 2 |
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; |