summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--NEWS3
-rw-r--r--lib/Makefile.am2
-rw-r--r--lib/auth_cert.c2
-rw-r--r--lib/gnutls_global.c2
-rw-r--r--lib/gnutls_hash_int.c3
-rw-r--r--lib/gnutls_random.c42
-rw-r--r--lib/gnutls_ui.h1
-rw-r--r--lib/gnutls_x509.c425
-rw-r--r--lib/pkix.asn40
-rw-r--r--lib/pkix_asn1_tab.c51
-rwxr-xr-xlib/x509_asn1.c4
-rw-r--r--lib/x509_extensions.c6
-rw-r--r--lib/x509_sig_check.c2
-rw-r--r--lib/x509_verify.c4
-rwxr-xr-xsrc/gnutls-http-serv2
-rw-r--r--src/serv.c2
16 files changed, 432 insertions, 159 deletions
diff --git a/NEWS b/NEWS
index 3a9043b22c..93f3eae24c 100644
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,6 @@
+Version 0.4.0
+- Added support for RFC2630 (PKCS7) X.509 certificate sets
+
Version 0.3.92 (23/03/2002)
- Updated documentation
- Combined error codes of ASN.1 parser and gnutls
diff --git a/lib/Makefile.am b/lib/Makefile.am
index f1e199a52c..074b211c11 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -39,7 +39,7 @@ COBJECTS = gnutls_record.c gnutls_compress.c debug.c \
x509_extensions.c auth_cert.c gnutls_ui.c gnutls_sig.c auth_dhe.c \
gnutls_dh_primes.c ext_max_record.c gnutls_alert.c gnutls_int_compat.c \
gnutls_str.c gnutls_state.c gnutls_x509.c gnutls_openpgp.c \
- ext_cert_type.c
+ ext_cert_type.c
# Separate so we can create the documentation
COBJECTS2 = x509_ASN.y x509_asn1.c x509_der.c
diff --git a/lib/auth_cert.c b/lib/auth_cert.c
index 4865362448..ac05a74b8b 100644
--- a/lib/auth_cert.c
+++ b/lib/auth_cert.c
@@ -105,7 +105,7 @@ int _gnutls_find_dn(gnutls_datum * odn, gnutls_cert * cert)
int start, end;
if ((result=asn1_create_structure
- (_gnutls_get_pkix(), "PKIX1Implicit88.Certificate", &dn,
+ (_gnutls_get_pkix(), "PKIX1.Certificate", &dn,
"dn")) != ASN_OK) {
gnutls_assert();
return result;
diff --git a/lib/gnutls_global.c b/lib/gnutls_global.c
index 5e0707ae08..8998268ede 100644
--- a/lib/gnutls_global.c
+++ b/lib/gnutls_global.c
@@ -113,7 +113,7 @@ int gnutls_global_init( void)
asn1_delete_structure( PKIX1_ASN);
return result;
}
-
+
result = _gnutls_dh_calc_mpis();
if (result < 0) {
gnutls_assert();
diff --git a/lib/gnutls_hash_int.c b/lib/gnutls_hash_int.c
index 273bca4c99..fcbb0d7ad3 100644
--- a/lib/gnutls_hash_int.c
+++ b/lib/gnutls_hash_int.c
@@ -148,6 +148,9 @@ void gnutls_hash_deinit(GNUTLS_HASH_HANDLE handle, void* digest)
free(ret);
}
#else
+ /* FIXME: replace this with something that does not
+ * allocate the hash
+ */
maclen = gcry_md_get_algo_dlen(gcry_md_get_algo(handle->handle));
gcry_md_final(handle->handle);
mac = gcry_md_read(handle->handle, 0);
diff --git a/lib/gnutls_random.c b/lib/gnutls_random.c
index b2acb0cb72..609ca21760 100644
--- a/lib/gnutls_random.c
+++ b/lib/gnutls_random.c
@@ -28,56 +28,30 @@
# include <sys/types.h>
# include <sys/stat.h>
# include <fcntl.h>
-# ifdef HAVE_SYS_TIME_H
-# include <sys/time.h>
-# endif
#endif
-int _gnutls_get_random(opaque * res, int bytes, int dev)
+/* fills the buffer 'res' with random bytes of 'bytes' long.
+ * level is WEAK, STRONG, or VERY_STRONG (libgcrypt)
+ */
+int _gnutls_get_random(opaque * res, int bytes, int level)
{
#ifndef USE_GCRYPT
int fd;
- struct timeval tv;
- char prand[16];
char *device;
-#error DONT USE THAT
-
- switch(dev) {
- case 1:
- device = "/dev/random";
- break;
- default:
- device = "dev/urandom";
- }
+ device = "dev/urandom";
fd = open(device, O_RDONLY);
if (device == NULL || fd < 0) {
- gettimeofday(&tv, (struct timezone *) 0);
- memcpy(prand, &tv, sizeof(tv));
- fd = getpid();
- memcpy(&prand[8], &fd, sizeof(fd));
- fd = clock();
- memcpy(&prand[12], &fd, sizeof(fd));
- memset(res, 0, bytes);
- if (bytes > 16)
- bytes = 16;
- memcpy(res, prand, bytes);
+ _gnutls_log( "Could not open random device\n");
+ return GNUTLS_E_FILE_ERROR;
} else {
read(fd, res, bytes);
close(fd);
}
return 0;
#else /* using gcrypt */
- char* buf;
- buf = gcry_random_bytes(bytes, dev);
- if (buf==NULL) {
- gnutls_assert();
- return GNUTLS_E_MEMORY_ERROR;
- }
-
- memcpy( res, buf, bytes);
- gcry_free(buf);
+ gcry_randomize( res, bytes, level);
return 0;
#endif
diff --git a/lib/gnutls_ui.h b/lib/gnutls_ui.h
index 22b2e08af3..a20dc122ef 100644
--- a/lib/gnutls_ui.h
+++ b/lib/gnutls_ui.h
@@ -88,6 +88,7 @@ int gnutls_x509_extract_certificate_serial(const gnutls_datum * cert, char* resu
time_t gnutls_x509_extract_certificate_activation_time( const gnutls_datum*);
time_t gnutls_x509_extract_certificate_expiration_time( const gnutls_datum*);
int gnutls_x509_extract_subject_alt_name( const gnutls_datum*, int seq, char*, int*);
+int gnutls_x509_pkcs7_extract_certificate(const gnutls_datum * pkcs7_struct, int indx, char* certificate, int* certificate_size);
int gnutls_x509_verify_certificate( const gnutls_datum* cert_list, int cert_list_length, const gnutls_datum * CA_list, int CA_list_length, const gnutls_datum* CRL_list, int CRL_list_length);
diff --git a/lib/gnutls_x509.c b/lib/gnutls_x509.c
index e6180ff16e..2a6b4e4ca1 100644
--- a/lib/gnutls_x509.c
+++ b/lib/gnutls_x509.c
@@ -48,6 +48,9 @@
* some x509 certificate parsing functions.
*/
+int gnutls_x509_pkcs7_extract_certificate(const gnutls_datum * pkcs7_struct, int indx, char* certificate, int* certificate_size);
+
+
#define _READ(a, aa, b, c, d, e, res, f) \
result = _IREAD(a, aa, sizeof(aa), b, c, d, e, res, sizeof(res)-1, f); \
if (result<0) return result; \
@@ -64,7 +67,7 @@ static int _IREAD(node_asn * rasn, char *name3, int name3_size, char *rstr, char
if (strcmp(rstr, OID) == 0) {
- _gnutls_str_cpy(str, sizeof(str), "PKIX1Implicit88.");
+ _gnutls_str_cpy(str, sizeof(str), "PKIX1.");
_gnutls_str_cat(str, sizeof(str), ANAME);
_gnutls_str_cpy(name2, sizeof(name2), "temp-structure-");
_gnutls_str_cat(name2, sizeof(name2), TYPE);
@@ -333,7 +336,7 @@ int gnutls_x509_extract_dn(const gnutls_datum * idn, gnutls_x509_dn * rdn)
if ((result =
asn1_create_structure(_gnutls_get_pkix(),
- "PKIX1Implicit88.Name", &dn,
+ "PKIX1.Name", &dn,
"dn")) != ASN_OK) {
gnutls_assert();
return result;
@@ -378,9 +381,9 @@ int gnutls_x509_extract_certificate_dn(const gnutls_datum * cert,
memset(ret, 0, sizeof(gnutls_x509_dn));
- if (asn1_create_structure
- (_gnutls_get_pkix(), "PKIX1Implicit88.Certificate", &c2,
- "certificate2")
+ if ((result=asn1_create_structure
+ (_gnutls_get_pkix(), "PKIX1.Certificate", &c2,
+ "certificate2"))
!= ASN_OK) {
gnutls_assert();
return result;
@@ -430,9 +433,9 @@ int gnutls_x509_extract_certificate_issuer_dn(const gnutls_datum * cert,
memset(ret, 0, sizeof(gnutls_x509_dn));
- if (asn1_create_structure
- (_gnutls_get_pkix(), "PKIX1Implicit88.Certificate", &c2,
- "certificate2")
+ if ((result=asn1_create_structure
+ (_gnutls_get_pkix(), "PKIX1.Certificate", &c2,
+ "certificate2"))
!= ASN_OK) {
gnutls_assert();
return result;
@@ -487,7 +490,8 @@ static GNUTLS_X509_SUBJECT_ALT_NAME _find_type( char* str_type) {
* or the type of alternative name if everything was ok. The type is one of the
* enumerated GNUTLS_X509_SUBJECT_ALT_NAME.
*
- * If the certificate does not have a Alternative name then returns GNUTLS_E_DATA_NOT_AVAILABLE;
+ * If the certificate does not have an Alternative name with the specified sequence number
+ * then returns GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
*
**/
int gnutls_x509_extract_subject_alt_name(const gnutls_datum * cert, int seq, char *ret, int *ret_size)
@@ -515,7 +519,7 @@ int gnutls_x509_extract_subject_alt_name(const gnutls_datum * cert, int seq, cha
}
if ((result=asn1_create_structure
- (_gnutls_get_pkix(), "PKIX1Implicit88.SubjectAltName", &c2, "san"))
+ (_gnutls_get_pkix(), "PKIX1.SubjectAltName", &c2, "san"))
!= ASN_OK) {
gnutls_assert();
gnutls_free_datum( &dnsname);
@@ -540,8 +544,15 @@ int gnutls_x509_extract_subject_alt_name(const gnutls_datum * cert, int seq, cha
_gnutls_str_cat( nptr, sizeof(nptr), num);
len = sizeof(ext_data);
- if ((result =
- asn1_read_value(c2, nptr, ext_data, &len)) != ASN_OK) {
+ result =
+ asn1_read_value(c2, nptr, ext_data, &len);
+
+ if (result == ASN_VALUE_NOT_FOUND) {
+ asn1_delete_structure(c2);
+ return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
+ }
+
+ if (result != ASN_OK) {
gnutls_assert();
asn1_delete_structure(c2);
return result;
@@ -588,7 +599,7 @@ time_t gnutls_x509_extract_certificate_activation_time(const
time_t ret;
if (asn1_create_structure
- (_gnutls_get_pkix(), "PKIX1Implicit88.Certificate", &c2,
+ (_gnutls_get_pkix(), "PKIX1.Certificate", &c2,
"certificate2")
!= ASN_OK) {
gnutls_assert();
@@ -630,7 +641,7 @@ time_t gnutls_x509_extract_certificate_expiration_time(const
time_t ret;
if (asn1_create_structure
- (_gnutls_get_pkix(), "PKIX1Implicit88.Certificate", &c2,
+ (_gnutls_get_pkix(), "PKIX1.Certificate", &c2,
"certificate2")
!= ASN_OK) {
gnutls_assert();
@@ -668,7 +679,7 @@ int gnutls_x509_extract_certificate_version(const gnutls_datum * cert)
int result;
if ((result=asn1_create_structure
- (_gnutls_get_pkix(), "PKIX1Implicit88.Certificate", &c2,
+ (_gnutls_get_pkix(), "PKIX1.Certificate", &c2,
"certificate2"))
!= ASN_OK) {
gnutls_assert();
@@ -897,7 +908,7 @@ int gnutls_x509_extract_certificate_serial(const gnutls_datum * cert, char* resu
int ret;
if ((ret=asn1_create_structure
- (_gnutls_get_pkix(), "PKIX1Implicit88.Certificate", &c2,
+ (_gnutls_get_pkix(), "PKIX1.Certificate", &c2,
"certificate2"))
!= ASN_OK) {
gnutls_assert();
@@ -946,37 +957,106 @@ static int _gnutls_check_key_cert_match( GNUTLS_CERTIFICATE_CREDENTIALS res) {
#define MAX_FILE_SIZE 100*1024
#define CERT_SEP "-----BEGIN"
-/* Reads a base64 encoded certificate from memory
+/* Reads a PKCS7 base64 encoded certificate list from memory and stores it to
+ * a gnutls_cert structure.
*/
-static int read_cert_mem(GNUTLS_CERTIFICATE_CREDENTIALS res, const char *cert, int cert_size)
+static int parse_pkcs7_cert_mem( gnutls_cert** cert_list, int* ncerts,
+ const char *input_cert, int input_cert_size)
{
- int siz, i, siz2;
+ int siz, i, j;
opaque *b64;
const char *ptr;
- gnutls_datum tmp;
+ gnutls_datum tmp, tmp2;
int ret;
+ opaque pcert[MAX_X509_CERT_SIZE];
+ int pcert_size;
- /* allocate space for the certificate to add
- */
- res->cert_list = gnutls_realloc( res->cert_list, (1+res->ncerts)*sizeof(gnutls_cert*));
- if (res->cert_list==NULL) {
- gnutls_assert();
- return GNUTLS_E_MEMORY_ERROR;
- }
+ ptr = input_cert;
+ siz = input_cert_size;
+ i = *ncerts + 1;
- res->cert_list_length = gnutls_realloc( res->cert_list_length,
- (1+res->ncerts)*sizeof(int));
- if (res->cert_list_length==NULL) {
+ ret = _gnutls_fbase64_decode(ptr, siz, &b64);
+
+ if (ret < 0) {
gnutls_assert();
- return GNUTLS_E_MEMORY_ERROR;
+ return GNUTLS_E_PARSING_ERROR;
}
+
+ /* tmp now contains the decoded certificate list */
+ tmp.data = b64;
+ tmp.size = ret;
+ j = 0;
+ do {
+ pcert_size = sizeof(pcert);
+ ret = gnutls_x509_pkcs7_extract_certificate( &tmp, j, pcert, &pcert_size);
- ptr = cert;
- siz = cert_size;
- i = 1;
+ /* if the current certificate is too long, just ignore
+ * it. */
+ if (ret==GNUTLS_E_MEMORY_ERROR) continue;
+
+ if (ret >= 0) {
+ *cert_list =
+ (gnutls_cert *) gnutls_realloc( *cert_list,
+ i * sizeof(gnutls_cert));
+
+ if ( *cert_list == NULL) {
+ gnutls_assert();
+ gnutls_free(b64);
+ return GNUTLS_E_MEMORY_ERROR;
+ }
+
+ /* set defaults to zero
+ */
+ memset( &cert_list[0][i - 1], 0, sizeof(gnutls_cert));
+
+ tmp2.data = pcert;
+ tmp2.size = pcert_size;
+
+ if ((ret =
+ _gnutls_x509_cert2gnutls_cert(
+ &cert_list[0][i - 1],
+ tmp2)) < 0) {
+ gnutls_free(b64);
+ gnutls_assert();
+ return ret;
+ }
+
+ i++;
+ }
+ j++;
+
+ } while (ret >= 0);
+
+ gnutls_free(b64);
+
+ *ncerts = i - 1;
+
+ return 0;
+}
+
+
+/* Reads a base64 encoded certificate list from memory and stores it to
+ * a gnutls_cert structure.
+ */
+static int parse_cert_mem( gnutls_cert** cert_list, int* ncerts,
+ const char *input_cert, int input_cert_size)
+{
+ int siz, i, siz2;
+ opaque *b64;
+ const char *ptr;
+ gnutls_datum tmp;
+ int ret;
- res->cert_list[res->ncerts] = NULL;
+ if (strstr( input_cert, "-----BEGIN PKCS7")!=NULL) {
+ return parse_pkcs7_cert_mem( cert_list, ncerts, input_cert,
+ input_cert_size);
+ }
+
+
+ ptr = input_cert;
+ siz = input_cert_size;
+ i = *ncerts + 1;
do {
siz2 = _gnutls_fbase64_decode(ptr, siz, &b64);
@@ -989,28 +1069,27 @@ static int read_cert_mem(GNUTLS_CERTIFICATE_CREDENTIALS res, const char *cert, i
}
- res->cert_list[res->ncerts] =
- (gnutls_cert *) gnutls_realloc(res->
- cert_list[res->ncerts],
+ *cert_list =
+ (gnutls_cert *) gnutls_realloc( *cert_list,
i *
sizeof(gnutls_cert));
- if (res->cert_list[res->ncerts] == NULL) {
+ if ( *cert_list == NULL) {
gnutls_assert();
gnutls_free(b64);
return GNUTLS_E_MEMORY_ERROR;
}
/* set defaults to zero
*/
- memset(&res->cert_list[res->ncerts][i - 1], 0,
+ memset( &cert_list[0][i - 1], 0,
sizeof(gnutls_cert));
tmp.data = b64;
tmp.size = siz2;
if ((ret =
- _gnutls_x509_cert2gnutls_cert(&res->
- cert_list[res->ncerts][i - 1],
+ _gnutls_x509_cert2gnutls_cert(
+ &cert_list[0][i - 1],
tmp)) < 0) {
gnutls_free(b64);
gnutls_assert();
@@ -1026,73 +1105,57 @@ static int read_cert_mem(GNUTLS_CERTIFICATE_CREDENTIALS res, const char *cert, i
i++;
} while ((ptr = strstr(ptr, CERT_SEP)) != NULL);
- res->cert_list_length[res->ncerts] = i - 1;
-
+ *ncerts = i - 1;
return 0;
}
-/* Reads a base64 encoded CA list from memory
- * This is to be called once.
+
+
+/* Reads a base64 encoded certificate from memory
*/
-static int read_ca_mem(GNUTLS_CERTIFICATE_CREDENTIALS res, const char *ca, int ca_size)
+static int read_cert_mem(GNUTLS_CERTIFICATE_CREDENTIALS res, const char *cert, int cert_size)
{
- int siz, siz2, i;
- opaque *b64;
- const char *ptr;
int ret;
- gnutls_datum tmp;
- siz = ca_size;
-
- ptr = ca;
-
- i = res->x509_ncas + 1;
-
- do {
- siz2 = _gnutls_fbase64_decode(ptr, siz, &b64);
- siz -= siz2; /* FIXME: this is not enough
- */
+ /* allocate space for the certificate to add
+ */
+ res->cert_list = gnutls_realloc( res->cert_list, (1+ res->ncerts)*sizeof(gnutls_cert*));
+ if ( res->cert_list==NULL) {
+ gnutls_assert();
+ return GNUTLS_E_MEMORY_ERROR;
+ }
- if (siz2 < 0) {
- gnutls_assert();
- return GNUTLS_E_PARSING_ERROR;
- }
+ res->cert_list_length = gnutls_realloc( res->cert_list_length,
+ (1+ res->ncerts)*sizeof(int));
+ if (res->cert_list_length==NULL) {
+ gnutls_assert();
+ return GNUTLS_E_MEMORY_ERROR;
+ }
- res->x509_ca_list =
- (gnutls_cert *) gnutls_realloc(res->x509_ca_list,
- i *
- sizeof(gnutls_cert));
- if (res->x509_ca_list == NULL) {
- gnutls_assert();
- gnutls_free(b64);
- return GNUTLS_E_MEMORY_ERROR;
- }
- memset(&res->x509_ca_list[i - 1], 0, sizeof(gnutls_cert));
+ res->cert_list[res->ncerts] = NULL; /* for realloc */
+ res->cert_list_length[res->ncerts] = 0;
- tmp.data = b64;
- tmp.size = siz2;
+ ret = parse_cert_mem( &res->cert_list[res->ncerts], &res->cert_list_length[res->ncerts],
+ cert, cert_size);
- if ((ret =
- _gnutls_x509_cert2gnutls_cert(&res->x509_ca_list[i - 1],
- tmp)) < 0) {
- gnutls_assert();
- gnutls_free(b64);
- return ret;
- }
- gnutls_free(b64);
+ if (ret < 0) {
+ gnutls_assert();
+ return ret;
+ }
- /* now we move ptr after the pem header */
- ptr = strstr(ptr, CERT_SEP);
- if (ptr!=NULL)
- ptr++;
+ return 0;
+}
- i++;
- } while ((ptr = strstr(ptr, CERT_SEP)) != NULL);
+/* Reads a base64 encoded CA list from memory
+ * This is to be called once.
+ */
+static int read_ca_mem(GNUTLS_CERTIFICATE_CREDENTIALS res, const char *ca, int ca_size)
+{
- res->x509_ncas = i - 1;
+ return parse_cert_mem( &res->x509_ca_list, &res->x509_ncas,
+ ca, ca_size);
- return 0;
}
@@ -1230,7 +1293,7 @@ static int read_key_file(GNUTLS_CERTIFICATE_CREDENTIALS res, char *keyfile)
* gnutls_certificate_set_x509_key_file - Used to set keys in a GNUTLS_CERTIFICATE_CREDENTIALS structure
* @res: is an &GNUTLS_CERTIFICATE_CREDENTIALS structure.
* @CERTFILE: is a PEM encoded file containing the certificate list (path) for
- * the specified private key
+ * the specified private key or a PEM encoded PKCS7 file
* @KEYFILE: is a PEM encoded file containing a private key
*
* This function sets a certificate/private key pair in the
@@ -1320,7 +1383,7 @@ opaque *pdata;
/**
* gnutls_certificate_set_x509_trust_mem - Used to add trusted CAs in a GNUTLS_CERTIFICATE_CREDENTIALS structure
* @res: is an &GNUTLS_CERTIFICATE_CREDENTIALS structure.
- * @CA: is a PEM encoded list of trusted CAs
+ * @CA: is a PEM encoded list of trusted CAs or a PKCS7 pem encoded list
* @CRL: is a PEM encoded list of CRLs (ignored for now)
*
* This function adds the trusted CAs in order to verify client
@@ -1459,7 +1522,7 @@ static int _read_dsa_params(opaque * der, int dersize, MPI * params)
node_asn *spk;
if ((result=asn1_create_structure
- (_gnutls_get_pkix(), "PKIX1Implicit88.Dss-Parms", &spk,
+ (_gnutls_get_pkix(), "PKIX1.Dss-Parms", &spk,
"dsa_parms")) != ASN_OK) {
gnutls_assert();
return result;
@@ -1685,7 +1748,7 @@ int _gnutls_x509_cert2gnutls_cert(gnutls_cert * gCert, gnutls_datum derCert)
}
if ((result=asn1_create_structure
- (_gnutls_get_pkix(), "PKIX1Implicit88.Certificate", &c2,
+ (_gnutls_get_pkix(), "PKIX1.Certificate", &c2,
"certificate2"))
!= ASN_OK) {
gnutls_assert();
@@ -1767,6 +1830,7 @@ int _gnutls_x509_cert2gnutls_cert(gnutls_cert * gCert, gnutls_datum derCert)
if (gCert->version < 0) {
gnutls_assert();
asn1_delete_structure(c2);
+ gnutls_free_datum( &gCert->raw);
return GNUTLS_E_ASN1_GENERIC_ERROR;
}
@@ -1923,4 +1987,171 @@ int _gnutls_verify_x509_file( char *cafile)
return _gnutls_verify_x509_mem( x, siz);
}
+
+
#endif
+
+/**
+ * gnutls_x509_pkcs7_extract_certificate - This function returns a certificate in a PKCS7 certificate set
+ * @pkcs7_struct: should contain a PKCS7 DER formatted structure
+ * @indx: contains the index of the certificate to extract
+ * @certificate: the contents of the certificate will be copied there
+ * @certificate_size: should hold the size of the certificate
+ *
+ * This function will return a certificate of the PKCS7 or RFC2630 certificate set.
+ * Returns 0 on success.
+ *
+ **/
+int gnutls_x509_pkcs7_extract_certificate(const gnutls_datum * pkcs7_struct, int indx, char* certificate, int* certificate_size)
+{
+ node_asn *c2, *c1;
+ int result, len;
+ char root1[128];
+ char oid[128];
+ char root2[128];
+ char counter[MAX_INT_DIGITS];
+ opaque* pkcs7_str = pkcs7_struct->data;
+ int pkcs7_str_size = pkcs7_struct->size;
+
+ opaque* pcert;
+ int pcert_size;
+
+ /* Step 1. Parse content and content info */
+
+ if (pkcs7_str_size == 0 || pkcs7_str == NULL) {
+ gnutls_assert();
+ return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
+ }
+
+ _gnutls_str_cpy( root1, sizeof(root1), "PKIX1.ContentInfo");
+ if ((result=asn1_create_structure
+ (_gnutls_get_pkix(), root1, &c1, "c1")) != ASN_OK) {
+ gnutls_assert();
+ return result;
+ }
+
+ result = asn1_get_der(c1, pkcs7_str, pkcs7_str_size);
+ if (result != ASN_OK) {
+ /* couldn't decode DER */
+
+ _gnutls_log("X509_auth: Decoding error %d\n");
+
+ gnutls_assert();
+ asn1_delete_structure(c1);
+ return result;
+ }
+
+ len = sizeof(oid) - 1;
+
+ /* root2 is used as a temp storage area
+ */
+ _gnutls_str_cpy( root2, sizeof(root2), "c1.contentType");
+ result = asn1_read_value(c1, root2, oid, &len);
+ if (result != ASN_OK) {
+ gnutls_assert();
+ asn1_delete_structure(c1);
+ return result;
+ }
+
+ if ( strcmp( oid, "1 2 840 113549 1 7 2") != 0) {
+ gnutls_assert();
+ asn1_delete_structure(c1);
+ return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
+ }
+
+ pcert_size = *certificate_size - 1;
+ pcert = certificate;
+
+ _gnutls_str_cpy( root2, sizeof(root2), "c1.content");
+ result = asn1_read_value(c1, root2, pcert, &pcert_size);
+
+ asn1_delete_structure(c1);
+
+ if (result != ASN_OK) {
+ gnutls_assert();
+ return result;
+ }
+
+ /* pcert, pcert_size hold the data and the size of the CertificateSet structure
+ * actually the ANY stuff.
+ */
+
+
+ /* Step 1.5. In case of a signed structure extract certificate set.
+ */
+ _gnutls_str_cpy( root2, sizeof(root2), "PKIX1.SignedData");
+ if ((result=asn1_create_structure
+ (_gnutls_get_pkix(), root2, &c2, "c2")) != ASN_OK) {
+ gnutls_assert();
+ return result;
+ }
+
+ result = asn1_get_der(c2, pcert, pcert_size);
+ if (result != ASN_OK) {
+ /* couldn't decode DER */
+
+ _gnutls_log("X509_auth: Decoding error %d\n");
+
+ gnutls_assert();
+ asn1_delete_structure(c2);
+ return result;
+ }
+
+
+ /* Step 2. Parse CertificateSet */
+
+
+ _gnutls_str_cpy( root2, sizeof(root2), "c2.certificates.?");
+ _gnutls_int2str( indx+1, counter);
+ _gnutls_str_cat( root2, sizeof(root2), counter);
+
+ len = sizeof(oid) - 1;
+
+ result = asn1_read_value(c2, root2, oid, &len);
+
+ if (result == ASN_VALUE_NOT_FOUND) {
+ asn1_delete_structure(c2);
+ return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
+ }
+
+ if (result != ASN_OK) {
+ gnutls_assert();
+ asn1_delete_structure(c2);
+ return result;
+ }
+
+ /* if 'Certificate' is the choice found: */
+ if (strcmp( oid, "certificate") == 0) {
+ int start, end;
+
+/* _gnutls_str_cat( root2, sizeof(root2), ".certificate"); */
+
+ result = asn1_get_start_end_der(c2, pcert, pcert_size,
+ root2, &start, &end);
+
+ if (result != ASN_OK) {
+ gnutls_assert();
+ asn1_delete_structure(c2);
+ return result;
+ }
+
+ end = end-start+1;
+
+ if (certificate!=NULL && end <= *certificate_size)
+ memcpy( certificate, &pcert[start], end);
+ else {
+ *certificate_size = end;
+ return GNUTLS_E_MEMORY_ERROR;
+ }
+
+ *certificate_size = end;
+
+ } else {
+ asn1_delete_structure(c2);
+ return GNUTLS_E_UNSUPPORTED_CERTIFICATE_TYPE;
+ }
+
+ asn1_delete_structure(c2);
+
+ return 0;
+}
diff --git a/lib/pkix.asn b/lib/pkix.asn
index 9faab3a370..fb44650127 100644
--- a/lib/pkix.asn
+++ b/lib/pkix.asn
@@ -1,11 +1,11 @@
-PKIX1Implicit88 {iso(1) identified-organization(3) dod(6) internet(1)
- security(5) mechanisms(5) pkix(7) id-mod(0) id-pkix1-implicit-88(2)}
+PKIX1 { }
DEFINITIONS IMPLICIT TAGS ::=
BEGIN
+-- This contains both PKIX1Implicit88 and RFC2630 ASN.1 modules.
-- ISO arc for standard certificate and CRL extensions
@@ -937,13 +937,47 @@ ub-x121-address-length INTEGER ::= 16
-END
+-- END of PKIX1Implicit88
+
+
+-- BEGIN of RFC2630
+
+-- Cryptographic Message Syntax
+
+ContentInfo ::= SEQUENCE {
+ contentType ContentType,
+ content [0] EXPLICIT ANY DEFINED BY contentType }
+ContentType ::= OBJECT IDENTIFIER
+SignedData ::= SEQUENCE {
+ version CMSVersion,
+ digestAlgorithms DigestAlgorithmIdentifiers,
+ encapContentInfo EncapsulatedContentInfo,
+ certificates [0] IMPLICIT CertificateSet OPTIONAL,
+ crls [1] IMPLICIT CertificateRevocationLists OPTIONAL,
+ signerInfos SignerInfos
+}
+
+CMSVersion ::= INTEGER { v0(0), v1(1), v2(2), v3(3), v4(4) }
+DigestAlgorithmIdentifiers ::= SET OF DigestAlgorithmIdentifier
+DigestAlgorithmIdentifier ::= AlgorithmIdentifier
+EncapsulatedContentInfo ::= SEQUENCE {
+ eContentType ContentType,
+ eContent [0] EXPLICIT OCTET STRING OPTIONAL }
+CertificateRevocationLists ::= SET OF CertificateList
+CertificateChoices ::= CHOICE {
+ certificate Certificate
+}
+CertificateSet ::= SET OF CertificateChoices
+SignerInfos ::= SET OF ANY -- this is not correct but we don't use it
+ -- anyway
+
+END
diff --git a/lib/pkix_asn1_tab.c b/lib/pkix_asn1_tab.c
index 727a980f4c..6839f8e996 100644
--- a/lib/pkix_asn1_tab.c
+++ b/lib/pkix_asn1_tab.c
@@ -2,17 +2,8 @@
#include "x509_asn1.h"
const static_asn pkix_asn1_tab[]={
- {"PKIX1Implicit88",536875024,0},
- {0,1610612748,0},
- {"iso",1073741825,"1"},
- {"identified-organization",1073741825,"3"},
- {"dod",1073741825,"6"},
- {"internet",1073741825,"1"},
- {"security",1073741825,"5"},
- {"mechanisms",1073741825,"5"},
- {"pkix",1073741825,"7"},
- {"id-mod",1073741825,"0"},
- {"id-pkix1-implicit-88",1,"2"},
+ {"PKIX1",536875024,0},
+ {0,1073741836,0},
{"id-ce",1879048204,0},
{"joint-iso-ccitt",1073741825,"2"},
{"ds",1073741825,"5"},
@@ -869,6 +860,42 @@ const static_asn pkix_asn1_tab[]={
{"ub-surname-length",1342177283,"40"},
{"ub-terminal-id-length",1342177283,"24"},
{"ub-unformatted-address-length",1342177283,"180"},
- {"ub-x121-address-length",268435459,"16"},
+ {"ub-x121-address-length",1342177283,"16"},
+ {"ContentInfo",1610612741,0},
+ {"contentType",1073741826,"ContentType"},
+ {"content",541073421,0},
+ {0,1073743880,"0"},
+ {"contentType",1,0},
+ {"ContentType",1073741836,0},
+ {"SignedData",1610612741,0},
+ {"version",1073741826,"CMSVersion"},
+ {"digestAlgorithms",1073741826,"DigestAlgorithmIdentifiers"},
+ {"encapContentInfo",1073741826,"EncapsulatedContentInfo"},
+ {"certificates",1610637314,"CertificateSet"},
+ {0,4104,"0"},
+ {"crls",1610637314,"CertificateRevocationLists"},
+ {0,4104,"1"},
+ {"signerInfos",2,"SignerInfos"},
+ {"CMSVersion",1610874883,0},
+ {"v0",1073741825,"0"},
+ {"v1",1073741825,"1"},
+ {"v2",1073741825,"2"},
+ {"v3",1073741825,"3"},
+ {"v4",1,"4"},
+ {"DigestAlgorithmIdentifiers",1610612751,0},
+ {0,2,"DigestAlgorithmIdentifier"},
+ {"DigestAlgorithmIdentifier",1073741826,"AlgorithmIdentifier"},
+ {"EncapsulatedContentInfo",1610612741,0},
+ {"eContentType",1073741826,"ContentType"},
+ {"eContent",536895495,0},
+ {0,2056,"0"},
+ {"CertificateRevocationLists",1610612751,0},
+ {0,2,"CertificateList"},
+ {"CertificateChoices",1610612754,0},
+ {"certificate",2,"Certificate"},
+ {"CertificateSet",1610612751,0},
+ {0,2,"CertificateChoices"},
+ {"SignerInfos",536870927,0},
+ {0,13,0},
{0,0,0}
};
diff --git a/lib/x509_asn1.c b/lib/x509_asn1.c
index 6784b2b783..cec909eecb 100755
--- a/lib/x509_asn1.c
+++ b/lib/x509_asn1.c
@@ -26,10 +26,10 @@
#include <gnutls_int.h>
+#include <gnutls_errors.h>
#include "x509_asn1.h"
#include "x509_der.h"
#include <gnutls_str.h>
-#include <gnutls_errors.h>
/* define used for visiting trees */
#define UP 1
@@ -938,7 +938,7 @@ _asn1_copy_structure2(node_asn *root,char *source_name)
* ASN_ELEMENT_NOT_FOUND\: SOURCE_NAME isn't known
*
* Example: using "pkix.asn"
- * result=asn1_create_structure(cert_def,"PKIX1Implicit88.Certificate",&cert,"certificate1");
+ * result=asn1_create_structure(cert_def,"PKIX1.Certificate",&cert,"certificate1");
**/
int
asn1_create_structure(node_asn *root,char *source_name,node_asn **pointer,char *dest_name)
diff --git a/lib/x509_extensions.c b/lib/x509_extensions.c
index 87e619f8a5..37d43ab2c7 100644
--- a/lib/x509_extensions.c
+++ b/lib/x509_extensions.c
@@ -41,7 +41,7 @@ static int _extract_keyUsage(uint16 *keyUsage, opaque * extnValue,
keyUsage[0] = 0;
if ((result=asn1_create_structure
- (_gnutls_get_pkix(), "PKIX1Implicit88.KeyUsage", &ext,
+ (_gnutls_get_pkix(), "PKIX1.KeyUsage", &ext,
"ku")) != ASN_OK) {
gnutls_assert();
return result;
@@ -80,7 +80,7 @@ static int _extract_basicConstraints(int *CA, opaque * extnValue,
*CA = 0;
if ((result=asn1_create_structure
- (_gnutls_get_pkix(), "PKIX1Implicit88.BasicConstraints", &ext,
+ (_gnutls_get_pkix(), "PKIX1.BasicConstraints", &ext,
"bc")) != ASN_OK) {
gnutls_assert();
return result;
@@ -268,7 +268,7 @@ int _gnutls_get_extension( const gnutls_datum * cert, const char* extension_id,
ret->size = 0;
if ((result=asn1_create_structure
- (_gnutls_get_pkix(), "PKIX1Implicit88.Certificate", &rasn,
+ (_gnutls_get_pkix(), "PKIX1.Certificate", &rasn,
"certificate2"))
!= ASN_OK) {
gnutls_assert();
diff --git a/lib/x509_sig_check.c b/lib/x509_sig_check.c
index 82547a5e3e..d6368855b9 100644
--- a/lib/x509_sig_check.c
+++ b/lib/x509_sig_check.c
@@ -42,7 +42,7 @@ opaque *str;
int result, len;
int start, end;
- if (asn1_create_structure( _gnutls_get_pkix(), "PKIX1Implicit88.Certificate", &c2, "certificate")!=ASN_OK) {
+ if (asn1_create_structure( _gnutls_get_pkix(), "PKIX1.Certificate", &c2, "certificate")!=ASN_OK) {
gnutls_assert();
return ret;
}
diff --git a/lib/x509_verify.c b/lib/x509_verify.c
index 5942e11bdb..d501c75874 100644
--- a/lib/x509_verify.c
+++ b/lib/x509_verify.c
@@ -206,7 +206,7 @@ int compare_dn(gnutls_cert * cert, gnutls_cert * issuer_cert)
/* get the issuer of 'cert'
*/
- if ((result=asn1_create_structure(_gnutls_get_pkix(), "PKIX1Implicit88.Certificate", &c2, "certificate2")) != ASN_OK) {
+ if ((result=asn1_create_structure(_gnutls_get_pkix(), "PKIX1.Certificate", &c2, "certificate2")) != ASN_OK) {
gnutls_assert();
return result;
}
@@ -223,7 +223,7 @@ int compare_dn(gnutls_cert * cert, gnutls_cert * issuer_cert)
/* get the 'subject' info of 'issuer_cert'
*/
- if ((result=asn1_create_structure(_gnutls_get_pkix(), "PKIX1Implicit88.Certificate", &c3, "certificate2")) != ASN_OK) {
+ if ((result=asn1_create_structure(_gnutls_get_pkix(), "PKIX1.Certificate", &c3, "certificate2")) != ASN_OK) {
gnutls_assert();
asn1_delete_structure(c2);
return result;
diff --git a/src/gnutls-http-serv b/src/gnutls-http-serv
index 82380eed99..2c002598d8 100755
--- a/src/gnutls-http-serv
+++ b/src/gnutls-http-serv
@@ -1,4 +1,4 @@
#! /bin/sh
-./gnutls-serv --http --x509certfile x509/cert.pem --x509keyfile x509/key.pem
+./gnutls-serv --http --x509certfile x509/cert.pem --x509keyfile x509/key.pem --cafile x509/ca.pem
diff --git a/src/serv.c b/src/serv.c
index 07c98819e9..2a604fdb9f 100644
--- a/src/serv.c
+++ b/src/serv.c
@@ -611,7 +611,7 @@ void gaa_parser(int argc, char **argv)
#else
x509_certfile = info.x509_certfile;
x509_keyfile = info.x509_keyfile;
- x509_cafile = info.x509_certfile;
+ x509_cafile = info.x509_cafile;
pgp_certfile = info.pgp_certfile;
pgp_keyfile = info.pgp_keyfile;
srp_passwd = info.srp_passwd;