diff options
author | Nikos Mavrogiannopoulos <nmav@gnutls.org> | 2001-12-05 12:50:26 +0000 |
---|---|---|
committer | Nikos Mavrogiannopoulos <nmav@gnutls.org> | 2001-12-05 12:50:26 +0000 |
commit | 091cea8dbd1e5fbd940d4c863b68d5eb5ff7cab3 (patch) | |
tree | b4d9b106120d97bb561fb75d2ee54a6b9352a40d | |
parent | 834e429a7169d4b5f239bc2980bda801e2bbdba0 (diff) | |
download | gnutls-091cea8dbd1e5fbd940d4c863b68d5eb5ff7cab3.tar.gz |
several cleanups. Removed old unneeded functions.
certificate verification was moved out of the handshake procedure.
-rw-r--r-- | lib/auth_dhe_rsa.c | 1 | ||||
-rw-r--r-- | lib/auth_x509.c | 230 | ||||
-rw-r--r-- | lib/auth_x509.h | 5 | ||||
-rw-r--r-- | lib/gnutls_cert.h | 2 | ||||
-rw-r--r-- | lib/gnutls_ui.h | 2 | ||||
-rw-r--r-- | src/serv.c | 4 |
6 files changed, 71 insertions, 173 deletions
diff --git a/lib/auth_dhe_rsa.c b/lib/auth_dhe_rsa.c index dea2635e39..ea219ef6d8 100644 --- a/lib/auth_dhe_rsa.c +++ b/lib/auth_dhe_rsa.c @@ -104,7 +104,6 @@ static int gen_dhe_rsa_server_kx(GNUTLS_STATE state, opaque ** data) info = state->gnutls_key->auth_info; info->dh_bits = gcry_mpi_get_nbits(p); - info->peer_certificate_status = GNUTLS_CERT_NONE; state->gnutls_key->auth_info_type = GNUTLS_X509PKI; } else diff --git a/lib/auth_x509.c b/lib/auth_x509.c index 95b366b4fc..b29adfb52b 100644 --- a/lib/auth_x509.c +++ b/lib/auth_x509.c @@ -41,13 +41,11 @@ /* Copies data from a internal certificate struct (gnutls_cert) to * exported certificate struct (X509PKI_AUTH_INFO) */ -int _gnutls_copy_x509_auth_info( X509PKI_AUTH_INFO info, gnutls_cert* cert, int ncerts, CertificateStatus verify) { +int _gnutls_copy_x509_auth_info( X509PKI_AUTH_INFO info, gnutls_cert* cert, int ncerts) { /* Copy peer's information to AUTH_INFO */ int ret, i, j; - info->peer_certificate_status = verify; - if (ncerts==0) { info->raw_certificate_list = NULL; info->ncerts = 0; @@ -84,140 +82,6 @@ int ret, i, j; return ret; } -typedef struct { - gnutls_datum rsa_modulus; - gnutls_datum rsa_exponent; -} RSA_Params; - -/* This function extracts the RSA parameters from the given(?) certificate. - */ -static int _gnutls_get_rsa_params(RSA_Params * params, - MPI * mod, MPI * exp, gnutls_datum cert) -{ - int ret = 0, result; - opaque str[5 * 1024]; - int len = sizeof(str); - node_asn *srsa, *spk; - - if (asn1_create_structure(_gnutls_get_pkix(), "PKIX1Implicit88.Certificate", &srsa, "rsa_params") - != ASN_OK) { - gnutls_assert(); - return GNUTLS_E_ASN1_ERROR; - } - result = asn1_get_der(srsa, cert.data, cert.size); - if (result != ASN_OK) { - /* couldn't decode DER */ - gnutls_assert(); - return GNUTLS_E_ASN1_PARSING_ERROR; - } - len = sizeof(str) - 1; - result = - asn1_read_value - (srsa, "rsa_params.tbsCertificate.subjectPublicKeyInfo.algorithm.algorithm", - str, &len); - - if (result != ASN_OK) { - gnutls_assert(); - asn1_delete_structure(srsa); - return GNUTLS_E_ASN1_PARSING_ERROR; - } - if (!strcmp(str, "1 2 840 113549 1 1 1")) { /* pkix-1 1 - RSA */ - len = sizeof(str) - 1; - result = - asn1_read_value - (srsa, "rsa_params.tbsCertificate.subjectPublicKeyInfo.subjectPublicKey", - str, &len); - asn1_delete_structure(srsa); - - if (result != ASN_OK) { - gnutls_assert(); - return GNUTLS_E_ASN1_PARSING_ERROR; - } - if (asn1_create_structure - (_gnutls_get_pkcs(), - "PKCS-1.RSAPublicKey", &spk, "rsa_public_key") != ASN_OK) { - gnutls_assert(); - return GNUTLS_E_ASN1_ERROR; - } - if (len % 8 != 0) { - gnutls_assert(); - asn1_delete_structure(spk); - return GNUTLS_E_UNIMPLEMENTED_FEATURE; - } - result = asn1_get_der(spk, str, len / 8); - - if (result != ASN_OK) { - gnutls_assert(); - asn1_delete_structure(spk); - return GNUTLS_E_ASN1_PARSING_ERROR; - } - len = sizeof(str) - 1; - result = asn1_read_value(spk, "rsa_public_key.modulus", str, &len); - if (result != ASN_OK) { - gnutls_assert(); - asn1_delete_structure(spk); - return GNUTLS_E_ASN1_PARSING_ERROR; - } - if (_gnutls_mpi_scan(mod, GCRYMPI_FMT_USG, str, &len) != 0) { - gnutls_assert(); - asn1_delete_structure(spk); - return GNUTLS_E_MPI_SCAN_FAILED; - } - if (params != NULL) - if (gnutls_set_datum - (¶ms->rsa_modulus, str, len) < 0) { - gnutls_assert(); - asn1_delete_structure(spk); - return GNUTLS_E_MEMORY_ERROR; - } - len = sizeof(str) - 1; - result = - asn1_read_value(spk, "rsa_public_key.publicExponent", str, &len); - if (result != ASN_OK) { - gnutls_assert(); - asn1_delete_structure(spk); - if (params != NULL) - gnutls_free_datum(¶ms->rsa_modulus); - _gnutls_mpi_release(mod); - return GNUTLS_E_ASN1_PARSING_ERROR; - } - if (_gnutls_mpi_scan(exp, GCRYMPI_FMT_USG, str, &len) != 0) { - gnutls_assert(); - _gnutls_mpi_release(mod); - if (params != NULL) - gnutls_free_datum(¶ms->rsa_modulus); - asn1_delete_structure(spk); - return GNUTLS_E_MPI_SCAN_FAILED; - } - if (params != NULL) - if (gnutls_set_datum - (¶ms->rsa_exponent, str, len) < 0) { - _gnutls_mpi_release(mod); - _gnutls_mpi_release(exp); - if (params != NULL) - gnutls_free_datum(¶ms-> - rsa_modulus); - asn1_delete_structure(spk); - return GNUTLS_E_MEMORY_ERROR; - } - asn1_delete_structure(spk); - - ret = 0; - - } else { - /* The certificate that was sent was not - * supported by the ciphersuite - */ - gnutls_assert(); - ret = GNUTLS_E_X509_CERTIFICATE_ERROR; - - asn1_delete_structure(srsa); - } - - - return ret; -} - /* This function reads the RSA parameters from the given private key * cert is not a certificate but a der structure containing the private * key(s). @@ -545,7 +409,6 @@ int _gnutls_proc_x509_server_certificate(GNUTLS_STATE state, opaque * data, int gnutls_cert *peer_certificate_list; int peer_certificate_list_size = 0; gnutls_datum tmp; - CertificateStatus verify; cred = _gnutls_get_cred(state->gnutls_key, GNUTLS_X509PKI, NULL); if (cred == NULL) { @@ -563,7 +426,6 @@ int _gnutls_proc_x509_server_certificate(GNUTLS_STATE state, opaque * data, int state->gnutls_key->auth_info_size = sizeof(X509PKI_AUTH_INFO_INT); info = state->gnutls_key->auth_info; - info->peer_certificate_status = GNUTLS_CERT_NONE; state->gnutls_key->auth_info_type = GNUTLS_X509PKI; } else @@ -582,7 +444,6 @@ int _gnutls_proc_x509_server_certificate(GNUTLS_STATE state, opaque * data, int if (size == 0) { gnutls_assert(); /* no certificate was sent */ - info->peer_certificate_status = GNUTLS_CERT_NONE; return GNUTLS_E_NO_CERTIFICATE_FOUND; } i = dsize; @@ -637,32 +498,27 @@ int _gnutls_proc_x509_server_certificate(GNUTLS_STATE state, opaque * data, int j++; } - /* store the required parameters for the handshake + /* move RSA parameters to gnutls_key (state). */ - if ((ret = - _gnutls_get_rsa_params(NULL, &state->gnutls_key->a, &state->gnutls_key->x, - peer_certificate_list[0].raw)) < 0) { - gnutls_assert(); - CLEAR_CERTS; - gnutls_free(peer_certificate_list); - return ret; - } - /* Verify certificate - */ - verify = gnutls_verify_certificate(peer_certificate_list, peer_certificate_list_size, - cred->ca_list, cred->ncas, NULL, 0); - if (verify < 0) { + state->gnutls_key->a = gcry_mpi_copy(peer_certificate_list[0].params[0]); + state->gnutls_key->x = gcry_mpi_copy(peer_certificate_list[0].params[1]); + + if (state->gnutls_key->a==NULL || state->gnutls_key->x==NULL) { + _gnutls_mpi_release( &state->gnutls_key->a); + _gnutls_mpi_release( &state->gnutls_key->x); gnutls_assert(); CLEAR_CERTS; gnutls_free(peer_certificate_list); - return verify; + return GNUTLS_E_MEMORY_ERROR; } /* keep the PK algorithm */ state->gnutls_internals.peer_pk_algorithm = peer_certificate_list[0].subject_pk_algorithm; - if ( (ret = _gnutls_copy_x509_auth_info(info, peer_certificate_list, peer_certificate_list_size, verify)) < 0) { + if ( (ret = _gnutls_copy_x509_auth_info(info, peer_certificate_list, peer_certificate_list_size)) < 0) { gnutls_assert(); + CLEAR_CERTS; + gnutls_free(peer_certificate_list); return ret; } @@ -721,7 +577,6 @@ int _gnutls_proc_x509_cert_req(GNUTLS_STATE state, opaque * data, int data_size) state->gnutls_key->auth_info_size = sizeof(X509PKI_AUTH_INFO_INT); info = state->gnutls_key->auth_info; - info->peer_certificate_status = GNUTLS_CERT_NONE; } info = state->gnutls_key->auth_info; @@ -1110,7 +965,6 @@ int gnutls_x509pki_get_subject_dns_name(GNUTLS_STATE state, char* ret, int *ret_ if ((result = _gnutls_get_extension( &info->raw_certificate_list[0], "2 5 29 17", &dnsname)) < 0) { - gnutls_assert(); return result; } @@ -1278,22 +1132,66 @@ int gnutls_x509pki_get_peer_certificate_version(GNUTLS_STATE state) * gnutls_x509pki_get_peer_certificate_status - This function returns the peer's certificate status * @state: is a gnutls state * - * This function will return the peer's certificate status (TRUSTED, EXPIRED etc.). This is the output - * of the certificate verification function. However you must also check the peer's name in order - * to check if the verified certificate belongs to the actual peer. - * Returns GNUTLS_CERT_NONE in case of an error, or if no certificate was sent. + * This function will try to verify the peer's certificate and return it's status (TRUSTED, EXPIRED etc.). + * Status should be one of the CertificateStatus enumerated elements. + * However you must also check the peer's name in order to check if the verified certificate belongs to the + * actual peer. Returns a negative error code in case of an error, or GNUTLS_CERT_NONE if no certificate was sent. * **/ -CertificateStatus gnutls_x509pki_get_peer_certificate_status(GNUTLS_STATE - state) +int gnutls_x509pki_get_peer_certificate_status(GNUTLS_STATE state) { X509PKI_AUTH_INFO info; + const X509PKI_CREDENTIALS cred; + CertificateStatus verify; + gnutls_cert* peer_certificate_list; + int peer_certificate_list_size, i, x, ret; - CHECK_AUTH(GNUTLS_X509PKI, GNUTLS_CERT_NONE); + CHECK_AUTH(GNUTLS_X509PKI, GNUTLS_E_INVALID_REQUEST); info = _gnutls_get_auth_info(state); if (info == NULL) + return GNUTLS_E_INVALID_REQUEST; + + cred = _gnutls_get_cred(state->gnutls_key, GNUTLS_X509PKI, NULL); + if (cred == NULL) { + gnutls_assert(); + return GNUTLS_E_INSUFICIENT_CRED; + } + + if (info->raw_certificate_list==NULL || info->ncerts==0) return GNUTLS_CERT_NONE; - return info->peer_certificate_status; + /* generate a list of gnutls_certs based on the auth info + * raw certs. + */ + peer_certificate_list_size = info->ncerts; + peer_certificate_list = gnutls_calloc( 1, peer_certificate_list_size*sizeof(gnutls_cert)); + if (peer_certificate_list==NULL) { + gnutls_assert(); + return GNUTLS_E_MEMORY_ERROR; + } + + for (i=0;i<peer_certificate_list_size;i++) { + if ( (ret=_gnutls_cert2gnutlsCert( &peer_certificate_list[i], info->raw_certificate_list[i])) < 0) { + gnutls_assert(); + CLEAR_CERTS; + gnutls_free( peer_certificate_list); + return ret; + } + } + + /* Verify certificate + */ + verify = gnutls_verify_certificate( peer_certificate_list, peer_certificate_list_size, cred->ca_list, cred->ncas, NULL, 0); + + CLEAR_CERTS; + gnutls_free( peer_certificate_list); + + if (verify < 0) { + gnutls_assert(); + return GNUTLS_CERT_INVALID; + } + + + return verify; } diff --git a/lib/auth_x509.h b/lib/auth_x509.h index 774b8e7df9..3083f2e7b0 100644 --- a/lib/auth_x509.h +++ b/lib/auth_x509.h @@ -44,14 +44,13 @@ typedef struct { #define X509PKI_CREDENTIALS X509PKI_CREDENTIALS_INT* typedef struct X509PKI_AUTH_INFO_INT { - CertificateStatus peer_certificate_status; int certificate_requested; /* if the peer requested certificate * this is non zero; */ int dh_bits; /* bits of the DH (if DHE_RSA is used) */ gnutls_datum* raw_certificate_list; /* holds the raw certificate of the - * peer. - */ + * peer. + */ int ncerts; /* holds the size of the list above */ } *X509PKI_AUTH_INFO; diff --git a/lib/gnutls_cert.h b/lib/gnutls_cert.h index 1e3013bc4d..587530347e 100644 --- a/lib/gnutls_cert.h +++ b/lib/gnutls_cert.h @@ -9,6 +9,8 @@ typedef struct gnutls_cert { MPI params[MAX_PARAMS_SIZE]; /* the size of params depends on the public * key algorithm + * RSA: [0] is modulus + * [1] is public exponent */ PKAlgorithm subject_pk_algorithm; diff --git a/lib/gnutls_ui.h b/lib/gnutls_ui.h index 7c268a1be2..0f017729b4 100644 --- a/lib/gnutls_ui.h +++ b/lib/gnutls_ui.h @@ -63,7 +63,7 @@ int gnutls_x509pki_get_certificate_request_status( GNUTLS_STATE); int gnutls_x509pki_get_peer_dn( GNUTLS_STATE, gnutls_DN*); const gnutls_datum* gnutls_x509pki_get_peer_certificate_list( GNUTLS_STATE, int* list_size); int gnutls_x509pki_get_issuer_dn( GNUTLS_STATE, gnutls_DN *); -CertificateStatus gnutls_x509pki_get_peer_certificate_status( GNUTLS_STATE); +int gnutls_x509pki_get_peer_certificate_status( GNUTLS_STATE); int gnutls_x509pki_get_peer_certificate_version( GNUTLS_STATE); time_t gnutls_x509pki_get_peer_certificate_activation_time( GNUTLS_STATE); time_t gnutls_x509pki_get_peer_certificate_expiration_time( GNUTLS_STATE); diff --git a/src/serv.c b/src/serv.c index 763da05504..6d9122d992 100644 --- a/src/serv.c +++ b/src/serv.c @@ -169,11 +169,11 @@ void print_info(GNUTLS_STATE state) printf(" - Certificate info:\n"); printf(" - Certificate version: #%d\n", gnutls_x509pki_client_get_peer_certificate_version(state)); - if (gnutls_x509pki_client_get_peer_dn( state, &dn) > 0) { + if ( gnutls_x509pki_client_get_peer_dn( state, &dn) >= 0) { PRINT_DN( dn); } - if (gnutls_x509pki_client_get_issuer_dn( state, &dn) > 0) { + if (gnutls_x509pki_client_get_issuer_dn( state, &dn) >= 0) { printf(" - Certificate Issuer's info:\n"); PRINT_DN( dn); } |