summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikos Mavrogiannopoulos <nmav@gnutls.org>2003-03-22 11:42:50 +0000
committerNikos Mavrogiannopoulos <nmav@gnutls.org>2003-03-22 11:42:50 +0000
commit2f035aae4b0eb01794fc730d4064836d190e471d (patch)
tree723528d0bace2bdb36f693fd36678f05bebad6ba
parent130e6c0e53b96f50f1183b92e0f8dbe6255ff4fd (diff)
downloadgnutls-2f035aae4b0eb01794fc730d4064836d190e471d.tar.gz
* Added the new functions: gnutls_certificate_set_x509_key()
gnutls_certificate_set_x509_trust(), gnutls_certificate_set_x509_crl(), gnutls_x509_crt_export(), gnutls_x509_crl_export().
-rw-r--r--NEWS4
-rw-r--r--includes/gnutls/x509.h10
-rw-r--r--lib/gnutls.h.in.in24
-rw-r--r--lib/gnutls_cert.c58
-rw-r--r--lib/gnutls_cert.h2
-rw-r--r--lib/gnutls_x509.c248
-rw-r--r--lib/minitasn1/coding.c2
-rw-r--r--lib/pkix.asn4
-rw-r--r--lib/x509/crl.c76
-rw-r--r--lib/x509/x509.c80
-rw-r--r--lib/x509/x509.h6
11 files changed, 494 insertions, 20 deletions
diff --git a/NEWS b/NEWS
index cf222abcaf..afa744b6b7 100644
--- a/NEWS
+++ b/NEWS
@@ -14,6 +14,10 @@ Version 0.9.3
gnutls_handshake_get_last_out().
- The gnutls_certificate_set_rsa_params() was renamed to
gnutls_certificate_set_rsa_export_params().
+- Added the new functions: gnutls_certificate_set_x509_key()
+ gnutls_certificate_set_x509_trust(), gnutls_certificate_set_x509_crl(),
+ gnutls_x509_crt_export(), gnutls_x509_crl_export().
+
Version 0.9.2 (15/03/2003)
- Some corrections in the memory mapping code (file is unmapped after
diff --git a/includes/gnutls/x509.h b/includes/gnutls/x509.h
index 84a1c2e1bc..e45ecd3797 100644
--- a/includes/gnutls/x509.h
+++ b/includes/gnutls/x509.h
@@ -46,13 +46,13 @@ extern "C" {
/* Certificate handling functions */
-struct gnutls_x509_crt_int;
-typedef struct gnutls_x509_crt_int* gnutls_x509_crt;
int gnutls_x509_crt_init(gnutls_x509_crt * cert);
void gnutls_x509_crt_deinit(gnutls_x509_crt cert);
int gnutls_x509_crt_import(gnutls_x509_crt cert, const gnutls_datum * data,
gnutls_x509_crt_fmt format);
+int gnutls_x509_crt_export( gnutls_x509_crt cert,
+ gnutls_x509_crt_fmt format, unsigned char* output_data, int* output_data_size);
int gnutls_x509_crt_get_issuer_dn(gnutls_x509_crt cert, char *buf,
int *sizeof_buf);
int gnutls_x509_crt_get_issuer_dn_by_oid(gnutls_x509_crt cert,
@@ -107,14 +107,14 @@ int gnutls_x509_rdn_get_by_oid(const gnutls_datum * idn, const char* oid,
/* CRL handling functions */
-struct gnutls_x509_crl_int;
-typedef struct gnutls_x509_crl_int* gnutls_x509_crl;
int gnutls_x509_crl_init(gnutls_x509_crl * crl);
void gnutls_x509_crl_deinit(gnutls_x509_crl crl);
int gnutls_x509_crl_import(gnutls_x509_crl crl, const gnutls_datum * data,
gnutls_x509_crt_fmt format);
+int gnutls_x509_crl_export( gnutls_x509_crl crl,
+ gnutls_x509_crt_fmt format, unsigned char* output_data, int* output_data_size);
int gnutls_x509_crl_get_issuer_dn(const gnutls_x509_crl crl,
char *buf, int *sizeof_buf);
@@ -191,8 +191,6 @@ int gnutls_x509_crt_get_fingerprint(gnutls_x509_crt cert,
/* Private key handling
*/
-struct gnutls_x509_privkey_int;
-typedef struct gnutls_x509_privkey_int* gnutls_x509_privkey;
int gnutls_x509_privkey_init(gnutls_x509_privkey * key);
void gnutls_x509_privkey_deinit(gnutls_x509_privkey key);
diff --git a/lib/gnutls.h.in.in b/lib/gnutls.h.in.in
index 8bde272900..348ee1cdd7 100644
--- a/lib/gnutls.h.in.in
+++ b/lib/gnutls.h.in.in
@@ -314,11 +314,14 @@ void gnutls_certificate_free_credentials( gnutls_certificate_credentials sc);
int gnutls_certificate_allocate_credentials( gnutls_certificate_credentials *sc);
void gnutls_certificate_free_keys(gnutls_certificate_credentials sc);
+void gnutls_certificate_free_cas(gnutls_certificate_credentials sc);
+void gnutls_certificate_free_crls(gnutls_certificate_credentials sc);
void gnutls_certificate_set_dh_params(gnutls_certificate_credentials res, gnutls_dh_params);
void gnutls_certificate_set_rsa_export_params(gnutls_certificate_credentials res, gnutls_rsa_params rsa_params);
void gnutls_certificate_set_verify_flags(gnutls_certificate_credentials res, unsigned int flags);
+
int gnutls_certificate_set_x509_trust_file( gnutls_certificate_credentials res, const char* CAFILE,
gnutls_x509_crt_fmt);
int gnutls_certificate_set_x509_trust_mem(gnutls_certificate_credentials res,
@@ -335,6 +338,27 @@ int gnutls_certificate_set_x509_key_mem(gnutls_certificate_credentials res,
const gnutls_datum* CERT, const gnutls_datum* KEY,
gnutls_x509_crt_fmt);
+
+/* New functions to allow setting already parsed X.509 stuff.
+ */
+struct gnutls_x509_privkey_int;
+typedef struct gnutls_x509_privkey_int* gnutls_x509_privkey;
+
+struct gnutls_x509_crl_int;
+typedef struct gnutls_x509_crl_int* gnutls_x509_crl;
+
+struct gnutls_x509_crt_int;
+typedef struct gnutls_x509_crt_int* gnutls_x509_crt;
+
+int gnutls_certificate_set_x509_key(gnutls_certificate_credentials res,
+ gnutls_x509_crt *cert_list, int cert_list_size,
+ gnutls_x509_privkey key);
+int gnutls_certificate_set_x509_trust(gnutls_certificate_credentials res,
+ gnutls_x509_crt * ca_list, int ca_list_size);
+int gnutls_certificate_set_x509_crl(gnutls_certificate_credentials res,
+ gnutls_x509_crl* crl_list, int crl_list_size);
+
+
/* global state functions
*/
int gnutls_global_init(void);
diff --git a/lib/gnutls_cert.c b/lib/gnutls_cert.c
index dfa9c17573..24406fbbd4 100644
--- a/lib/gnutls_cert.c
+++ b/lib/gnutls_cert.c
@@ -493,6 +493,64 @@ int _gnutls_x509_cert2gnutls_cert(gnutls_cert * gcert, const gnutls_datum *derCe
}
+/* Like above but it accepts a parsed certificate instead.
+ */
+int _gnutls_x509_crt2gnutls_cert(gnutls_cert * gcert, gnutls_x509_crt cert,
+ unsigned int flags)
+{
+ int ret = 0;
+
+ memset(gcert, 0, sizeof(gnutls_cert));
+ gcert->cert_type = GNUTLS_CRT_X509;
+
+ if ( !(flags & CERT_NO_COPY)) {
+ opaque* der;
+ int der_size = 0;
+
+ ret = gnutls_x509_crt_export( cert, GNUTLS_X509_FMT_DER, NULL, &der_size);
+ if (ret != GNUTLS_E_SHORT_MEMORY_BUFFER) {
+ gnutls_assert();
+ return ret;
+ }
+
+ der = gnutls_malloc( der_size);
+ if (der == NULL) {
+ gnutls_assert();
+ return GNUTLS_E_MEMORY_ERROR;
+ }
+
+ ret = gnutls_x509_crt_export( cert, GNUTLS_X509_FMT_DER, der, &der_size);
+ if (ret < 0) {
+ gnutls_assert();
+ return ret;
+ }
+
+ gcert->raw.data = der;
+ gcert->raw.size = der_size;
+ } else
+ /* now we have 0 or a bitwise or of things to decode */
+ flags ^= CERT_NO_COPY;
+
+
+ if (flags & CERT_ONLY_EXTENSIONS || flags == 0) {
+ gnutls_x509_crt_get_key_usage( cert, &gcert->keyUsage, NULL);
+ gcert->version = gnutls_x509_crt_get_version( cert);
+ }
+ gcert->subject_pk_algorithm = gnutls_x509_crt_get_pk_algorithm( cert, NULL);
+
+ if (flags & CERT_ONLY_PUBKEY || flags == 0) {
+ gcert->params_size = MAX_PUBLIC_PARAMS_SIZE;
+ ret = _gnutls_x509_crt_get_mpis( cert, gcert->params, &gcert->params_size);
+ if (ret < 0) {
+ gnutls_assert();
+ return ret;
+ }
+ }
+
+ return 0;
+
+}
+
void _gnutls_free_cert(gnutls_cert *cert)
{
int i;
diff --git a/lib/gnutls_cert.h b/lib/gnutls_cert.h
index 44ac3ce0af..c0e69cbea1 100644
--- a/lib/gnutls_cert.h
+++ b/lib/gnutls_cert.h
@@ -83,6 +83,8 @@ typedef enum ConvFlags {
int _gnutls_x509_cert2gnutls_cert(gnutls_cert * gcert, const gnutls_datum *derCert,
int flags);
+int _gnutls_x509_crt2gnutls_cert(gnutls_cert * gcert, gnutls_x509_crt cert,
+ unsigned int flags);
void _gnutls_free_cert(gnutls_cert* cert);
int _gnutls_cert_get_dn(gnutls_cert * cert, gnutls_datum * odn);
diff --git a/lib/gnutls_x509.c b/lib/gnutls_x509.c
index 3186b76785..b476b0e656 100644
--- a/lib/gnutls_x509.c
+++ b/lib/gnutls_x509.c
@@ -162,17 +162,14 @@ uint pk = res->cert_list[res->ncerts-1][0].subject_pk_algorithm;
return 0;
}
-#define MAX_FILE_SIZE 100*1024
-
/* Reads a DER encoded certificate list from memory and stores it to
* a gnutls_cert structure. This is only called if PKCS7 read fails.
* returns the number of certificates parsed (1)
*/
-static int parse_der_cert_mem( gnutls_cert** cert_list, int* ncerts,
- const char *input_cert, int input_cert_size)
+static int parse_crt_mem( gnutls_cert** cert_list, int* ncerts,
+ gnutls_x509_crt cert)
{
int i;
- gnutls_datum tmp;
int ret;
i = *ncerts + 1;
@@ -187,11 +184,8 @@ static int parse_der_cert_mem( gnutls_cert** cert_list, int* ncerts,
return GNUTLS_E_MEMORY_ERROR;
}
- tmp.data = (opaque*)input_cert;
- tmp.size = input_cert_size;
-
- ret = _gnutls_x509_cert2gnutls_cert(
- &cert_list[0][i - 1], &tmp, 0);
+ ret = _gnutls_x509_crt2gnutls_cert(
+ &cert_list[0][i-1], cert, 0);
if ( ret < 0) {
gnutls_assert();
return ret;
@@ -202,6 +196,39 @@ static int parse_der_cert_mem( gnutls_cert** cert_list, int* ncerts,
return 1; /* one certificate parsed */
}
+/* Reads a DER encoded certificate list from memory and stores it to
+ * a gnutls_cert structure. This is only called if PKCS7 read fails.
+ * returns the number of certificates parsed (1)
+ */
+static int parse_der_cert_mem( gnutls_cert** cert_list, int* ncerts,
+ const char *input_cert, int input_cert_size)
+{
+ gnutls_datum tmp;
+ gnutls_x509_crt cert;
+ int ret;
+
+ ret = gnutls_x509_crt_init( &cert);
+ if ( ret < 0) {
+ gnutls_assert();
+ return ret;
+ }
+
+ tmp.data = (opaque*)input_cert;
+ tmp.size = input_cert_size;
+
+ ret = gnutls_x509_crt_import( cert, &tmp, GNUTLS_X509_FMT_DER);
+ if ( ret < 0) {
+ gnutls_assert();
+ gnutls_x509_crt_deinit( cert);
+ return ret;
+ }
+
+ ret = parse_crt_mem( cert_list, ncerts, cert);
+ gnutls_x509_crt_deinit( cert);
+
+ return ret;
+}
+
#define CERT_PEM 1
/* Reads a PKCS7 base64 encoded certificate list from memory and stores it to
@@ -511,7 +538,13 @@ static int read_key_mem(gnutls_certificate_credentials res, const char *key, int
return ret;
}
- privkey_cpy( &res->pkey[res->ncerts], tmpkey);
+ ret = privkey_cpy( &res->pkey[res->ncerts], tmpkey);
+ if (ret < 0) {
+ gnutls_assert();
+ gnutls_x509_privkey_deinit( tmpkey);
+
+ return ret;
+ }
gnutls_x509_privkey_deinit( tmpkey);
@@ -704,6 +737,50 @@ void gnutls_certificate_free_keys(gnutls_certificate_credentials sc)
}
/**
+ * gnutls_certificate_free_cas - Used to free all the CAs from a gnutls_certificate_credentials structure
+ * @sc: is an &gnutls_certificate_credentials structure.
+ *
+ * This function will delete all the CAs associated
+ * with the given credentials.
+ *
+ **/
+void gnutls_certificate_free_cas(gnutls_certificate_credentials sc)
+{
+ uint j;
+
+ for (j = 0; j < sc->x509_ncas; j++) {
+ gnutls_x509_crt_deinit( sc->x509_ca_list[j]);
+ }
+
+ sc->x509_ncas = 0;
+
+ gnutls_free( sc->x509_ca_list);
+ sc->x509_ca_list = NULL;
+}
+
+/**
+ * gnutls_certificate_free_crls - Used to free all the CRLs from a gnutls_certificate_credentials structure
+ * @sc: is an &gnutls_certificate_credentials structure.
+ *
+ * This function will delete all the CRLs associated
+ * with the given credentials.
+ *
+ **/
+void gnutls_certificate_free_crls(gnutls_certificate_credentials sc)
+{
+ uint j;
+
+ for (j = 0; j < sc->x509_ncrls; j++) {
+ gnutls_x509_crl_deinit( sc->x509_crl_list[j]);
+ }
+
+ sc->x509_ncrls = 0;
+
+ gnutls_free( sc->x509_crl_list);
+ sc->x509_crl_list = NULL;
+}
+
+/**
* gnutls_certificate_set_x509_key_mem - Used to set keys in a gnutls_certificate_credentials structure
* @res: is an &gnutls_certificate_credentials structure.
* @CERT: contains a certificate list (path) for the specified private key
@@ -742,6 +819,78 @@ int gnutls_certificate_set_x509_key_mem(gnutls_certificate_credentials res, cons
if ((ret = read_cert_mem( res, CERT->data, CERT->size, type)) < 0)
return ret;
+ res->ncerts++;
+
+ if ((ret=_gnutls_check_key_cert_match( res)) < 0) {
+ gnutls_assert();
+ return ret;
+ }
+
+ return 0;
+}
+
+/**
+ * gnutls_certificate_set_x509_key - Used to set keys in a gnutls_certificate_credentials structure
+ * @res: is an &gnutls_certificate_credentials structure.
+ * @cert_list: contains a certificate list (path) for the specified private key
+ * @cert_list_size: holds the size of the certificate list
+ * @key: is a gnutls_x509_privkey key
+ *
+ * This function sets a certificate/private key pair in the
+ * gnutls_certificate_credentials structure. This function may be called
+ * more than once (in case multiple keys/certificates exist for the
+ * server).
+ *
+ **/
+int gnutls_certificate_set_x509_key(gnutls_certificate_credentials res,
+ gnutls_x509_crt *cert_list, int cert_list_size,
+ gnutls_x509_privkey key)
+{
+ int ret, i;
+
+ /* this should be first
+ */
+
+ res->pkey = gnutls_realloc_fast( res->pkey, (res->ncerts+1)*sizeof(gnutls_privkey));
+ if (res->pkey==NULL) {
+ gnutls_assert();
+ return GNUTLS_E_MEMORY_ERROR;
+ }
+
+ ret = privkey_cpy( &res->pkey[res->ncerts], key);
+ if (ret < 0) {
+ gnutls_assert();
+ return ret;
+ }
+
+ res->cert_list = gnutls_realloc_fast( res->cert_list,
+ (1+ res->ncerts)*sizeof(gnutls_cert*));
+ if ( res->cert_list==NULL) {
+ gnutls_assert();
+ return GNUTLS_E_MEMORY_ERROR;
+ }
+
+ res->cert_list_length = gnutls_realloc_fast( res->cert_list_length,
+ (1+ res->ncerts)*sizeof(int));
+ if (res->cert_list_length==NULL) {
+ gnutls_assert();
+ return GNUTLS_E_MEMORY_ERROR;
+ }
+
+ res->cert_list[res->ncerts] = NULL; /* for realloc */
+ res->cert_list_length[res->ncerts] = 0;
+
+
+ for (i=0;i<cert_list_size;i++) {
+ ret = parse_crt_mem( &res->cert_list[res->ncerts],
+ &res->cert_list_length[res->ncerts], cert_list[i]);
+ if ( ret < 0) {
+ gnutls_assert();
+ return ret;
+ }
+ }
+ res->ncerts++;
+
if ((ret=_gnutls_check_key_cert_match( res)) < 0) {
gnutls_assert();
return ret;
@@ -1062,6 +1211,48 @@ int gnutls_certificate_set_x509_trust_mem(gnutls_certificate_credentials res,
}
/**
+ * gnutls_certificate_set_x509_trust - Used to add trusted CAs in a gnutls_certificate_credentials structure
+ * @res: is an &gnutls_certificate_credentials structure.
+ * @ca_list: is a list of trusted CAs
+ * @ca_list_size: holds the size of the CA list
+ *
+ * This function adds the trusted CAs in order to verify client
+ * certificates. This function may be called multiple times.
+ *
+ * In case of a server the CAs set here will be sent to the client
+ * if a certificate request is sent. This can be disabled using
+ * gnutls_certificate_send_x509_rdn_sequence().
+ *
+ **/
+int gnutls_certificate_set_x509_trust(gnutls_certificate_credentials res,
+ gnutls_x509_crt * ca_list, int ca_list_size)
+{
+ int ret, i, ret2;
+
+ res->x509_ca_list = gnutls_realloc_fast( res->x509_ca_list,
+ (ca_list_size + res->x509_ncas)*sizeof(gnutls_x509_crt));
+ if ( res->x509_ca_list==NULL) {
+ gnutls_assert();
+ return GNUTLS_E_MEMORY_ERROR;
+ }
+
+ for (i=0;i<ca_list_size;i++) {
+ ret = _gnutls_x509_crt_cpy( res->x509_ca_list[i+res->x509_ncas],
+ ca_list[i]);
+ if ( ret < 0) {
+ gnutls_assert();
+ return ret;
+ }
+ res->x509_ncas++;
+ }
+
+ if ((ret2 = generate_rdn_seq(res)) < 0)
+ return ret2;
+
+ return 0;
+}
+
+/**
* gnutls_certificate_set_x509_trust_file - Used to add trusted CAs in a gnutls_certificate_credentials structure
* @res: is an &gnutls_certificate_credentials structure.
* @cafile: is a file containing the list of trusted CAs (DER or PEM list)
@@ -1278,6 +1469,41 @@ int gnutls_certificate_set_x509_crl_mem(gnutls_certificate_credentials res,
}
/**
+ * gnutls_certificate_set_x509_crl - Used to add CRLs in a gnutls_certificate_credentials structure
+ * @res: is an &gnutls_certificate_credentials structure.
+ * @crl_list: is a list of trusted CRLs. They should have been verified before.
+ * @crl_list_size: holds the size of the crl_list
+ *
+ * This function adds the trusted CRLs in order to verify client or server
+ * certificates. This function may be called multiple times.
+ *
+ **/
+int gnutls_certificate_set_x509_crl(gnutls_certificate_credentials res,
+ gnutls_x509_crl* crl_list, int crl_list_size)
+{
+ int ret, i;
+
+ res->x509_crl_list = gnutls_realloc_fast( res->x509_crl_list,
+ (crl_list_size + res->x509_ncrls)*sizeof(gnutls_x509_crl));
+ if ( res->x509_crl_list==NULL) {
+ gnutls_assert();
+ return GNUTLS_E_MEMORY_ERROR;
+ }
+
+ for (i=0;i<crl_list_size;i++) {
+ ret = _gnutls_x509_crl_cpy( res->x509_crl_list[i+res->x509_ncrls],
+ crl_list[i]);
+ if ( ret < 0) {
+ gnutls_assert();
+ return ret;
+ }
+ res->x509_ncrls++;
+ }
+
+ return 0;
+}
+
+/**
* gnutls_certificate_set_x509_crl_file - Used to add CRLs in a gnutls_certificate_credentials structure
* @res: is an &gnutls_certificate_credentials structure.
* @crlfile: is a file containing the list of verified CRLs (DER or PEM list)
diff --git a/lib/minitasn1/coding.c b/lib/minitasn1/coding.c
index a4e307f2d1..8add4692cc 100644
--- a/lib/minitasn1/coding.c
+++ b/lib/minitasn1/coding.c
@@ -783,6 +783,8 @@ asn1_der_coding(ASN1_TYPE element,const char *name,unsigned char *der,int *len,
if(p->value[0]=='F') der[counter++]=0;
else der[counter++]=0xFF;
}
+ else
+ counter+=2;
}
move=RIGHT;
break;
diff --git a/lib/pkix.asn b/lib/pkix.asn
index 626224ca3b..a175d1c794 100644
--- a/lib/pkix.asn
+++ b/lib/pkix.asn
@@ -1058,8 +1058,10 @@ pkcs-5-PBES2-params ::= SEQUENCE {
pkcs-5-id-PBKDF2 OBJECT IDENTIFIER ::= {pkcs-5 12}
+-- pkcs-5-id-hmacWithSHA1 OBJECT IDENTIFIER ::= {iso(1) member-body(2) us(840) rsadsi(113549) 2 7}
+
-- pkcs-5-algid-hmacWithSHA1 AlgorithmIdentifier ::=
--- {algorithm pkcs-5-id-hmacWithSHA1, parameters NULL : NULL}
+-- {algorithm pkcs-5-id-hmacWithSHA1, parameters NULL : NULL}
pkcs-5-PBKDF2-params ::= SEQUENCE {
salt CHOICE {
diff --git a/lib/x509/crl.c b/lib/x509/crl.c
index 436f3832a7..56d9fe2238 100644
--- a/lib/x509/crl.c
+++ b/lib/x509/crl.c
@@ -487,3 +487,79 @@ int _gnutls_x509_crl_get_raw_issuer_dn(gnutls_x509_crl crl,
}
+/**
+ * gnutls_x509_crl_export - This function will export the CRL
+ * @crl: Holds the revocation list
+ * @format: the format of output params. One of PEM or DER.
+ * @output_data: will contain a private key PEM or DER encoded
+ * @output_data_size: holds the size of output_data (and will be replaced by the actual size of parameters)
+ *
+ * This function will export the revocation list to DER or PEM format.
+ *
+ * If the buffer provided is not long enough to hold the output, then
+ * GNUTLS_E_SHORT_MEMORY_BUFFER will be returned.
+ *
+ * If the structure is PEM encoded, it will have a header
+ * of "BEGIN X509 CRL".
+ *
+ * In case of failure a negative value will be returned, and
+ * 0 on success.
+ *
+ **/
+int gnutls_x509_crl_export( gnutls_x509_crl crl,
+ gnutls_x509_crt_fmt format, unsigned char* output_data, int* output_data_size)
+{
+ return _gnutls_x509_export_int( crl->crl, format, PEM_CRL, *output_data_size,
+ output_data, output_data_size);
+}
+
+/*-
+ * _gnutls_x509_crl_cpy - This function copies a gnutls_x509_crl structure
+ * @dest: The structure where to copy
+ * @src: The structure to be copied
+ *
+ * This function will copy an X.509 certificate structure.
+ *
+ * Returns 0 on success.
+ *
+ -*/
+int _gnutls_x509_crl_cpy(gnutls_x509_crl dest, gnutls_x509_crl src)
+{
+int ret;
+int der_size;
+opaque * der;
+gnutls_datum tmp;
+
+ ret = gnutls_x509_crl_export( src, GNUTLS_X509_FMT_DER, NULL, &der_size);
+ if (ret != GNUTLS_E_SHORT_MEMORY_BUFFER) {
+ gnutls_assert();
+ return ret;
+ }
+
+ der = gnutls_alloca( der_size);
+ if (der == NULL) {
+ gnutls_assert();
+ return GNUTLS_E_MEMORY_ERROR;
+ }
+
+ ret = gnutls_x509_crl_export( src, GNUTLS_X509_FMT_DER, der, &der_size);
+ if (ret < 0) {
+ gnutls_assert();
+ gnutls_afree( der);
+ return ret;
+ }
+
+ tmp.data = der;
+ tmp.size = der_size;
+ ret = gnutls_x509_crl_import( dest, &tmp, GNUTLS_X509_FMT_DER);
+
+ gnutls_afree( der);
+
+ if (ret < 0) {
+ gnutls_assert();
+ return ret;
+ }
+
+ return 0;
+
+}
diff --git a/lib/x509/x509.c b/lib/x509/x509.c
index 39daebe038..74be296acc 100644
--- a/lib/x509/x509.c
+++ b/lib/x509/x509.c
@@ -36,7 +36,7 @@
#include <gnutls_ui.h>
/**
- * gnutls_x509_crt_init - This function initializes a gnutls_crl structure
+ * gnutls_x509_crt_init - This function initializes a gnutls_x509_crt structure
* @cert: The structure to be initialized
*
* This function will initialize an X.509 certificate structure.
@@ -61,6 +61,57 @@ int gnutls_x509_crt_init(gnutls_x509_crt * cert)
return GNUTLS_E_MEMORY_ERROR;
}
+/*-
+ * _gnutls_x509_crt_cpy - This function copies a gnutls_x509_crt structure
+ * @dest: The structure where to copy
+ * @src: The structure to be copied
+ *
+ * This function will copy an X.509 certificate structure.
+ *
+ * Returns 0 on success.
+ *
+ -*/
+int _gnutls_x509_crt_cpy(gnutls_x509_crt dest, gnutls_x509_crt src)
+{
+int ret;
+int der_size;
+opaque * der;
+gnutls_datum tmp;
+
+ ret = gnutls_x509_crt_export( src, GNUTLS_X509_FMT_DER, NULL, &der_size);
+ if (ret != GNUTLS_E_SHORT_MEMORY_BUFFER) {
+ gnutls_assert();
+ return ret;
+ }
+
+ der = gnutls_alloca( der_size);
+ if (der == NULL) {
+ gnutls_assert();
+ return GNUTLS_E_MEMORY_ERROR;
+ }
+
+ ret = gnutls_x509_crt_export( src, GNUTLS_X509_FMT_DER, der, &der_size);
+ if (ret < 0) {
+ gnutls_assert();
+ gnutls_afree( der);
+ return ret;
+ }
+
+ tmp.data = der;
+ tmp.size = der_size;
+ ret = gnutls_x509_crt_import( dest, &tmp, GNUTLS_X509_FMT_DER);
+
+ gnutls_afree( der);
+
+ if (ret < 0) {
+ gnutls_assert();
+ return ret;
+ }
+
+ return 0;
+
+}
+
/**
* gnutls_x509_crt_deinit - This function deinitializes memory used by a gnutls_x509_crt structure
* @cert: The structure to be initialized
@@ -1005,7 +1056,6 @@ gnutls_datum tmp;
return _gnutls_asn2err(result);
}
- tmp.data = cert_buf;
tmp.size = cert_buf_size;
result = gnutls_fingerprint( algo, &tmp, buf, sizeof_buf);
@@ -1014,6 +1064,32 @@ gnutls_datum tmp;
return result;
}
+/**
+ * gnutls_x509_crt_export - This function will export the certificate
+ * @cert: Holds the certificate
+ * @format: the format of output params. One of PEM or DER.
+ * @output_data: will contain a private key PEM or DER encoded
+ * @output_data_size: holds the size of output_data (and will be replaced by the actual size of parameters)
+ *
+ * This function will export the certificate to DER or PEM format.
+ *
+ * If the buffer provided is not long enough to hold the output, then
+ * GNUTLS_E_SHORT_MEMORY_BUFFER will be returned.
+ *
+ * If the structure is PEM encoded, it will have a header
+ * of "BEGIN CERTIFICATE".
+ *
+ * In case of failure a negative value will be returned, and
+ * 0 on success.
+ *
+ **/
+int gnutls_x509_crt_export( gnutls_x509_crt cert,
+ gnutls_x509_crt_fmt format, unsigned char* output_data, int* output_data_size)
+{
+ return _gnutls_x509_export_int( cert->cert, format, "CERTIFICATE", *output_data_size,
+ output_data, output_data_size);
+}
+
/* A generic export function. Will export the given ASN.1 encoded data
* to PEM or DER raw data.
diff --git a/lib/x509/x509.h b/lib/x509/x509.h
index 3659db09d5..b1f5d07975 100644
--- a/lib/x509/x509.h
+++ b/lib/x509/x509.h
@@ -77,6 +77,7 @@ int gnutls_x509_crt_get_dn_by_oid(gnutls_x509_crt cert, const char* oid,
int gnutls_x509_crt_get_ca_status(gnutls_x509_crt cert, int* critical);
int gnutls_x509_crt_get_pk_algorithm( gnutls_x509_crt cert, int* bits);
+int _gnutls_x509_crt_cpy(gnutls_x509_crt dest, gnutls_x509_crt src);
int _gnutls_x509_crt_get_raw_issuer_dn( gnutls_x509_crt cert,
gnutls_const_datum* start);
int _gnutls_x509_crt_get_raw_dn( gnutls_x509_crt cert,
@@ -90,6 +91,7 @@ int _gnutls_x509_compare_raw_dn(const gnutls_const_datum * dn1,
int gnutls_x509_crt_check_revocation(gnutls_x509_crt cert, gnutls_x509_crl * crl_list, int crl_list_length);
+int _gnutls_x509_crl_cpy(gnutls_x509_crl dest, gnutls_x509_crl src);
int _gnutls_x509_crl_get_raw_issuer_dn( gnutls_x509_crl crl,
gnutls_const_datum* dn);
int gnutls_x509_crl_get_certificate_count(gnutls_x509_crl crl);
@@ -101,11 +103,15 @@ void gnutls_x509_crl_deinit(gnutls_x509_crl crl);
int gnutls_x509_crl_init(gnutls_x509_crl * crl);
int gnutls_x509_crl_import(gnutls_x509_crl crl, const gnutls_datum * data,
gnutls_x509_crt_fmt format);
+int gnutls_x509_crl_export( gnutls_x509_crl crl,
+ gnutls_x509_crt_fmt format, unsigned char* output_data, int* output_data_size);
int gnutls_x509_crt_init(gnutls_x509_crt * cert);
void gnutls_x509_crt_deinit(gnutls_x509_crt cert);
int gnutls_x509_crt_import(gnutls_x509_crt cert, const gnutls_datum * data,
gnutls_x509_crt_fmt format);
+int gnutls_x509_crt_export( gnutls_x509_crt cert,
+ gnutls_x509_crt_fmt format, unsigned char* output_data, int* output_data_size);
int gnutls_x509_crt_get_key_usage(gnutls_x509_crt cert, unsigned int *key_usage,
int *critical);