summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikos Mavrogiannopoulos <nmav@gnutls.org>2001-12-05 12:50:26 +0000
committerNikos Mavrogiannopoulos <nmav@gnutls.org>2001-12-05 12:50:26 +0000
commit091cea8dbd1e5fbd940d4c863b68d5eb5ff7cab3 (patch)
treeb4d9b106120d97bb561fb75d2ee54a6b9352a40d
parent834e429a7169d4b5f239bc2980bda801e2bbdba0 (diff)
downloadgnutls-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.c1
-rw-r--r--lib/auth_x509.c230
-rw-r--r--lib/auth_x509.h5
-rw-r--r--lib/gnutls_cert.h2
-rw-r--r--lib/gnutls_ui.h2
-rw-r--r--src/serv.c4
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
- (&params->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(&params->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(&params->rsa_modulus);
- asn1_delete_structure(spk);
- return GNUTLS_E_MPI_SCAN_FAILED;
- }
- if (params != NULL)
- if (gnutls_set_datum
- (&params->rsa_exponent, str, len) < 0) {
- _gnutls_mpi_release(mod);
- _gnutls_mpi_release(exp);
- if (params != NULL)
- gnutls_free_datum(&params->
- 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);
}