]> git.ipfire.org Git - thirdparty/gnutls.git/commitdiff
now the peer's certificate list is stored into auth info structure (instead
authorNikos Mavrogiannopoulos <nmav@gnutls.org>
Tue, 4 Dec 2001 16:03:19 +0000 (16:03 +0000)
committerNikos Mavrogiannopoulos <nmav@gnutls.org>
Tue, 4 Dec 2001 16:03:19 +0000 (16:03 +0000)
of the certificate).
several other cleanups.

23 files changed:
configure.in
lib/auth_dhe_rsa.c
lib/auth_x509.c
lib/auth_x509.h
lib/gnutls.h.in
lib/gnutls_auth.c
lib/gnutls_cert.c
lib/gnutls_cert.h
lib/gnutls_errors.c
lib/gnutls_errors_int.h
lib/gnutls_int.h
lib/gnutls_kx.c
lib/gnutls_record.c
lib/gnutls_session_pack.c
lib/gnutls_ui.c
lib/gnutls_ui.h
lib/x509_extensions.c
lib/x509_extensions.h
src/Makefile.am
src/cli.c
src/common.h [new file with mode: 0644]
src/port.h [deleted file]
src/serv.c

index 14a98c92bfaf3ba58ecc2cc0ed7a79ec889ec25e..34e7121f2f36273679c9125ea4ab8d6167aefeff 100644 (file)
@@ -261,19 +261,29 @@ AC_SUBST( DEFINE_SIZE_T)
 ])
 
 
-AC_CHECK_TYPE(time_t,,
-AC_DEFINE(NO_TIME_T),
+AC_CHECK_TYPE(time_t,
+ DEFINE_TIME_T="#include <time.h>"
+ AC_SUBST( DEFINE_TIME_T)
+ ,
+  AC_CHECK_TYPE(time_t,
+   DEFINE_TIME_T="#include <sys/time.h>"
+   AC_SUBST( DEFINE_TIME_T)
+   ,
+    DEFINE_TIME_T="typedef unsigned int time_t;"
+    AC_SUBST( DEFINE_TIME_T)
+    AC_DEFINE(NO_TIME_T),
+  [
+   #include <sys/time.h>
+  ]
+  )
+,
 [
-#ifdef HAVE_TIME_H
-# include <time.h>
-#endif
-#ifdef HAVE_SYS_TIME_H
-# include <sys/time.h>
-#endif
+ #include <time.h>
 ]
 )
 
 
+
 AC_C_BIGENDIAN
 
 AC_MSG_RESULT([***
index d6f7b8291c3ebb73ec64ad8e37189107bb6f8750..dea2635e39aed3edc53d4c34666ab1c272750e26 100644 (file)
@@ -79,7 +79,10 @@ static int gen_dhe_rsa_server_kx(GNUTLS_STATE state, opaque ** data)
        }
 
        /* find the appropriate certificate */
-       if ((ret=_gnutls_find_apr_cert( state, &apr_cert_list, &apr_cert_list_length, &apr_pkey))<0) {
+       if ((ret =
+            _gnutls_find_apr_cert(state, &apr_cert_list,
+                                  &apr_cert_list_length,
+                                  &apr_pkey)) < 0) {
                gnutls_assert();
                return ret;
        }
@@ -90,7 +93,7 @@ static int gen_dhe_rsa_server_kx(GNUTLS_STATE state, opaque ** data)
                return GNUTLS_E_MEMORY_ERROR;
        }
 
-       if ( state->gnutls_key->auth_info==NULL) {
+       if (state->gnutls_key->auth_info == NULL) {
                state->gnutls_key->auth_info =
                    gnutls_calloc(1, sizeof(X509PKI_AUTH_INFO_INT));
                if (state->gnutls_key->auth_info == NULL)
@@ -105,13 +108,14 @@ static int gen_dhe_rsa_server_kx(GNUTLS_STATE state, opaque ** data)
                state->gnutls_key->auth_info_type = GNUTLS_X509PKI;
 
        } else
-               if (gnutls_get_auth_type( state) != state->gnutls_key->auth_info_type) {
-                       gnutls_assert();
-                       return GNUTLS_E_INVALID_REQUEST;
-               }
+           if (gnutls_get_auth_type(state) !=
+               state->gnutls_key->auth_info_type) {
+               gnutls_assert();
+               return GNUTLS_E_INVALID_REQUEST;
+       }
 
        info = state->gnutls_key->auth_info;
-       
+
        X = gnutls_calc_dh_secret(&x, g, p);
        if (X == NULL) {
                _gnutls_mpi_release(&g);
@@ -160,28 +164,29 @@ static int gen_dhe_rsa_server_kx(GNUTLS_STATE state, opaque ** data)
 
        if (apr_pkey != NULL) {
                if ((ret =
-                    _gnutls_generate_sig_params(
-                       state, &apr_cert_list[0], apr_pkey, &ddata, &signature)) < 0) {
+                    _gnutls_generate_sig_params(state, &apr_cert_list[0],
+                                                apr_pkey, &ddata,
+                                                &signature)) < 0) {
                        gnutls_assert();
-                       gnutls_free( *data);
+                       gnutls_free(*data);
                        return ret;
                }
        } else {
                gnutls_assert();
-               return data_size; /* do not put a signature - ILLEGAL! */
+               return data_size;       /* do not put a signature - ILLEGAL! */
        }
 
-       *data = gnutls_realloc( *data, data_size+signature.size+2);
-       if (*data==NULL) {
-               gnutls_free_datum( &signature);
+       *data = gnutls_realloc(*data, data_size + signature.size + 2);
+       if (*data == NULL) {
+               gnutls_free_datum(&signature);
                gnutls_assert();
                return GNUTLS_E_MEMORY_ERROR;
        }
-       
-       WRITEdatum16( &(*data)[data_size], signature);
-       data_size += signature.size+2;
 
-       gnutls_free_datum( &signature);
+       WRITEdatum16(&(*data)[data_size], signature);
+       data_size += signature.size + 2;
+
+       gnutls_free_datum(&signature);
 
        return data_size;
 }
@@ -194,21 +199,21 @@ static int gen_dhe_rsa_client_kx(GNUTLS_STATE state, opaque ** data)
 
        X = gnutls_calc_dh_secret(&x, state->gnutls_key->client_g,
                                  state->gnutls_key->client_p);
-       if (X==NULL || x==NULL) {
+       if (X == NULL || x == NULL) {
                gnutls_assert();
-               _gnutls_mpi_release( &x);
-               _gnutls_mpi_release( &X);
+               _gnutls_mpi_release(&x);
+               _gnutls_mpi_release(&X);
                return GNUTLS_E_MEMORY_ERROR;
        }
-       
+
        gcry_mpi_print(GCRYMPI_FMT_USG, NULL, &n_X, X);
        (*data) = gnutls_malloc(n_X + 2);
        if (*data == NULL) {
-               _gnutls_mpi_release( &x);
-               _gnutls_mpi_release( &X);
+               _gnutls_mpi_release(&x);
+               _gnutls_mpi_release(&X);
                return GNUTLS_E_MEMORY_ERROR;
        }
-       
+
        gcry_mpi_print(GCRYMPI_FMT_USG, &(*data)[2], &n_X, X);
        _gnutls_mpi_release(&X);
 
@@ -220,7 +225,7 @@ static int gen_dhe_rsa_client_kx(GNUTLS_STATE state, opaque ** data)
                               state->gnutls_key->client_p);
 
        _gnutls_mpi_release(&x);
-       if (state->gnutls_key->KEY==NULL) {
+       if (state->gnutls_key->KEY == NULL) {
                gnutls_assert();
                return GNUTLS_E_MEMORY_ERROR;
        }
@@ -230,7 +235,7 @@ static int gen_dhe_rsa_client_kx(GNUTLS_STATE state, opaque ** data)
        _gnutls_mpi_release(&state->gnutls_key->client_p);
        _gnutls_mpi_release(&state->gnutls_key->client_g);
 
-       ret = _gnutls_generate_key( state->gnutls_key);
+       ret = _gnutls_generate_key(state->gnutls_key);
        _gnutls_mpi_release(&state->gnutls_key->KEY);
 
        if (ret < 0) {
@@ -251,6 +256,14 @@ static int proc_dhe_rsa_server_kx(GNUTLS_STATE state, opaque * data,
        int i, sigsize;
        gnutls_datum vparams, signature;
        int ret;
+       X509PKI_AUTH_INFO info = state->gnutls_key->auth_info;
+       gnutls_cert peer_cert;
+
+       if (info == NULL || info->ncerts==0) {
+               gnutls_assert();
+               /* we need this in order to get peer's certificate */
+               return GNUTLS_E_UNKNOWN_ERROR;
+       }
 
        i = 0;
        n_p = READuint16(&data[i]);
@@ -287,39 +300,51 @@ static int proc_dhe_rsa_server_kx(GNUTLS_STATE state, opaque * data,
        _n_p = n_p;
 
        if (_gnutls_mpi_scan(&state->gnutls_key->client_Y,
-                         GCRYMPI_FMT_USG, data_Y, &_n_Y) != 0) {
+                            GCRYMPI_FMT_USG, data_Y, &_n_Y) != 0) {
                gnutls_assert();
                return GNUTLS_E_MPI_SCAN_FAILED;
        }
 
        if (_gnutls_mpi_scan(&state->gnutls_key->client_g,
-                         GCRYMPI_FMT_USG, data_g, &_n_g) != 0) {
+                            GCRYMPI_FMT_USG, data_g, &_n_g) != 0) {
                gnutls_assert();
                return GNUTLS_E_MPI_SCAN_FAILED;
        }
        if (_gnutls_mpi_scan(&state->gnutls_key->client_p,
-                         GCRYMPI_FMT_USG, data_p, &_n_p) != 0) {
+                            GCRYMPI_FMT_USG, data_p, &_n_p) != 0) {
                gnutls_assert();
                return GNUTLS_E_MPI_SCAN_FAILED;
        }
 
 
        /* VERIFY SIGNATURE */
-       
+
        vparams.size = n_Y + n_p + n_g + 6;
        vparams.data = data;
 
-       if (data_size-vparams.size-2 <= 0) { /* check if the peer sent enough data */
+       if (data_size - vparams.size - 2 <= 0) {        /* check if the peer sent enough data */
                gnutls_assert();
                return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
        }
-       
-       sigsize = READuint16( &data[vparams.size]);
-       signature.data = &data[vparams.size+2];
-       signature.size = GMIN(data_size-vparams.size-2, sigsize);
 
-       ret = _gnutls_verify_sig_params( state, &state->gnutls_internals.peer_cert, &vparams, &signature);
-       if (ret<0) {
+       sigsize = READuint16(&data[vparams.size]);
+       signature.data = &data[vparams.size + 2];
+       signature.size = GMIN(data_size - vparams.size - 2, sigsize);
+
+       if ((ret =
+            _gnutls_cert2gnutlsCert( &peer_cert,
+                                    info->raw_certificate_list[0])) < 0) {
+               gnutls_assert();
+               return ret;
+       }
+
+       ret =
+           _gnutls_verify_sig_params(state,
+                                     &peer_cert,
+                                     &vparams, &signature);
+       
+       gnutls_free_cert( peer_cert);
+       if (ret < 0) {
                gnutls_assert();
                return ret;
        }
@@ -349,16 +374,16 @@ static int proc_dhe_rsa_client_kx(GNUTLS_STATE state, opaque * data,
        _n_Y = n_Y;
 
        if (_gnutls_mpi_scan(&state->gnutls_key->client_Y,
-                         GCRYMPI_FMT_USG, &data[2], &_n_Y)) {
+                            GCRYMPI_FMT_USG, &data[2], &_n_Y)) {
                gnutls_assert();
                return GNUTLS_E_MPI_SCAN_FAILED;
        }
 
        g = gnutls_get_dh_params(&p, bits);
-       if (g==NULL || p==NULL) {
+       if (g == NULL || p == NULL) {
                gnutls_assert();
-               _gnutls_mpi_release( &g);
-               _gnutls_mpi_release( &p);
+               _gnutls_mpi_release(&g);
+               _gnutls_mpi_release(&p);
                return GNUTLS_E_MEMORY_ERROR;
        }
 
@@ -368,7 +393,7 @@ static int proc_dhe_rsa_client_kx(GNUTLS_STATE state, opaque * data,
        _gnutls_mpi_release(&g);
        _gnutls_mpi_release(&p);
 
-       if (state->gnutls_key->KEY==NULL) {
+       if (state->gnutls_key->KEY == NULL) {
                return GNUTLS_E_MEMORY_ERROR;
        }
 
@@ -376,7 +401,7 @@ static int proc_dhe_rsa_client_kx(GNUTLS_STATE state, opaque * data,
        _gnutls_mpi_release(&state->gnutls_key->client_Y);
        _gnutls_mpi_release(&state->gnutls_key->dh_secret);
 
-       ret = _gnutls_generate_key( state->gnutls_key);
+       ret = _gnutls_generate_key(state->gnutls_key);
        _gnutls_mpi_release(&state->gnutls_key->KEY);
 
        if (ret < 0) {
index cf3e22c2923a0c3a59513d749f0613fc28f7bdf1..95b366b4fc0fcf387809b616f48a4fc2e0021e78 100644 (file)
 #include <x509_verify.h>
 #include <gnutls_sig.h>
 #include <ext_dnsname.h>
+#include <x509_extensions.h>
 
 /* Copies data from a internal certificate struct (gnutls_cert) to 
  * exported certificate struct (X509PKI_AUTH_INFO)
  */
-int _gnutls_copy_x509_client_auth_info( X509PKI_AUTH_INFO info, gnutls_cert* cert, CertificateStatus verify) {
+int _gnutls_copy_x509_auth_info( X509PKI_AUTH_INFO info, gnutls_cert* cert, int ncerts, CertificateStatus verify) {
  /* Copy peer's information to AUTH_INFO
   */
-int ret;
+int ret, i, j;
 
        info->peer_certificate_status = verify;
 
-       info->peer_certificate_version = cert->version;
+       if (ncerts==0) {
+               info->raw_certificate_list = NULL;
+               info->ncerts = 0;
+               return 0;
+       }
        
-       if ( cert->subjectAltDNSName[0]!=0)
-               strcpy( info->subjectAltDNSName, cert->subjectAltDNSName);
-
-       info->keyUsage = cert->keyUsage;
-
-       info->peer_certificate_expiration_time = cert->expiration_time;
-       info->peer_certificate_activation_time = cert->activation_time;
+       info->raw_certificate_list = gnutls_calloc( 1, sizeof(gnutls_datum)*ncerts);
+       if (info->raw_certificate_list==NULL) {
+               gnutls_assert();
+               return GNUTLS_E_MEMORY_ERROR;
+       }
 
-       if (cert->raw.size > 0) {
-               ret = gnutls_set_datum( &info->raw_certificate, cert->raw.data, cert->raw.size);
-               if ( ret < 0) {
-                       gnutls_assert();
-                       return ret;
+       for (i=0;i<ncerts;i++) {
+               if (cert->raw.size > 0) {
+                       ret = gnutls_set_datum( &info->raw_certificate_list[i], cert[i].raw.data, cert[i].raw.size);
+                       if ( ret < 0) {
+                               gnutls_assert();
+                               goto clear;
+                       }
                }
        }
-       
+       info->ncerts = ncerts;
+               
        return 0;
+       
+       clear:
+       
+       for (j=0;j<i;j++)
+               gnutls_free_datum( &info->raw_certificate_list[j]);
+
+       gnutls_free( info->raw_certificate_list);
+       info->raw_certificate_list = NULL;
+               
+       return ret;
 }
 
 typedef struct {
@@ -615,17 +631,6 @@ int _gnutls_proc_x509_server_certificate(GNUTLS_STATE state, opaque * data, int
                        gnutls_free(peer_certificate_list);
                        return ret;
                }
-               if (j==0) { /* Copy the first certificate in the chain - peer's certificate 
-                            * into the peer_cert. This is needed in order to access these
-                            * parameters later.
-                            */
-                       if ((ret = _gnutls_cert2gnutlsCert(&state->gnutls_internals.peer_cert, tmp)) < 0) {
-                               gnutls_assert();
-                               CLEAR_CERTS;
-                               gnutls_free(peer_certificate_list);
-                               return ret;
-                       }
-               }
                
                p += len;
                i -= len + 3;
@@ -656,7 +661,7 @@ int _gnutls_proc_x509_server_certificate(GNUTLS_STATE state, opaque * data, int
        /* keep the PK algorithm */
        state->gnutls_internals.peer_pk_algorithm = peer_certificate_list[0].subject_pk_algorithm;
 
-       if ( (ret = _gnutls_copy_x509_client_auth_info(info, &peer_certificate_list[0], verify)) < 0) {
+       if ( (ret = _gnutls_copy_x509_auth_info(info, peer_certificate_list, peer_certificate_list_size, verify)) < 0) {
                gnutls_assert();
                return ret;
        }
@@ -804,6 +809,14 @@ int size, ret;
 int dsize = data_size;
 opaque* pdata = data;
 gnutls_datum sig;
+X509PKI_AUTH_INFO info = state->gnutls_key->auth_info;
+gnutls_cert peer_cert;
+
+       if (info == NULL || info->ncerts==0) {
+               gnutls_assert();
+               /* we need this in order to get peer's certificate */
+               return GNUTLS_E_UNKNOWN_ERROR;
+       }
 
        DECR_LEN(dsize, 2);
        size = READuint16( pdata);
@@ -817,10 +830,19 @@ gnutls_datum sig;
        sig.data = pdata;
        sig.size = size;
 
-       if ( (ret=_gnutls_verify_sig_hdata( state, &state->gnutls_internals.peer_cert, &sig, data_size+HANDSHAKE_HEADER_SIZE))<0) {
+       if ((ret =
+            _gnutls_cert2gnutlsCert( &peer_cert,
+                                    info->raw_certificate_list[0])) < 0) {
+               gnutls_assert();
+               return ret;
+       }
+
+       if ( (ret=_gnutls_verify_sig_hdata( state, &peer_cert, &sig, data_size+HANDSHAKE_HEADER_SIZE))<0) {
                gnutls_assert();
+               gnutls_free_cert( peer_cert);
                return ret;
        }
+       gnutls_free_cert( peer_cert);
 
        return 0;
 }
@@ -974,7 +996,7 @@ int gnutls_x509pki_get_peer_dn(GNUTLS_STATE state, gnutls_DN * ret)
        }
 
 
-       result = asn1_get_der(c2, info->raw_certificate.data, info->raw_certificate.size);
+       result = asn1_get_der(c2, info->raw_certificate_list[0].data, info->raw_certificate_list[0].size);
        if (result != ASN_OK) {
                /* couldn't decode DER */
 #ifdef DEBUG
@@ -1031,7 +1053,7 @@ int gnutls_x509pki_get_issuer_dn(GNUTLS_STATE state, gnutls_DN * ret)
                return GNUTLS_E_ASN1_ERROR;
        }
 
-       result = asn1_get_der(c2, info->raw_certificate.data, info->raw_certificate.size);
+       result = asn1_get_der(c2, info->raw_certificate_list[0].data, info->raw_certificate_list[0].size);
        if (result != ASN_OK) {
                /* couldn't decode DER */
 #ifdef DEBUG
@@ -1054,3 +1076,224 @@ int gnutls_x509pki_get_issuer_dn(GNUTLS_STATE state, gnutls_DN * ret)
 
        return 0;
 }
+
+/**
+  * gnutls_x509pki_get_subject_dns_name - This function returns the peer's dns name, if any
+  * @state: is a gnutls state
+  * @ret: is the place where dns name will be copied to
+  * @ret_size: holds the size of ret.
+  *
+  * This function will return the peer's alternative name (the dns part of it). 
+  * This is specified in X509v3 Certificate Extensions. 
+  * GNUTLS will only return the dnsName of the Alternative name, or a negative
+  * error code.
+  * Returns GNUTLS_E_MEMORY_ERROR if ret_size is not enough to hold dns name,
+  * or the size of dns name if everything was ok.
+  *
+  * If the certificate does not have a DNS name then returns GNUTLS_E_DATA_NOT_AVAILABLE;
+  *
+  **/
+int gnutls_x509pki_get_subject_dns_name(GNUTLS_STATE state, char* ret, int *ret_size)
+{
+       X509PKI_AUTH_INFO info;
+       int result;
+       gnutls_datum dnsname;
+
+       CHECK_AUTH(GNUTLS_X509PKI, GNUTLS_E_INVALID_REQUEST);
+
+       info = _gnutls_get_auth_info(state);
+       if (info == NULL)
+               return GNUTLS_E_INVALID_REQUEST;
+
+
+       memset(ret, 0, *ret_size);
+
+       if ((result =
+            _gnutls_get_extension( &info->raw_certificate_list[0], "2 5 29 17", &dnsname)) < 0) {
+               gnutls_assert();
+               return result;
+       }
+
+       if (dnsname.size==0) {
+               return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
+       }
+       
+       if ( *ret_size > dnsname.size) {
+               *ret_size = dnsname.size;
+               strcpy( ret, dnsname.data);
+               gnutls_free_datum( &dnsname);
+       } else {
+               *ret_size = dnsname.size;
+               gnutls_free_datum( &dnsname);
+               return GNUTLS_E_MEMORY_ERROR;
+       }
+
+       return *ret_size;
+}
+
+/**
+  * gnutls_x509pki_get_peer_certificate_activation_time - This function returns the peer's certificate activation time
+  * @state: is a gnutls state
+  *
+  * This function will return the peer's certificate activation time in UNIX time 
+  * (ie seconds since 00:00:00 UTC January 1, 1970).
+  * Returns a (time_t) -1 in case of an error.
+  *
+  **/
+time_t gnutls_x509pki_get_peer_certificate_activation_time(GNUTLS_STATE
+                                                          state)
+{
+       X509PKI_AUTH_INFO info;
+       node_asn *c2;
+       int result;
+       time_t ret;
+
+       CHECK_AUTH(GNUTLS_X509PKI, -1);
+
+       info = _gnutls_get_auth_info(state);
+       if (info == NULL)
+               return -1;
+
+       if (asn1_create_structure
+           (_gnutls_get_pkix(), "PKIX1Implicit88.Certificate", &c2,
+            "certificate2")
+           != ASN_OK) {
+               gnutls_assert();
+               return -1;
+       }
+
+       result = asn1_get_der(c2, info->raw_certificate_list[0].data, info->raw_certificate_list[0].size);
+       if (result != ASN_OK) {
+               /* couldn't decode DER */
+#ifdef DEBUG
+               _gnutls_log("Decoding error %d\n", result);
+#endif
+               gnutls_assert();
+               return -1;
+       }
+
+       ret = _gnutls_get_time(c2, "certificate2", "notBefore");
+
+       asn1_delete_structure(c2);
+
+       return ret;     
+}
+
+/**
+  * gnutls_x509pki_get_peer_certificate_expiration_time - This function returns the peer's certificate expiration time
+  * @state: is a gnutls state
+  *
+  * This function will return the peer's certificate expiration time in UNIX time 
+  * (ie seconds since 00:00:00 UTC January 1, 1970).
+  * Returns a (time_t) -1 in case of an error.
+  *
+  **/
+time_t gnutls_x509pki_get_peer_certificate_expiration_time(GNUTLS_STATE
+                                                          state)
+{
+       X509PKI_AUTH_INFO info;
+       node_asn *c2;
+       int result;
+       time_t ret;
+
+       CHECK_AUTH(GNUTLS_X509PKI, -1);
+
+       info = _gnutls_get_auth_info(state);
+       if (info == NULL)
+               return -1;
+
+       if (asn1_create_structure
+           (_gnutls_get_pkix(), "PKIX1Implicit88.Certificate", &c2,
+            "certificate2")
+           != ASN_OK) {
+               gnutls_assert();
+               return -1;
+       }
+
+       result = asn1_get_der(c2, info->raw_certificate_list[0].data, info->raw_certificate_list[0].size);
+       if (result != ASN_OK) {
+               /* couldn't decode DER */
+#ifdef DEBUG
+               _gnutls_log("Decoding error %d\n", result);
+#endif
+               gnutls_assert();
+               return -1;
+       }
+
+       ret = _gnutls_get_time(c2, "certificate2", "notAfter");
+
+       asn1_delete_structure(c2);
+
+       return ret;     
+}
+
+/**
+  * gnutls_x509pki_get_peer_certificate_version - This function returns the peer's certificate version
+  * @state: is a gnutls state
+  *
+  * This function will return the peer's certificate version (1, 2, 3). This is obtained by the X509 Certificate
+  * Version field. If the certificate is invalid then version will be zero.
+  * Returns a negative value in case of an error.
+  *
+  **/
+int gnutls_x509pki_get_peer_certificate_version(GNUTLS_STATE state)
+{
+       X509PKI_AUTH_INFO info;
+       node_asn *c2;
+       int result;
+
+       CHECK_AUTH(GNUTLS_X509PKI, GNUTLS_E_INVALID_REQUEST);
+
+       info = _gnutls_get_auth_info(state);
+       if (info == NULL)
+               return GNUTLS_E_INVALID_REQUEST;
+
+       if (asn1_create_structure
+           (_gnutls_get_pkix(), "PKIX1Implicit88.Certificate", &c2,
+            "certificate2")
+           != ASN_OK) {
+               gnutls_assert();
+               return GNUTLS_E_ASN1_ERROR;
+       }
+
+       result = asn1_get_der(c2, info->raw_certificate_list[0].data, info->raw_certificate_list[0].size);
+       if (result != ASN_OK) {
+               /* couldn't decode DER */
+#ifdef DEBUG
+               _gnutls_log("Decoding error %d\n", result);
+#endif
+               gnutls_assert();
+               return GNUTLS_E_ASN1_PARSING_ERROR;
+       }
+
+       result = _gnutls_get_version(c2, "certificate2");
+
+       asn1_delete_structure(c2);
+
+       return result;
+
+}
+
+/**
+  * 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.
+  *
+  **/
+CertificateStatus gnutls_x509pki_get_peer_certificate_status(GNUTLS_STATE
+                                                            state)
+{
+       X509PKI_AUTH_INFO info;
+
+       CHECK_AUTH(GNUTLS_X509PKI, GNUTLS_CERT_NONE);
+
+       info = _gnutls_get_auth_info(state);
+       if (info == NULL)
+               return GNUTLS_CERT_NONE;
+
+       return info->peer_certificate_status;
+}
index 27385a5705270eb1897a2974283793f748dfd954..774b8e7df91e5efbf2fb7390a9a2d1d75aa26663 100644 (file)
@@ -45,18 +45,14 @@ typedef struct {
 
 typedef struct X509PKI_AUTH_INFO_INT {
        CertificateStatus peer_certificate_status;
-       int               peer_certificate_version;
-       time_t            peer_certificate_activation_time;
-       time_t            peer_certificate_expiration_time;
-       char              subjectAltDNSName[X509_CN_SIZE];
-       unsigned char     keyUsage;
        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; /* holds the raw certificate of the
+       gnutls_datum*     raw_certificate_list; /* holds the raw certificate of the
                                            * peer.
                                            */
+       int               ncerts; /* holds the size of the list above */
 } *X509PKI_AUTH_INFO;
 
 typedef struct X509PKI_AUTH_INFO_INT X509PKI_AUTH_INFO_INT;
index 835ac16f5e5b67f8d5891cb1dafa672b0c64a28a..f055616e0302f271526268b70248d6bd0b9d065b 100644 (file)
@@ -28,6 +28,7 @@ extern "C" {
 #define LIBGNUTLS_VERSION "@VERSION@"
 
 @DEFINE_SIZE_T@
+@DEFINE_TIME_T@
 
 #define GNUTLS_AES GNUTLS_RIJNDAEL
 
index 8af9a04696720f2e9dfa616e000f437ab7647ba3..a0267b3118bf22db0d444d390aa7def199657771 100644 (file)
@@ -205,13 +205,21 @@ void _gnutls_free_auth_info( GNUTLS_STATE state) {
                
                break;
        case GNUTLS_X509PKI: {
+               int i;
                X509PKI_AUTH_INFO info =
                            _gnutls_get_auth_info(state);
 
-               if (info==NULL) break;
-               gnutls_free( info->raw_certificate.data);
-
+                       if (info==NULL) break;
+                       for (i=0;i<info->ncerts;i++) {
+                               gnutls_free( info->raw_certificate_list[0].data);
+                       }
+       
+                       gnutls_free( info->raw_certificate_list);
+                       info->raw_certificate_list = NULL;
+                       info->ncerts = 0;
                }
+
+
                break;
        default:
                return;
index 789b54b7f8197722c705aedb40e5b46969300e73..c91b5a6b159ecfd7e74bcbb4df089af8bf8c55bd 100644 (file)
@@ -751,7 +751,7 @@ int _gnutls_get_name_type(node_asn * rasn, char *root, gnutls_DN * dn)
 
 
 #define MAX_TIME 1024
-static time_t _gnutls_get_time(node_asn * c2, char *root, char *when)
+time_t _gnutls_get_time(node_asn * c2, char *root, char *when)
 {
        opaque ttime[MAX_TIME];
        char name[1024];
@@ -798,7 +798,7 @@ static time_t _gnutls_get_time(node_asn * c2, char *root, char *when)
        return ctime;
 }
 
-static int _gnutls_get_version(node_asn * c2, char *root)
+int _gnutls_get_version(node_asn * c2, char *root)
 {
        opaque gversion[5];
        char name[1024];
@@ -831,6 +831,8 @@ int _gnutls_cert2gnutlsCert(gnutls_cert * gCert, gnutls_datum derCert)
        opaque str[MAX_X509_CERT_SIZE];
        int len = sizeof(str);
 
+       memset( gCert, 0, sizeof(gnutls_cert));
+       
        gCert->valid = 1;
 
        if (asn1_create_structure
@@ -911,7 +913,7 @@ int _gnutls_cert2gnutlsCert(gnutls_cert * gCert, gnutls_datum derCert)
                gCert->subject_pk_algorithm = GNUTLS_PK_UNKNOWN;
 
        }
-
+       
        len = sizeof(gCert->signature);
        result =
            asn1_read_value
@@ -926,8 +928,12 @@ int _gnutls_cert2gnutlsCert(gnutls_cert * gCert, gnutls_datum derCert)
        gCert->signature_size = len;
 
 
-       memset(&gCert->subjectAltDNSName, 0,
-              sizeof(gCert->subjectAltDNSName));
+       gCert->expiration_time =
+           _gnutls_get_time(c2, "certificate2", "notAfter");
+       gCert->activation_time =
+           _gnutls_get_time(c2, "certificate2", "notBefore");
+       gCert->version = _gnutls_get_version(c2, "certificate2");
+
        if ((result =
             _gnutls_get_ext_type(c2,
                                  "certificate2.tbsCertificate.extensions",
@@ -937,13 +943,6 @@ int _gnutls_cert2gnutlsCert(gnutls_cert * gCert, gnutls_datum derCert)
                return result;
        }
 
-       gCert->expiration_time =
-           _gnutls_get_time(c2, "certificate2", "notAfter");
-       gCert->activation_time =
-           _gnutls_get_time(c2, "certificate2", "notBefore");
-
-       gCert->version = _gnutls_get_version(c2, "certificate2");
-
        asn1_delete_structure(c2);
 
        if (gnutls_set_datum(&gCert->raw, derCert.data, derCert.size) < 0) {
index 2b9365e02bb1baaf4e77d1d50e931ba287990784..1e3013bc4d90a567f1f602e0a8b816c30be18587 100644 (file)
@@ -7,14 +7,11 @@
 
 #define MAX_PARAMS_SIZE 2 /* ok for RSA */
 typedef struct gnutls_cert {
-       MPI params[MAX_PARAMS_SIZE];            /* the size of params depends on the public 
+       MPI params[MAX_PARAMS_SIZE];    /* the size of params depends on the public 
                                 * key algorithm 
                                 */
        PKAlgorithm subject_pk_algorithm;
 
-       opaque     subjectAltDNSName[X509_CN_SIZE]; 
-       int        subjectAltDNSName_size;
-       
        opaque     signature[1024];
        int        signature_size;
        
@@ -58,5 +55,7 @@ void _gnutls_int2str(int k, char* data);
 int _gnutls_get_name_type( node_asn *rasn, char *root, gnutls_DN * dn);
 void gnutls_free_cert(gnutls_cert cert);
 int _gnutls_check_x509_key_usage( const gnutls_cert * cert, KXAlgorithm alg);
+int _gnutls_get_version(node_asn * c2, char *root);
+time_t _gnutls_get_time(node_asn * c2, char *root, char *when);
 
 #endif
index f8c80e266b480d9b28fa2011276b08241d6ef88c..2da20177c90c65491ca322fe6be35c2059e1fec8 100644 (file)
@@ -73,6 +73,7 @@ static gnutls_error_entry error_algorithms[] = {
        GNUTLS_ERROR_ENTRY( GNUTLS_E_EXPIRED, 1),
        GNUTLS_ERROR_ENTRY( GNUTLS_E_HASH_FAILED, 1),
        GNUTLS_ERROR_ENTRY( GNUTLS_E_PARSING_ERROR, 1),
+       GNUTLS_ERROR_ENTRY( GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE, 0),
        GNUTLS_ERROR_ENTRY( GNUTLS_E_PULL_ERROR, 1),
        GNUTLS_ERROR_ENTRY( GNUTLS_E_PUSH_ERROR, 1),
        GNUTLS_ERROR_ENTRY( GNUTLS_E_NO_CERTIFICATE_FOUND, 1),
index 4426100b5c4d771d978074334c2235b0a32ad0a5..c1962a28d0ca66ef1e3e1fecbfe751b798261c47 100644 (file)
@@ -48,7 +48,6 @@
 #define GNUTLS_E_PK_SIGNATURE_FAILED -46
 #define GNUTLS_E_X509_UNSUPPORTED_CRITICAL_EXTENSION -47
 #define GNUTLS_E_X509_KEY_USAGE_VIOLATION -48
-#define GNUTLS_E_PKCS1_WRONG_PAD -48
 #define GNUTLS_E_NO_CERTIFICATE_FOUND -49
 #define GNUTLS_E_INVALID_PARAMETERS -50
 #define GNUTLS_E_INVALID_REQUEST -51
@@ -56,5 +55,7 @@
 #define GNUTLS_E_PUSH_ERROR -53
 #define GNUTLS_E_PULL_ERROR -54
 #define GNUTLS_E_ILLEGAL_PARAMETER -55
+#define GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE -56
+#define GNUTLS_E_PKCS1_WRONG_PAD -57
 
 #define GNUTLS_E_UNIMPLEMENTED_FEATURE -250
index 1aacd4058f8d9ee03b25b56237da65d0a65434f4..60f2e559d7e6bc0d80de93665fba7b66783bf317 100644 (file)
@@ -452,7 +452,6 @@ typedef struct {
         * client certificates were found.
         */
        x509_cert_callback_func*        x509_client_cert_callback;
-       gnutls_cert                     peer_cert;
        int                             max_handshake_data_buffer_size;
 
        /* PUSH & PULL functions.
index 1b41ad5527e6419aeb3288a5ddb62fb6caf34629..aad059fcb8a5dfbd727cb4723a52a594051c0b3d 100644 (file)
@@ -542,10 +542,6 @@ int _gnutls_recv_client_certificate( GNUTLS_STATE state)
                        }
                        /* certificate was required */
                        if (optional==MANDATORY_PACKET) {
-#ifdef DEBUG
-# warning FIX THIS ALERT
-                               gnutls_send_alert(  state, GNUTLS_FATAL, GNUTLS_BAD_CERTIFICATE);
-#endif
                                gnutls_assert();
                        }
                        return ret;
@@ -634,10 +630,6 @@ int _gnutls_recv_client_certificate_verify_message( GNUTLS_STATE state)
 
                if (ret==0 && datasize == 0 && state->gnutls_internals.send_cert_req == GNUTLS_CERT_REQUIRE) {
                        /* certificate was required */
-#ifdef DEBUG
-# warning FIX THIS ALERT
-                       gnutls_send_alert( state, GNUTLS_FATAL, GNUTLS_BAD_CERTIFICATE);
-#endif
                        gnutls_assert();
                        return GNUTLS_E_NO_CERTIFICATE_FOUND;
                } 
index 573fe7967759e7cf3999be444d57427688cca077..595b408a979c7f340c96c86499d3f114f1848167 100644 (file)
@@ -217,7 +217,6 @@ int gnutls_deinit(GNUTLS_STATE state)
        _gnutls_free(state->gnutls_internals.CompressionMethodPriority.algorithm_priority);
 
        _gnutls_free(state->gnutls_internals.db_name);
-       gnutls_free_cert( state->gnutls_internals.peer_cert);
 
        memset( state, 0, sizeof(struct GNUTLS_STATE_INT));
        gnutls_free(state);
@@ -433,6 +432,7 @@ int ret = GNUTLS_E_UNIMPLEMENTED_FEATURE;
                         ret = gnutls_send_alert( state, GNUTLS_FATAL, GNUTLS_ILLEGAL_PARAMETER);
                         break;
                case GNUTLS_E_ASN1_PARSING_ERROR:
+               case GNUTLS_E_NO_CERTIFICATE_FOUND:
                         ret = gnutls_send_alert( state, GNUTLS_FATAL, GNUTLS_BAD_CERTIFICATE);
                         break;
                case GNUTLS_E_UNKNOWN_CIPHER_SUITE:
index 38396d14de3e39a153c1df3979a18a8e428d68cd..18116d21c2a0ad178c387de6fabc8845a974d25b 100644 (file)
 #include <gnutls_num.h>
 
 #define PACK_HEADER_SIZE 1
-int _gnutls_pack_x509pki_auth_info(X509PKI_AUTH_INFO info,
+int _gnutls_pack_x509pki_auth_info( X509PKI_AUTH_INFO info,
                                   gnutls_datum * packed_session);
 int _gnutls_unpack_x509pki_auth_info(X509PKI_AUTH_INFO info,
                                     const gnutls_datum * packed_session);
-static int _gnutls_pack_x509pki_auth_info_size();
+static int _gnutls_pack_x509pki_auth_info_size( X509PKI_AUTH_INFO info);
 
 
 /* Since auth_info structures contain malloced data, this function
@@ -49,14 +49,19 @@ int _gnutls_session_pack(GNUTLS_STATE state, gnutls_datum * packed_session)
                return GNUTLS_E_UNIMPLEMENTED_FEATURE;
        }
 
+
        switch (gnutls_get_auth_type(state)) {
        case GNUTLS_SRP:{
                        SRP_SERVER_AUTH_INFO info =
                            _gnutls_get_auth_info(state);
-                       if (info == NULL || info->username[0] == 0)
+
+                       
+                       if (info == NULL && state->gnutls_key->auth_info_size!=0) {
+                               gnutls_assert();
                                return GNUTLS_E_INVALID_PARAMETERS;
+                       }
 
-                       pack_size = sizeof(SRP_SERVER_AUTH_INFO_INT);
+                       pack_size = state->gnutls_key->auth_info_size;
                        packed_session->size =
                            PACK_HEADER_SIZE + pack_size + sizeof(uint32);
 
@@ -64,19 +69,22 @@ int _gnutls_session_pack(GNUTLS_STATE state, gnutls_datum * packed_session)
                        WRITEuint32(pack_size,
                                    &packed_session->
                                    data[PACK_HEADER_SIZE]);
-                       memcpy(&packed_session->
-                              data[PACK_HEADER_SIZE + sizeof(uint32)],
-                              info, sizeof(SRP_SERVER_AUTH_INFO_INT));
+                       
+                       if (state->gnutls_key->auth_info_size > 0)
+                               memcpy(&packed_session->
+                                      data[PACK_HEADER_SIZE + sizeof(uint32)],
+                                      info, state->gnutls_key->auth_info_size);
 
                }
+
                break;
        case GNUTLS_ANON:{
                        ANON_CLIENT_AUTH_INFO info =
                            _gnutls_get_auth_info(state);
-                       if (info == NULL)
+                       if (info == NULL && state->gnutls_key->auth_info_size!=0)
                                return GNUTLS_E_INVALID_PARAMETERS;
 
-                       pack_size = sizeof(ANON_CLIENT_AUTH_INFO_INT);
+                       pack_size = state->gnutls_key->auth_info_size;
                        packed_session->size =
                            PACK_HEADER_SIZE + pack_size + sizeof(uint32);
 
@@ -84,9 +92,11 @@ int _gnutls_session_pack(GNUTLS_STATE state, gnutls_datum * packed_session)
                        WRITEuint32(pack_size,
                                    &packed_session->
                                    data[PACK_HEADER_SIZE]);
-                       memcpy(&packed_session->
-                              data[PACK_HEADER_SIZE + sizeof(uint32)],
-                              info, sizeof(ANON_CLIENT_AUTH_INFO_INT));
+                       
+                       if (state->gnutls_key->auth_info_size > 0)
+                               memcpy(&packed_session->
+                                      data[PACK_HEADER_SIZE + sizeof(uint32)],
+                                      info, state->gnutls_key->auth_info_size);
 
                }
                break;
@@ -119,6 +129,7 @@ int _gnutls_session_pack(GNUTLS_STATE state, gnutls_datum * packed_session)
               data[packed_session->size - sizeof(SecurityParameters)],
               &state->security_parameters, sizeof(SecurityParameters));
 
+
        return 0;
 }
 
@@ -134,8 +145,17 @@ int _gnutls_session_size( GNUTLS_STATE state)
        case GNUTLS_SRP:
        case GNUTLS_ANON:
                pack_size += state->gnutls_key->auth_info_size;
-       case GNUTLS_X509PKI:
-               pack_size += _gnutls_pack_x509pki_auth_info_size( state);
+               break;
+       case GNUTLS_X509PKI: {
+               X509PKI_AUTH_INFO info =
+                   _gnutls_get_auth_info(state);
+       
+                       if (info == NULL)
+                               return GNUTLS_E_INVALID_PARAMETERS;
+       
+                       pack_size += _gnutls_pack_x509pki_auth_info_size( info);
+               }
+               break;
        }
 
        /* Auth_info structures copied. Now copy SecurityParameters. 
@@ -162,14 +182,13 @@ int _gnutls_session_unpack(GNUTLS_STATE state,
                _gnutls_free_auth_info( state);
        }
        
-       switch (packed_session->data[0]) {
+       switch ( packed_session->data[0]) {
        case GNUTLS_SRP:{
 
                        pack_size =
                            READuint32(&packed_session->
                                       data[PACK_HEADER_SIZE]);
                        
-
                        if (pack_size == 0) break;
                        if (pack_size != sizeof(SRP_SERVER_AUTH_INFO_INT)) {
                                gnutls_assert();
@@ -180,8 +199,10 @@ int _gnutls_session_unpack(GNUTLS_STATE state,
                            gnutls_calloc(1,
                                          sizeof
                                          (SRP_SERVER_AUTH_INFO_INT));
-                       if (state->gnutls_key->auth_info == NULL)
+                       if (state->gnutls_key->auth_info == NULL) {
+                               gnutls_assert();
                                return GNUTLS_E_MEMORY_ERROR;
+                       }
                        state->gnutls_key->auth_info_size =
                            sizeof(SRP_SERVER_AUTH_INFO_INT);
 
@@ -208,8 +229,10 @@ int _gnutls_session_unpack(GNUTLS_STATE state,
                            gnutls_calloc(1,
                                          sizeof
                                          (ANON_CLIENT_AUTH_INFO_INT));
-                       if (state->gnutls_key->auth_info == NULL)
+                       if (state->gnutls_key->auth_info == NULL) {
+                               gnutls_assert();
                                return GNUTLS_E_MEMORY_ERROR;
+                       }
                        state->gnutls_key->auth_info_size =
                            sizeof(ANON_CLIENT_AUTH_INFO_INT);
 
@@ -233,8 +256,10 @@ int _gnutls_session_unpack(GNUTLS_STATE state,
                        state->gnutls_key->auth_info =
                            gnutls_calloc(1,
                                          sizeof(X509PKI_AUTH_INFO_INT));
-                       if (state->gnutls_key->auth_info == NULL)
+                       if (state->gnutls_key->auth_info == NULL) {
+                               gnutls_assert();
                                return GNUTLS_E_MEMORY_ERROR;
+                       }
                        state->gnutls_key->auth_info_size =
                            sizeof(X509PKI_AUTH_INFO_INT);
 
@@ -248,11 +273,10 @@ int _gnutls_session_unpack(GNUTLS_STATE state,
                                return ret;
                        }
 
-                       pack_size += ret;
-
                }
                break;
        default:
+               gnutls_assert();
                return GNUTLS_E_UNIMPLEMENTED_FEATURE;
 
        }
@@ -280,7 +304,7 @@ int _gnutls_session_unpack(GNUTLS_STATE state,
                memcpy( &state->gnutls_internals.resumed_security_parameters, &sp, sizeof(SecurityParameters));
        } else {
                _gnutls_free_auth_info( state);
-
+               gnutls_assert();
                return GNUTLS_E_EXPIRED;
        }
 
@@ -288,57 +312,87 @@ int _gnutls_session_unpack(GNUTLS_STATE state,
        return 0;
 }
 
-int _gnutls_pack_x509pki_auth_info(X509PKI_AUTH_INFO info,
+int _gnutls_pack_x509pki_auth_info( X509PKI_AUTH_INFO info,
                                   gnutls_datum * packed_session)
 {
-       uint32 pack_size = sizeof(X509PKI_AUTH_INFO_INT) + info->raw_certificate.size;
-       packed_session->size =
-           pack_size + PACK_HEADER_SIZE + sizeof(uint32);
+       uint32 pos, i;
+       packed_session->size = _gnutls_pack_x509pki_auth_info_size( info);
 
        packed_session->data[0] = GNUTLS_X509PKI;
-       WRITEuint32(pack_size, &packed_session->data[PACK_HEADER_SIZE]);
+       WRITEuint32( packed_session->size-PACK_HEADER_SIZE-sizeof(uint32), &packed_session->data[PACK_HEADER_SIZE]);
+
+
        memcpy(&packed_session->data[PACK_HEADER_SIZE + sizeof(uint32)],
               info, sizeof(X509PKI_AUTH_INFO_INT));
        
-       if (info->raw_certificate.size > 0)
-               memcpy(&packed_session->data[PACK_HEADER_SIZE + sizeof(uint32) +
-                       sizeof(X509PKI_AUTH_INFO_INT)], info->raw_certificate.data, 
-                       info->raw_certificate.size);
+       pos = PACK_HEADER_SIZE + sizeof(uint32) + sizeof(X509PKI_AUTH_INFO_INT);
+
+       for (i=0;i<info->ncerts;i++) {
+               WRITEuint32( info->raw_certificate_list[i].size, &packed_session->data[pos]);
+               pos += sizeof(uint32);
+               
+               memcpy(&packed_session->data[pos], info->raw_certificate_list[i].data, info->raw_certificate_list[i].size);
+               pos += info->raw_certificate_list[i].size;
+       }
 
+       
        return 0;
 }
 
-static int _gnutls_pack_x509pki_auth_info_size( GNUTLS_STATE state)
+static int _gnutls_pack_x509pki_auth_info_size( X509PKI_AUTH_INFO info)
 {
-       X509PKI_AUTH_INFO info =
-           _gnutls_get_auth_info(state);
        uint32 pack_size = sizeof(X509PKI_AUTH_INFO_INT);
+       int i;
 
        if (info == NULL)
                return 0;
-           
-       return pack_size + PACK_HEADER_SIZE + sizeof(uint32) + info->raw_certificate.size;
+
+       for (i=0;i<info->ncerts;i++) {
+               pack_size += sizeof(uint32) + info->raw_certificate_list[i].size;
+       }
+
+       return pack_size + PACK_HEADER_SIZE + sizeof(uint32);
 }
 
 
 int _gnutls_unpack_x509pki_auth_info(X509PKI_AUTH_INFO info,
                                     const gnutls_datum * packed_session)
 {
-int ret;
+int ret, i, pos, j;
+uint32 size;
 
        memcpy(info,
               &packed_session->data[PACK_HEADER_SIZE + sizeof(uint32)],
               sizeof(X509PKI_AUTH_INFO_INT));
 
-       if (info->raw_certificate.size > 0) {
-               ret = gnutls_set_datum( &info->raw_certificate, 
-                &packed_session->data[PACK_HEADER_SIZE + sizeof(uint32) + sizeof(X509PKI_AUTH_INFO_INT)],
-                info->raw_certificate.size);
-
-               if (ret < 0) {
+       pos = PACK_HEADER_SIZE + sizeof(uint32) + sizeof(X509PKI_AUTH_INFO_INT);
+       if (info->ncerts > 0) {
+               info->raw_certificate_list = gnutls_calloc( 1, info->ncerts * sizeof( gnutls_datum));
+               if (info->raw_certificate_list == NULL) {
                        gnutls_assert();
-                       return ret;
+                       return GNUTLS_E_MEMORY_ERROR;
+               }
+               
+               for (i=0;i<info->ncerts;i++) {
+                       size = READuint32( &packed_session->data[ pos]);
+                       pos += sizeof(uint32);
+
+                       ret = gnutls_set_datum( &info->raw_certificate_list[i], &packed_session->data[ pos], size);
+                       pos += size;
+                               
+                       if (ret < 0) {
+                               gnutls_assert();
+                               goto clear;
+                       }
                }
        }
        return 0;
+       
+       clear:
+               for (j=0;j<i;j++)
+                       gnutls_free_datum( &info->raw_certificate_list[j]);
+
+               gnutls_free( info->raw_certificate_list);
+               return GNUTLS_E_MEMORY_ERROR;
+               
 }
index fb8fce623ece388199216db29abaf7e67668eead..d1e7f4afa2c63c5f9cf6c61544fef665fec0aadc 100644 (file)
@@ -100,38 +100,16 @@ int gnutls_anon_client_get_dh_bits(GNUTLS_STATE state)
 /* X509PKI */
 
 /**
-  * gnutls_x509pki_get_peer_certificate_status - This function returns the peer's certificate status
+  * gnutls_x509pki_get_peer_certificate_list - This function returns the peer's raw (DER encoded) certificate
   * @state: is a gnutls state
+  * @list_size: is the length of the certificate list
   *
-  * 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.
-  *
-  **/
-CertificateStatus gnutls_x509pki_get_peer_certificate_status(GNUTLS_STATE
-                                                            state)
-{
-       X509PKI_AUTH_INFO info;
-
-       CHECK_AUTH(GNUTLS_X509PKI, GNUTLS_CERT_NONE);
-
-       info = _gnutls_get_auth_info(state);
-       if (info == NULL)
-               return GNUTLS_CERT_NONE;
-       return info->peer_certificate_status;
-}
-
-/**
-  * gnutls_x509pki_get_peer_certificate - This function returns the peer's raw (DER encoded) certificate
-  * @state: is a gnutls state
-  *
-  * This function will return the peer's raw certificate as sent by the peer.
-  * This certificate is DER encoded.
+  * This function will return the peer's raw certificate list as sent by the peer.
+  * These certificates are DER encoded. 
   * Returns NULL in case of an error, or if no certificate was sent.
   *
   **/
-const gnutls_datum *gnutls_x509pki_get_peer_certificate(GNUTLS_STATE state)
+const gnutls_datum *gnutls_x509pki_get_peer_certificate_list(GNUTLS_STATE state, int *list_size)
 {
        X509PKI_AUTH_INFO info;
 
@@ -140,30 +118,12 @@ const gnutls_datum *gnutls_x509pki_get_peer_certificate(GNUTLS_STATE state)
        info = _gnutls_get_auth_info(state);
        if (info == NULL)
                return NULL;
-       return &info->raw_certificate;
-}
-
-/**
-  * gnutls_x509pki_get_peer_certificate_version - This function returns the peer's certificate version
-  * @state: is a gnutls state
-  *
-  * This function will return the peer's certificate version (1, 2, 3). This is obtained by the X509 Certificate
-  * Version field. If the certificate is invalid then version will be zero.
-  * Returns a negative value in case of an error.
-  *
-  **/
-int gnutls_x509pki_get_peer_certificate_version(GNUTLS_STATE state)
-{
-       X509PKI_AUTH_INFO info;
-
-       CHECK_AUTH(GNUTLS_X509PKI, GNUTLS_E_INVALID_REQUEST);
 
-       info = _gnutls_get_auth_info(state);
-       if (info == NULL)
-               return GNUTLS_E_UNKNOWN_ERROR;
-       return info->peer_certificate_version;
+       *list_size = info->ncerts;
+       return info->raw_certificate_list;
 }
 
+
 /**
   * gnutls_x509pki_get_dh_bits - This function returns the number of bits used in a DHE handshake
   * @state: is a gnutls state
@@ -186,71 +146,7 @@ int gnutls_x509pki_get_dh_bits(GNUTLS_STATE state)
        return info->dh_bits;
 }
 
-/**
-  * gnutls_x509pki_get_peer_certificate_activation_time - This function returns the peer's certificate activation time
-  * @state: is a gnutls state
-  *
-  * This function will return the peer's certificate activation time in UNIX time 
-  * (ie seconds since 00:00:00 UTC January 1, 1970).
-  * Returns a (time_t) -1 in case of an error.
-  *
-  **/
-time_t gnutls_x509pki_get_peer_certificate_activation_time(GNUTLS_STATE
-                                                          state)
-{
-       X509PKI_AUTH_INFO info;
-
-       CHECK_AUTH(GNUTLS_X509PKI, -1);
 
-       info = _gnutls_get_auth_info(state);
-       if (info == NULL)
-               return -1;
-       return info->peer_certificate_activation_time;
-}
-
-/**
-  * gnutls_x509pki_get_peer_certificate_expiration_time - This function returns the peer's certificate expiration time
-  * @state: is a gnutls state
-  *
-  * This function will return the peer's certificate expiration time in UNIX time 
-  * (ie seconds since 00:00:00 UTC January 1, 1970).
-  * Returns a (time_t) -1 in case of an error.
-  *
-  **/
-time_t gnutls_x509pki_get_peer_certificate_expiration_time(GNUTLS_STATE
-                                                          state)
-{
-       X509PKI_AUTH_INFO info;
-
-       CHECK_AUTH(GNUTLS_X509PKI, -1);
-
-       info = _gnutls_get_auth_info(state);
-       if (info == NULL)
-               return -1;
-       return info->peer_certificate_expiration_time;
-}
-
-
-/**
-  * gnutls_x509pki_get_key_usage - This function returns the peer's certificate key usage
-  * @state: is a gnutls state
-  *
-  * This function will return the peer's certificate key usage. This is specified in X509v3 Certificate
-  * Extensions and is an 8bit string.
-  * Returns zero in case of an error.
-  *
-  **/
-unsigned char gnutls_x509pki_get_key_usage(GNUTLS_STATE state)
-{
-       X509PKI_AUTH_INFO info;
-
-       CHECK_AUTH(GNUTLS_X509PKI, 0);
-
-       info = _gnutls_get_auth_info(state);
-       if (info == NULL)
-               return 0;
-       return info->keyUsage;
-}
 
 /**
   * gnutls_x509pki_get_certificate_request_status - This function returns the certificate request status
@@ -274,25 +170,3 @@ int gnutls_x509pki_get_certificate_request_status(GNUTLS_STATE state)
 }
 
 
-/**
-  * gnutls_x509pki_get_subject_dns_name - This function returns the peer's dns name, if any
-  * @state: is a gnutls state
-  *
-  * This function will return the peer's alternative name (the dns part of it). 
-  * This is specified in X509v3 Certificate Extensions. 
-  * GNUTLS will only return the dnsName of the Alternative name, or a null 
-  * string.
-  * Returns NULL in case of an error.
-  *
-  **/
-const char *gnutls_x509pki_get_subject_dns_name(GNUTLS_STATE state)
-{
-       X509PKI_AUTH_INFO info;
-
-       CHECK_AUTH(GNUTLS_X509PKI, NULL);
-
-       info = _gnutls_get_auth_info(state);
-       if (info == NULL)
-               return NULL;
-       return info->subjectAltDNSName;
-}
index ce7b6f9651d882d903475d2fa7ab5cd4d0d6d92b..7c268a1be250076298ecb00430aa9a1970c07422 100644 (file)
@@ -61,14 +61,14 @@ int gnutls_x509pki_set_cert_request( GNUTLS_STATE, CertificateRequest);
 
 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( GNUTLS_STATE);
+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_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);
 unsigned char gnutls_x509pki_get_key_usage( GNUTLS_STATE);
-const char* gnutls_x509pki_get_subject_dns_name( GNUTLS_STATE);
+int gnutls_x509pki_get_subject_dns_name( GNUTLS_STATE, char*, int*);
 int gnutls_x509pki_get_dh_bits( GNUTLS_STATE);
 
 #define gnutls_x509pki_server_get_dh_bits gnutls_x509pki_get_dh_bits
index 702410e4b8377d7b064b3756adfa6d489f21f893..0e6f7c5bb684be83fbcc2aaf92ea85b01d2f1d1c 100644 (file)
 #include <gnutls_cert.h>
 #include <gnutls_errors.h>
 #include <gnutls_global.h>
+#include "debug.h"
 
-/* Here we only read subjectAltDNSName, in case of
- * dnsName. Otherwise we read nothing.
- */
-static int _extract_subjectAltDNSName( char* subjectAltDNSName, opaque* extnValue, int extnValueLen) {
-node_asn* ext;
-char counter[MAX_INT_DIGITS];
-char name[1024];
-char str[1024];
-int len, k, result;
-
-       subjectAltDNSName[0] = 0;
-       
-       if (asn1_create_structure
-           ( _gnutls_get_pkix(), "PKIX1Implicit88.GeneralNames", &ext, 
-               "san") != ASN_OK) {
-               gnutls_assert();
-               return GNUTLS_E_ASN1_PARSING_ERROR;
-       }
-
-       result = asn1_get_der ( ext, extnValue, extnValueLen);
-
-       if (result != ASN_OK) {
-               gnutls_assert();
-               asn1_delete_structure(ext);
-               return GNUTLS_E_ASN1_PARSING_ERROR;
-       }
-
-       k = 1;
-       for (;;) {
-               strcpy(name, "san.?");
-               _gnutls_int2str(k, counter);
-               strcat(name, counter);
-
-               len = sizeof(str) - 1;
-               result = asn1_read_value(ext, name, str, &len);
-               if (result == ASN_ELEMENT_NOT_FOUND) break;
-               
-               if (strcmp( str, "dNSName") == 0) {
-                       strcat( name, "dNSName");
-                       len = sizeof( str) -1;
-                       result = asn1_read_value(ext, name, str, &len);
-
-                       if (result != ASN_OK) {
-                               gnutls_assert();
-                               asn1_delete_structure(ext);
-                               return GNUTLS_E_ASN1_PARSING_ERROR;
-                       }
-                       
-                       strncpy( subjectAltDNSName, str, GMIN( len, X509_CN_SIZE-1));
-                       subjectAltDNSName[X509_CN_SIZE-1] = 0;
-                       
-                       break;
-               }
-               k++;
-       }
-
-       asn1_delete_structure(ext);
-       return 0;
-}
 
 /* Here we only extract the KeyUsage field
  */
-static int _extract_keyUsage( char* keyUsage, opaque* extnValue, int extnValueLen) {
-node_asn* ext;
-char str[128];
-int len, result;
+static int _extract_keyUsage(char *keyUsage, opaque * extnValue,
+                            int extnValueLen)
+{
+       node_asn *ext;
+       char str[10];
+       int len, result;
 
+       keyUsage[0] = 0;
        
        if (asn1_create_structure
-           ( _gnutls_get_pkix(), "PKIX1Implicit88.KeyUsage", &ext, 
-               "ku") != ASN_OK) {
+           (_gnutls_get_pkix(), "PKIX1Implicit88.KeyUsage", &ext,
+            "ku") != ASN_OK) {
                gnutls_assert();
                return GNUTLS_E_ASN1_PARSING_ERROR;
        }
 
-       result = asn1_get_der ( ext, extnValue, extnValueLen);
+       result = asn1_get_der(ext, extnValue, extnValueLen);
 
        if (result != ASN_OK) {
                gnutls_assert();
                asn1_delete_structure(ext);
-               return GNUTLS_E_ASN1_PARSING_ERROR;
+               return 0;
        }
 
        len = sizeof(str) - 1;
@@ -114,7 +59,7 @@ int len, result;
        if (result != ASN_OK) {
                gnutls_assert();
                asn1_delete_structure(ext);
-               return GNUTLS_E_ASN1_PARSING_ERROR;
+               return 0;
        }
 
        keyUsage[0] = str[0];
@@ -124,29 +69,28 @@ int len, result;
        return 0;
 }
 
-static int _extract_basicConstraints( int* CA, opaque* extnValue, int extnValueLen) {
-node_asn* ext;
-char str[128];
-int len, result;
+static int _extract_basicConstraints(int *CA, opaque * extnValue,
+                                    int extnValueLen)
+{
+       node_asn *ext;
+       char str[128];
+       int len, result;
 
        *CA = 0;
-               
+
        if (asn1_create_structure
-           ( _gnutls_get_pkix(), "PKIX1Implicit88.BasicConstraints", &ext, 
-               "bc") != ASN_OK) {
+           (_gnutls_get_pkix(), "PKIX1Implicit88.BasicConstraints", &ext,
+            "bc") != ASN_OK) {
                gnutls_assert();
                return GNUTLS_E_ASN1_PARSING_ERROR;
        }
 
-       result = asn1_get_der ( ext, extnValue, extnValueLen);
+       result = asn1_get_der(ext, extnValue, extnValueLen);
 
        if (result != ASN_OK) {
                gnutls_assert();
                asn1_delete_structure(ext);
-               return 0; /* GNUTLS_E_ASN1_PARSING_ERROR may be better
-                          * but we want to continue even if the
-                          * certificate is badly formated.
-                          */
+               return 0;
        }
 
        len = sizeof(str) - 1;
@@ -154,47 +98,50 @@ int len, result;
        if (result != ASN_OK) {
                gnutls_assert();
                asn1_delete_structure(ext);
-               return 0; /* see above.
-                          */
+               return 0;
        }
 
        asn1_delete_structure(ext);
 
-       if ( strcmp(str, "TRUE")==0) *CA = 1;
-       else *CA = 0;
+       if (strcmp(str, "TRUE") == 0)
+               *CA = 1;
+       else
+               *CA = 0;
 
 
        return 0;
 }
 
 
-static int _parse_extension( gnutls_cert* cert, char* extnID, char* critical, char* extnValue, int extnValueLen) {
+static int _parse_extension(gnutls_cert * cert, char *extnID,
+                           char *critical, char *extnValue,
+                           int extnValueLen)
+{
 
-       if (strcmp( extnID, "2 5 29 14")==0) { /* subject Key ID */
+       if (strcmp(extnID, "2 5 29 14") == 0) { /* subject Key ID */
                /* we don't use it */
                return 0;
        }
 
-       if (strcmp( extnID, "2 5 29 15")==0) { /* Key Usage */
-               return _extract_keyUsage( &cert->keyUsage, extnValue, extnValueLen);
+       if (strcmp(extnID, "2 5 29 15") == 0) { /* Key Usage */
+fprintf(stderr, "key USAGE FOUND\n");
+               return _extract_keyUsage(&cert->keyUsage, extnValue, extnValueLen);
        }
 
-       if (strcmp( extnID, "2 5 29 19")==0) { /* Basic Constraints */
+       if (strcmp(extnID, "2 5 29 19") == 0) { /* Basic Constraints */
                /* actually checks if a certificate belongs to
                 * a Certificate Authority.
                 */
-               return _extract_basicConstraints( &cert->CA, extnValue, extnValueLen);
-       }
-
-       if (strcmp( extnID, "2 5 29 17")==0) { /* subjectAltDNSName */
-               return _extract_subjectAltDNSName( cert->subjectAltDNSName, extnValue, extnValueLen);
+               return _extract_basicConstraints(&cert->CA, extnValue,
+                                                extnValueLen);
        }
 
 #ifdef DEBUG
-       _gnutls_log("CERT[%s]: Unsupported Extension: %s, %s\n", GET_CN(cert->raw), extnID, critical);
+       _gnutls_log("CERT[%s]: Unsupported Extension: %s, %s\n",
+                   GET_CN(cert->raw), extnID, critical);
 #endif
-       
-       if (strcmp( critical, "TRUE")==0) {
+
+       if (strcmp(critical, "TRUE") == 0) {
                gnutls_assert();
                return GNUTLS_E_X509_UNSUPPORTED_CRITICAL_EXTENSION;
        }
@@ -205,7 +152,7 @@ static int _parse_extension( gnutls_cert* cert, char* extnID, char* critical, ch
 /* This function will attempt to parse Extensions in
  * an X509v3 certificate
  */
-int _gnutls_get_ext_type( node_asn *rasn, char *root, gnutls_cert *cert)
+int _gnutls_get_ext_type(node_asn * rasn, char *root, gnutls_cert * cert)
 {
        int k, result, len;
        char name[128], name2[128], counter[MAX_INT_DIGITS];
@@ -217,19 +164,20 @@ int _gnutls_get_ext_type( node_asn *rasn, char *root, gnutls_cert *cert)
        k = 0;
        do {
                k++;
-               
+
                strcpy(name, root);
                strcat(name, ".?");
                _gnutls_int2str(k, counter);
                strcat(name, counter);
 
                len = sizeof(str) - 1;
-               result = asn1_read_value( rasn, name, str, &len);
-               
+               result = asn1_read_value(rasn, name, str, &len);
+
                /* move to next
                 */
 
-               if (result==ASN_ELEMENT_NOT_FOUND) break;
+               if (result == ASN_ELEMENT_NOT_FOUND)
+                       break;
 
                do {
 
@@ -237,60 +185,207 @@ int _gnutls_get_ext_type( node_asn *rasn, char *root, gnutls_cert *cert)
                        strcat(name2, ".extnID");
 
                        len = sizeof(extnID) - 1;
-                       result = asn1_read_value( rasn, name2, extnID, &len);
+                       result =
+                           asn1_read_value(rasn, name2, extnID, &len);
 
-                       if (result==ASN_ELEMENT_NOT_FOUND) break;
-                       else
-                               if (result != ASN_OK) {
-                                       gnutls_assert();
-                                       return GNUTLS_E_ASN1_PARSING_ERROR;
-                               }
+                       if (result == ASN_ELEMENT_NOT_FOUND)
+                               break;
+                       else if (result != ASN_OK) {
+                               gnutls_assert();
+                               return GNUTLS_E_ASN1_PARSING_ERROR;
+                       }
 
                        strcpy(name2, name);
                        strcat(name2, ".critical");
-                       
+
                        len = sizeof(critical) - 1;
-                       result = asn1_read_value( rasn, name2, critical, &len);
+                       result =
+                           asn1_read_value(rasn, name2, critical, &len);
 
-                       if (result==ASN_ELEMENT_NOT_FOUND) break;
-                       else
+                       if (result == ASN_ELEMENT_NOT_FOUND)
+                               break;
+                       else if (result != ASN_OK) {
+                               gnutls_assert();
+                               return GNUTLS_E_ASN1_PARSING_ERROR;
+                       }
+
+                       strcpy(name2, name);
+                       strcat(name2, ".extnValue");
+
+                       len = sizeof(extnValue) - 1;
+                       result =
+                           asn1_read_value(rasn, name2, extnValue, &len);
+
+                       if (result == ASN_ELEMENT_NOT_FOUND)
+                               break;
+                       else {
+                               if (result == ASN_MEM_ERROR
+                                   && strcmp(critical, "FALSE") == 0) {
+#ifdef DEBUG
+                                       _gnutls_log
+                                           ("Cannot parse extension: %s. Too small buffer.",
+                                            extnID);
+#endif
+                                       continue;
+                               }
                                if (result != ASN_OK) {
                                        gnutls_assert();
                                        return GNUTLS_E_ASN1_PARSING_ERROR;
                                }
-                               
+                       }
+
+                       /* Handle Extension */
+                       if ((result =
+                            _parse_extension(cert, extnID, critical,
+                                             extnValue, len)) < 0) {
+                               gnutls_assert();
+                               return result;
+                       }
+
+
+               } while (0);
+       } while (1);
+
+       if (result == ASN_ELEMENT_NOT_FOUND)
+               return 0;
+       else
+               return GNUTLS_E_ASN1_PARSING_ERROR;
+}
+
+/* This function will attempt to return the requested extension found in
+ * the given X509v3 certificate. The return value is allocated and stored into
+ * ret.
+ */
+int _gnutls_get_extension( const gnutls_datum * cert, const char* extension_id, gnutls_datum* ret)
+{
+       int k, result, len;
+       char name[128], name2[128], counter[MAX_INT_DIGITS];
+       char str[1024];
+       char critical[10];
+       char extnID[128];
+       char extnValue[256];
+       node_asn* rasn;
+
+       ret->data = NULL;
+       ret->size = 0;
+       
+       if (asn1_create_structure
+           (_gnutls_get_pkix(), "PKIX1Implicit88.Certificate", &rasn,
+            "certificate2")
+           != ASN_OK) {
+               gnutls_assert();
+               return GNUTLS_E_ASN1_ERROR;
+       }
+
+       result =
+           asn1_get_der(rasn, cert->data, cert->size);
+       if (result != ASN_OK) {
+               /* couldn't decode DER */
+#ifdef DEBUG
+               _gnutls_log("Decoding error %d\n", result);
+#endif
+               gnutls_assert();
+               asn1_delete_structure(rasn);
+               return GNUTLS_E_ASN1_PARSING_ERROR;
+       }
+
+       k = 0;
+       do {
+               k++;
+
+               strcpy(name, "certificate2");
+               strcat(name, ".?");
+               _gnutls_int2str(k, counter);
+               strcat(name, counter);
+
+               len = sizeof(str) - 1;
+               result = asn1_read_value(rasn, name, str, &len);
+
+               /* move to next
+                */
+
+               if (result == ASN_ELEMENT_NOT_FOUND)
+                       break;
+
+               do {
+
+                       strcpy(name2, name);
+                       strcat(name2, ".extnID");
+
+                       len = sizeof(extnID) - 1;
+                       result =
+                           asn1_read_value(rasn, name2, extnID, &len);
+
+                       if (result == ASN_ELEMENT_NOT_FOUND)
+                               break;
+                       else if (result != ASN_OK) {
+                               gnutls_assert();
+                               return GNUTLS_E_ASN1_PARSING_ERROR;
+                       }
+
+                       strcpy(name2, name);
+                       strcat(name2, ".critical");
+
+                       len = sizeof(critical) - 1;
+                       result =
+                           asn1_read_value(rasn, name2, critical, &len);
+
+                       if (result == ASN_ELEMENT_NOT_FOUND)
+                               break;
+                       else if (result != ASN_OK) {
+                               gnutls_assert();
+                               asn1_delete_structure(rasn);
+                               return GNUTLS_E_ASN1_PARSING_ERROR;
+                       }
+
                        strcpy(name2, name);
                        strcat(name2, ".extnValue");
 
-                       len = sizeof( extnValue) - 1;
-                       result = asn1_read_value( rasn, name2, extnValue, &len);
+                       len = sizeof(extnValue) - 1;
+                       result =
+                           asn1_read_value(rasn, name2, extnValue, &len);
 
-                       if (result==ASN_ELEMENT_NOT_FOUND) break;
+                       if (result == ASN_ELEMENT_NOT_FOUND)
+                               break;
                        else {
-                               if (result==ASN_MEM_ERROR && strcmp(critical, "FALSE")==0) {
+                               if (result == ASN_MEM_ERROR
+                                   && strcmp(critical, "FALSE") == 0) {
 #ifdef DEBUG
-                                       _gnutls_log("Cannot parse extension: %s. Too small buffer.", extnID);
+                                       _gnutls_log
+                                           ("Cannot parse extension: %s. Too small buffer.",
+                                            extnID);
 #endif
                                        continue;
                                }
                                if (result != ASN_OK) {
                                        gnutls_assert();
+                                       asn1_delete_structure(rasn);
                                        return GNUTLS_E_ASN1_PARSING_ERROR;
                                }
                        }
-                       
+
                        /* Handle Extension */
-                       if ( (result=_parse_extension( cert, extnID, critical, extnValue, len)) < 0) {
-                               gnutls_assert();
-                               return result;
+                       if ( strcmp(extnID, extension_id)==0) { /* extension was found */
+                               asn1_delete_structure(rasn);
+                               ret->data = gnutls_malloc( len);
+                               if (ret->data==NULL)
+                                       return GNUTLS_E_MEMORY_ERROR;   
+
+                               ret->size = len;
+                               memcpy( ret->data, extnValue, len);
+                               
+                               return 0;
                        }
-                       
-                       
+
+
                } while (0);
        } while (1);
 
-       if (result==ASN_ELEMENT_NOT_FOUND)
-               return 0;
-       else 
+       asn1_delete_structure(rasn);
+
+
+       if (result == ASN_ELEMENT_NOT_FOUND)
+               return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
+       else
                return GNUTLS_E_ASN1_PARSING_ERROR;
 }
index 89350710258f1a242492e29736e10755f919c1cd..1d4d1c82d0c0a1229ae14a3c427fe245ae5abd83 100644 (file)
@@ -1 +1,2 @@
 int _gnutls_get_ext_type( node_asn *rasn, char *root, gnutls_cert *cert);
+int _gnutls_get_extension( const gnutls_datum * cert, const char* extension_id, gnutls_datum* ret);
index cbb75e398884001dd847f2eb49a9b4949382b0ab..2daea7c7696dad5afb36f3d528cf8df061103923 100644 (file)
@@ -1,4 +1,4 @@
-EXTRA_DIST = port.h prime.gaa crypt.gaa crypt-gaa.h README.crypt prime-gaa.h \
+EXTRA_DIST = common.h prime.gaa crypt.gaa crypt-gaa.h README.crypt prime-gaa.h \
                README 
 SUBDIRS = srp x509
 
index 19b1ad4b2e43dba7fee6e0cd8d062528abdc1aff..01aa491126e99a91eeafe09875366f3f8c08c23a 100644 (file)
--- a/src/cli.c
+++ b/src/cli.c
@@ -31,6 +31,7 @@
 #include <sys/time.h>
 #include <signal.h>
 #include <netdb.h>
+#include <common.h>
 
 #ifndef SHUT_WR
 # define SHUT_WR 1
 #define CLIKEYFILE "x509/clikey.pem"
 #define CLICERTFILE "x509/clicert.pem"
 
-#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( "E:", X.email); \
-       PRINTX( "SAN:", gnutls_x509pki_client_get_subject_dns_name(state))
-
 static int print_info( GNUTLS_STATE state) {
 const char *tmp;
 CredType cred;
 gnutls_DN dn;
 CertificateStatus status;
-
+char dnsname[512];
+int dnsname_size;
 
        tmp = gnutls_kx_get_name(gnutls_get_current_kx( state));
        printf("- Key Exchange: %s\n", tmp);
diff --git a/src/common.h b/src/common.h
new file mode 100644 (file)
index 0000000..56f77d4
--- /dev/null
@@ -0,0 +1,14 @@
+#define PORT 5556
+#define SERVER "127.0.0.1"
+
+#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( "E:", X.email); \
+       dnsname_size = sizeof(dnsname); \
+       gnutls_x509pki_client_get_subject_dns_name(state, dnsname, &dnsname_size); \
+       PRINTX( "SAN:", dnsname)
diff --git a/src/port.h b/src/port.h
deleted file mode 100644 (file)
index 696b48c..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-#define PORT 5556
-#define SERVER "127.0.0.1"
index 8bf777f1593bcf4181ea254646c64c8593f7976f..763da05504e1c33f0868d4a2922b3790d70c407d 100644 (file)
@@ -28,7 +28,7 @@
 #include <string.h>
 #include <unistd.h>
 #include "../lib/gnutls.h"
-#include <port.h>
+#include <common.h>
 #include <signal.h>
 
 #define KEYFILE "x509/key.pem"
@@ -100,15 +100,6 @@ GNUTLS_STATE initialize_state()
        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( "E:", X.email); \
-       PRINTX( "SAN:", gnutls_x509pki_client_get_subject_dns_name(state))
 
 void print_info(GNUTLS_STATE state)
 {
@@ -118,6 +109,8 @@ void print_info(GNUTLS_STATE state)
        gnutls_DN dn;
        CredType cred;
        CertificateStatus status;
+       char dnsname[512];
+       int dnsname_size;
        
        /* print session_id specific data */
        gnutls_get_current_session_id( state, sesid, &sesid_size);