diff options
author | Nikos Mavrogiannopoulos <nmav@gnutls.org> | 2003-03-22 11:42:50 +0000 |
---|---|---|
committer | Nikos Mavrogiannopoulos <nmav@gnutls.org> | 2003-03-22 11:42:50 +0000 |
commit | 2f035aae4b0eb01794fc730d4064836d190e471d (patch) | |
tree | 723528d0bace2bdb36f693fd36678f05bebad6ba | |
parent | 130e6c0e53b96f50f1183b92e0f8dbe6255ff4fd (diff) | |
download | gnutls-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-- | NEWS | 4 | ||||
-rw-r--r-- | includes/gnutls/x509.h | 10 | ||||
-rw-r--r-- | lib/gnutls.h.in.in | 24 | ||||
-rw-r--r-- | lib/gnutls_cert.c | 58 | ||||
-rw-r--r-- | lib/gnutls_cert.h | 2 | ||||
-rw-r--r-- | lib/gnutls_x509.c | 248 | ||||
-rw-r--r-- | lib/minitasn1/coding.c | 2 | ||||
-rw-r--r-- | lib/pkix.asn | 4 | ||||
-rw-r--r-- | lib/x509/crl.c | 76 | ||||
-rw-r--r-- | lib/x509/x509.c | 80 | ||||
-rw-r--r-- | lib/x509/x509.h | 6 |
11 files changed, 494 insertions, 20 deletions
@@ -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); |