diff options
author | Nikos Mavrogiannopoulos <nmav@gnutls.org> | 2003-10-23 19:16:16 +0000 |
---|---|---|
committer | Nikos Mavrogiannopoulos <nmav@gnutls.org> | 2003-10-23 19:16:16 +0000 |
commit | 98303f5328dce05ca179aaa05a5c09e40e69189d (patch) | |
tree | 7b05613599f744803567f3a7e67da5c66c0e206b | |
parent | 0b63f1a2b945ddf1d64cadc422af031f1509cc96 (diff) | |
download | gnutls-98303f5328dce05ca179aaa05a5c09e40e69189d.tar.gz |
Added some support for writable gnutls_x509_crt structures. Not ready yet.
-rw-r--r-- | NEWS | 3 | ||||
-rw-r--r-- | THANKS | 2 | ||||
-rw-r--r-- | configure.in | 2 | ||||
-rw-r--r-- | includes/gnutls/x509.h | 26 | ||||
-rw-r--r-- | lib/Makefile.am | 2 | ||||
-rw-r--r-- | lib/pkix.asn | 21 | ||||
-rw-r--r-- | lib/pkix_asn1_tab.c | 20 | ||||
-rw-r--r-- | lib/x509/Makefile.am | 2 | ||||
-rw-r--r-- | lib/x509/common.c | 257 | ||||
-rw-r--r-- | lib/x509/common.h | 9 | ||||
-rw-r--r-- | lib/x509/crq.c | 116 | ||||
-rw-r--r-- | lib/x509/crq.h | 6 | ||||
-rw-r--r-- | lib/x509/dn.c | 90 | ||||
-rw-r--r-- | lib/x509/dn.h | 2 | ||||
-rw-r--r-- | lib/x509/extensions.c | 84 | ||||
-rw-r--r-- | lib/x509/extensions.h | 4 | ||||
-rw-r--r-- | lib/x509/x509.c | 92 | ||||
-rw-r--r-- | lib/x509/x509_write.c | 391 | ||||
-rw-r--r-- | libgcrypt.m4 | 199 |
19 files changed, 1004 insertions, 324 deletions
@@ -1,3 +1,6 @@ +Version 0.9.92 +- The RFC2818 hostname verification is now case insensitive. + Version 0.9.91 (17/10/2003) - Fixed a compilation issue in the openpgp authentication part. @@ -15,3 +15,5 @@ Jeff Johnson <jbj@redhat.com> David Taylor <dtaylo11@bigpond.net.au> Ivo Timmermans <ivo@o2w.nl> Ian Peters <itp@ximian.com> +Arne Thomassen <arne@arne-thomassen.de> +Casey Marshall <rsdio@metastatic.org> diff --git a/configure.in b/configure.in index b64c9d4af1..72984f3a2d 100644 --- a/configure.in +++ b/configure.in @@ -158,7 +158,7 @@ AC_HEADER_TIME AC_CHECK_HEADERS(unistd.h strings.h stddef.h alloca.h) AC_CHECK_HEADERS(sys/stat.h sys/types.h sys/socket.h) AC_CHECK_HEADERS(errno.h sys/time.h time.h) -AC_CHECK_FUNCS(memmove strnstr mmap,,) +AC_CHECK_FUNCS(memmove strnstr mmap gmtime_r,,) AC_FUNC_ALLOCA diff --git a/includes/gnutls/x509.h b/includes/gnutls/x509.h index fc9ecd7080..425e6b96a0 100644 --- a/includes/gnutls/x509.h +++ b/includes/gnutls/x509.h @@ -105,7 +105,26 @@ int gnutls_x509_crt_to_xml(gnutls_x509_crt cert, gnutls_datum* res, int detail); #define GNUTLS_XML_SHOW_ALL 1 #define GNUTLS_XML_NORMAL 0 -/* RDN handling */ +/* X.509 Certificate writing. + */ +int gnutls_x509_crt_set_dn_by_oid(gnutls_x509_crt crt, const char* oid, + const char *name, unsigned int sizeof_name); +int gnutls_x509_crt_set_issuer_dn_by_oid(gnutls_x509_crt crt, const char* oid, + const char *name, unsigned int sizeof_name); +int gnutls_x509_crt_set_version(gnutls_x509_crt crt, unsigned int version); +int gnutls_x509_crt_set_key(gnutls_x509_crt crt, gnutls_x509_privkey key); +int gnutls_x509_crt_set_ca_status(gnutls_x509_crt crt, unsigned int ca); +int gnutls_x509_crt_sign(gnutls_x509_crt crt, gnutls_x509_crt issuer, + gnutls_x509_privkey issuer_key); +int gnutls_x509_crt_set_activation_time(gnutls_x509_crt cert, time_t act_time); +int gnutls_x509_crt_set_expiration_time(gnutls_x509_crt cert, time_t exp_time); +int gnutls_x509_crt_set_serial(gnutls_x509_crt cert, const unsigned char* serial, + size_t serial_size); +int gnutls_x509_crt_set_crq(gnutls_x509_crt crt, gnutls_x509_crq crq); + + +/* RDN handling + */ int gnutls_x509_rdn_get(const gnutls_datum * idn, char *buf, size_t *sizeof_buf); @@ -256,13 +275,14 @@ int gnutls_x509_crq_init(gnutls_x509_crq * crq); void gnutls_x509_crq_deinit(gnutls_x509_crq crq); int gnutls_x509_crq_import(gnutls_x509_crq crq, const gnutls_datum * data, gnutls_x509_crt_fmt format); +int gnutls_x509_crq_get_pk_algorithm( gnutls_x509_crq crq, unsigned int* bits); int gnutls_x509_crq_get_dn(gnutls_x509_crq crq, char *buf, size_t *sizeof_buf); int gnutls_x509_crq_get_dn_by_oid(gnutls_x509_crq crq, const char* oid, int indx, char *buf, size_t *sizeof_buf); int gnutls_x509_crq_set_dn_by_oid(gnutls_x509_crq crq, const char* oid, - const char *name, int sizeof_name); -int gnutls_x509_crq_set_version(gnutls_x509_crq crq, int version); + const char *name, unsigned int sizeof_name); +int gnutls_x509_crq_set_version(gnutls_x509_crq crq, unsigned int version); int gnutls_x509_crq_set_key(gnutls_x509_crq crq, gnutls_x509_privkey key); int gnutls_x509_crq_sign(gnutls_x509_crq crq, gnutls_x509_privkey key); diff --git a/lib/Makefile.am b/lib/Makefile.am index 06beae66c9..1e31ad4034 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -56,7 +56,7 @@ libgnutls_la_LIBADD = $(MINITASN1_OBJECTS) x509/dn.lo x509/crl.lo x509/common.lo x509/x509.lo x509/extensions.lo x509/compat.lo x509/verify.lo \ x509/mpi.lo x509/privkey.lo x509/pkcs7.lo x509/crq.lo x509/xml.lo x509/sign.lo \ x509/pkcs5.lo x509/privkey_pkcs8.lo x509/pkcs12.lo x509/pkcs12_bag.lo \ - x509/pkcs12_encr.lo x509/rfc2818_hostname.lo x509/rc2.lo + x509/pkcs12_encr.lo x509/rfc2818_hostname.lo x509/rc2.lo x509/x509_write.lo libgnutls_la_LDFLAGS = $(LIBASN1_LINK) $(LIBGCRYPT_LIBS) \ $(libgnutls_version_script_cmd) \ diff --git a/lib/pkix.asn b/lib/pkix.asn index aa9ac0ec1e..9902e781d6 100644 --- a/lib/pkix.asn +++ b/lib/pkix.asn @@ -539,6 +539,27 @@ TBSCertificate ::= SEQUENCE { -- If present, version shall be v3 -- } +Certificate_write ::= SEQUENCE { + tbsCertificate TBSCertificate_write, + signatureAlgorithm AlgorithmIdentifier, + signature BIT STRING } + +TBSCertificate_write ::= SEQUENCE { + version [0] EXPLICIT Version DEFAULT v1, + serialNumber CertificateSerialNumber, + signature AlgorithmIdentifier, + issuer ANY, + validity Validity, + subject ANY, + subjectPublicKeyInfo SubjectPublicKeyInfo, + issuerUniqueID [1] IMPLICIT UniqueIdentifier OPTIONAL, + -- If present, version shall be v2 or v3 + subjectUniqueID [2] IMPLICIT UniqueIdentifier OPTIONAL, + -- If present, version shall be v2 or v3 + extensions [3] EXPLICIT Extensions OPTIONAL + -- If present, version shall be v3 -- +} + Version ::= INTEGER { v1(0), v2(1), v3(2) } CertificateSerialNumber ::= INTEGER diff --git a/lib/pkix_asn1_tab.c b/lib/pkix_asn1_tab.c index 9922313d05..1954899c5b 100644 --- a/lib/pkix_asn1_tab.c +++ b/lib/pkix_asn1_tab.c @@ -533,6 +533,26 @@ const ASN1_ARRAY_TYPE pkix_asn1_tab[]={ {0,4104,"2"}, {"extensions",536895490,"Extensions"}, {0,2056,"3"}, + {"Certificate_write",1610612741,0}, + {"tbsCertificate",1073741826,"TBSCertificate_write"}, + {"signatureAlgorithm",1073741826,"AlgorithmIdentifier"}, + {"signature",6,0}, + {"TBSCertificate_write",1610612741,0}, + {"version",1610653698,"Version"}, + {0,1073741833,"v1"}, + {0,2056,"0"}, + {"serialNumber",1073741826,"CertificateSerialNumber"}, + {"signature",1073741826,"AlgorithmIdentifier"}, + {"issuer",1073741837,0}, + {"validity",1073741826,"Validity"}, + {"subject",1073741837,0}, + {"subjectPublicKeyInfo",1073741826,"SubjectPublicKeyInfo"}, + {"issuerUniqueID",1610637314,"UniqueIdentifier"}, + {0,4104,"1"}, + {"subjectUniqueID",1610637314,"UniqueIdentifier"}, + {0,4104,"2"}, + {"extensions",536895490,"Extensions"}, + {0,2056,"3"}, {"Version",1610874883,0}, {"v1",1073741825,"0"}, {"v2",1073741825,"1"}, diff --git a/lib/x509/Makefile.am b/lib/x509/Makefile.am index 013fe97877..206617b223 100644 --- a/lib/x509/Makefile.am +++ b/lib/x509/Makefile.am @@ -9,7 +9,7 @@ noinst_LTLIBRARIES = libx509.la COBJECTS = crl.c dn.c common.c x509.c extensions.c \ rfc2818_hostname.c verify.c mpi.c privkey.c pkcs7.c \ crq.c xml.c sign.c pkcs5.c privkey_pkcs8.c pkcs12.c \ - pkcs12_bag.c pkcs12_encr.c rc2.c + pkcs12_bag.c pkcs12_encr.c rc2.c x509_write.c COMPAT_OBJECTS = compat.c diff --git a/lib/x509/common.c b/lib/x509/common.c index bc405baa7e..b86db3ac65 100644 --- a/lib/x509/common.c +++ b/lib/x509/common.c @@ -29,6 +29,7 @@ #include <gnutls_num.h> #include <x509_b64.h> #include <common.h> +#include <mpi.h> typedef struct _oid2string { const char * oid; @@ -346,7 +347,7 @@ static time_t mktime_utc(const struct fake_tm *tm) * month|day|hour|minute (2 chars each) * and year is given. Returns a time_t date. */ -static time_t _gnutls_x509_time2gtime(char *ttime, int year) +time_t _gnutls_x509_time2gtime(const char *ttime, int year) { char xx[3]; struct fake_tm etime; @@ -403,7 +404,7 @@ static time_t _gnutls_x509_time2gtime(char *ttime, int year) * The given time is expressed as: * YEAR(2)|MONTH(2)|DAY(2)|HOUR(2)|MIN(2) */ -time_t _gnutls_x509_utcTime2gtime(char *ttime) +time_t _gnutls_x509_utcTime2gtime(const char *ttime) { char xx[3]; int year; @@ -427,11 +428,42 @@ time_t _gnutls_x509_utcTime2gtime(char *ttime) return _gnutls_x509_time2gtime( ttime, year); } +/* returns a time value that contains the given time. + * The given time is expressed as: + * YEAR(2)|MONTH(2)|DAY(2)|HOUR(2)|MIN(2) + */ +int _gnutls_x509_gtime2utcTime(time_t gtime, char *str_time, int str_time_size) +{ +size_t ret; + +#ifdef HAVE_GMTIME_R +struct tm _tm; + + gmtime_r( >ime, &_tm); + + ret = strftime( str_time, str_time_size, "%y%m%d%H%M00Z", &_tm); +#else +struct tm* _tm; + + _tm = gmtime( >ime); + + ret = strftime( str_time, str_time_size, "%y%m%d%H%M00Z", _tm); +#endif + + if (!ret) { + gnutls_assert(); + return GNUTLS_E_SHORT_MEMORY_BUFFER; + } + + return 0; + +} + /* returns a time_t value that contains the given time. * The given time is expressed as: * YEAR(4)|MONTH(2)|DAY(2)|HOUR(2)|MIN(2) */ -time_t _gnutls_x509_generalTime2gtime(char *ttime) +time_t _gnutls_x509_generalTime2gtime(const char *ttime) { char xx[5]; int year; @@ -506,6 +538,40 @@ time_t _gnutls_x509_get_time(ASN1_TYPE c2, const char *when) return ctime; } +/* Sets the time in time_t in the ASN1_TYPE given. Where should + * be something like "tbsCertList.thisUpdate". + */ +int _gnutls_x509_set_time(ASN1_TYPE c2, const char *where, time_t tim) +{ + opaque str_time[MAX_TIME]; + char name[1024]; + int result, len; + + _gnutls_str_cpy(name, sizeof(name), where); + + if ((result = asn1_write_value(c2, name, "UTCTime", 1)) < 0) { + gnutls_assert(); + return _gnutls_asn2err(result); + } + + result = _gnutls_x509_gtime2utcTime( tim, str_time, sizeof(str_time)); + if (result < 0) { + gnutls_assert(); + return result; + } + + _gnutls_str_cat(name, sizeof(name), ".utcTime"); + + result = asn1_write_value(c2, name, str_time, len); + if (result != ASN1_SUCCESS) { + gnutls_assert(); + return _gnutls_asn2err(result); + } + + return 0; +} + + gnutls_x509_subject_alt_name _gnutls_x509_san_find_type( char* str_type) { if (strcmp( str_type, "dNSName")==0) return GNUTLS_SAN_DNSNAME; if (strcmp( str_type, "rfc822Name")==0) return GNUTLS_SAN_RFC822NAME; @@ -521,13 +587,18 @@ int _gnutls_x509_export_int( ASN1_TYPE asn1_data, gnutls_x509_crt_fmt format, char* pem_header, int tmp_buf_size, unsigned char* output_data, size_t* output_data_size) { - int result; + int result, len; if (tmp_buf_size == 0) tmp_buf_size = 16*1024; if (format == GNUTLS_X509_FMT_DER) { + len = *output_data_size; + if (output_data == NULL) *output_data_size = 0; - if ((result=asn1_der_coding( asn1_data, "", output_data, output_data_size, NULL)) != ASN1_SUCCESS) { + if ((result=asn1_der_coding( asn1_data, "", output_data, &len, NULL)) != ASN1_SUCCESS) + { + *output_data_size = len; + if (result == ASN1_MEM_ERROR) return GNUTLS_E_SHORT_MEMORY_BUFFER; @@ -538,8 +609,9 @@ int _gnutls_x509_export_int( ASN1_TYPE asn1_data, } else { /* PEM */ opaque *tmp; opaque *out; - int len = tmp_buf_size; + len = tmp_buf_size; + tmp = gnutls_alloca( len); if (tmp == NULL) { gnutls_assert(); @@ -842,3 +914,176 @@ gnutls_datum val; if (val.data != data->data) _gnutls_free_datum( &val); return result; } + +/* Encodes and copies the private key parameters into a + * subjectPublicKeyInfo structure. + * + * FIXME: can only support RSA parameters. + */ +int _gnutls_x509_encode_and_copy_PKI_params( ASN1_TYPE dst, const char* dst_name, + gnutls_pk_algorithm pk_algorithm, GNUTLS_MPI* params, int params_size) +{ +const char* pk; +opaque * der; +int der_size, result; +char name[128]; + + if (pk_algorithm != GNUTLS_PK_RSA) { + gnutls_assert(); + return GNUTLS_E_UNIMPLEMENTED_FEATURE; + } + + pk = _gnutls_x509_pk2oid( pk_algorithm); + if (pk == NULL) { + gnutls_assert(); + return GNUTLS_E_UNKNOWN_PK_ALGORITHM; + } + + /* write the RSA OID + */ + _gnutls_str_cpy( name, sizeof(name), dst_name); + _gnutls_str_cat( name, sizeof(name), ".algorithm.algorithm"); + result = asn1_write_value( dst, name, pk, 1); + if (result != ASN1_SUCCESS) { + gnutls_assert(); + return _gnutls_asn2err(result); + } + + /* disable parameters, which are not used in RSA. + */ + _gnutls_str_cpy( name, sizeof(name), dst_name); + _gnutls_str_cat( name, sizeof(name), ".algorithm.parameters"); + result = asn1_write_value( dst, name, NULL, 0); + if (result != ASN1_SUCCESS) { + gnutls_assert(); + return _gnutls_asn2err(result); + } + + _gnutls_x509_write_rsa_params( params, params_size, NULL, &der_size); + + der = gnutls_alloca( der_size); + if (der == NULL) { + gnutls_assert(); + return GNUTLS_E_MEMORY_ERROR; + } + + result = _gnutls_x509_write_rsa_params( params, params_size, der, &der_size); + if (result < 0) { + gnutls_assert(); + gnutls_afree(der); + return result; + } + + /* Write the DER parameters. (in bits) + */ + _gnutls_str_cpy( name, sizeof(name), dst_name); + _gnutls_str_cat( name, sizeof(name), ".subjectPublicKey"); + result = asn1_write_value( dst, name, der, der_size*8); + + gnutls_afree(der); + + if (result != ASN1_SUCCESS) { + gnutls_assert(); + return _gnutls_asn2err(result); + } + + return 0; +} + +/* Reads and returns the PK algorithm of the given certificate-like + * ASN.1 structure. src_name should be something like "tbsCertificate.subjectPublicKeyInfo". + */ +int _gnutls_x509_get_pk_algorithm( ASN1_TYPE src, const char* src_name, unsigned int* bits) +{ +int result; +opaque *str = NULL; +int algo; +char oid[64]; +int len; +GNUTLS_MPI params[MAX_PUBLIC_PARAMS_SIZE]; +char name[128]; + + _gnutls_str_cpy( name, sizeof(name), src_name); + _gnutls_str_cat( name, sizeof(name), ".algorithm.algorithm"); + + len = sizeof(oid); + result = + asn1_read_value(src, name, oid, &len); + + if (result != ASN1_SUCCESS) { + gnutls_assert(); + return _gnutls_asn2err(result); + } + + algo = _gnutls_x509_oid2pk_algorithm( oid); + + if ( bits==NULL) { + gnutls_free(str); + return algo; + } + + /* Now read the parameters' bits */ + _gnutls_str_cpy( name, sizeof(name), src_name); + _gnutls_str_cat( name, sizeof(name), ".subjectPublicKey"); + + len = 0; + result = asn1_read_value( src, name, NULL, &len); + if (result != ASN1_MEM_ERROR) { + gnutls_assert(); + return _gnutls_asn2err(result); + } + + if (len % 8 != 0) { + gnutls_assert(); + return GNUTLS_E_CERTIFICATE_ERROR; + } + + len /= 8; + + str = gnutls_malloc( len); + if (str == NULL) { + gnutls_assert(); + return GNUTLS_E_MEMORY_ERROR; + } + + _gnutls_str_cpy( name, sizeof(name), src_name); + _gnutls_str_cat( name, sizeof(name), ".subjectPublicKey"); + + result = asn1_read_value(src, name, str, &len); + + if (result != ASN1_SUCCESS) { + gnutls_assert(); + gnutls_free(str); + return _gnutls_asn2err(result); + } + + len /= 8; + + if (algo==GNUTLS_PK_RSA) { + if ((result=_gnutls_x509_read_rsa_params( str, len, params)) < 0) { + gnutls_assert(); + return result; + } + + bits[0] = _gnutls_mpi_get_nbits( params[0]); + + _gnutls_mpi_release( ¶ms[0]); + _gnutls_mpi_release( ¶ms[1]); + } + + if (algo==GNUTLS_PK_DSA) { + + if ((result = + _gnutls_x509_read_dsa_pubkey(str, len, params)) < 0) { + gnutls_assert(); + return result; + } + + bits[0] = _gnutls_mpi_get_nbits( params[3]); + + _gnutls_mpi_release( ¶ms[3]); + } + + gnutls_free(str); + return algo; +} diff --git a/lib/x509/common.h b/lib/x509/common.h index c197f7bdef..3878714d82 100644 --- a/lib/x509/common.h +++ b/lib/x509/common.h @@ -17,8 +17,9 @@ void _gnutls_int2str(unsigned int k, char *data); #define RSA_MD5_OID "1.2.840.113549.1.1.4" #define RSA_SHA1_OID "1.2.840.113549.1.1.5" -time_t _gnutls_x509_utcTime2gtime(char *ttime); -time_t _gnutls_x509_generalTime2gtime(char *ttime); +time_t _gnutls_x509_utcTime2gtime(const char *ttime); +time_t _gnutls_x509_generalTime2gtime(const char *ttime); +int _gnutls_x509_set_time(ASN1_TYPE c2, const char *where, time_t tim); int _gnutls_x509_oid_data2string( const char* OID, void* value, int value_size, char * res, int *res_size); @@ -57,3 +58,7 @@ int _gnutls_x509_encode_and_write_attribute( const char* given_oid, ASN1_TYPE as const char* where, const unsigned char* data, int sizeof_data, int multi); int _gnutls_x509_decode_and_read_attribute(ASN1_TYPE asn1_struct, const char* where, char* oid, int oid_size, gnutls_datum* value, int multi); +int _gnutls_x509_encode_and_copy_PKI_params( ASN1_TYPE dst, const char* dst_name, + gnutls_pk_algorithm pk_algorithm, GNUTLS_MPI* params, int params_size); + +int _gnutls_x509_get_pk_algorithm( ASN1_TYPE src, const char* src_name, unsigned int* bits); diff --git a/lib/x509/crq.c b/lib/x509/crq.c index 06e91859a6..d1d805101d 100644 --- a/lib/x509/crq.c +++ b/lib/x509/crq.c @@ -386,7 +386,7 @@ int gnutls_x509_crq_get_challenge_password(gnutls_x509_crq crq, * **/ int gnutls_x509_crq_set_dn_by_oid(gnutls_x509_crq crq, const char* oid, - const char *name, int sizeof_name) + const char *name, unsigned int sizeof_name) { if (sizeof_name == 0 || name == NULL || crq == NULL) { return GNUTLS_E_INVALID_REQUEST; @@ -407,7 +407,7 @@ int gnutls_x509_crq_set_dn_by_oid(gnutls_x509_crq crq, const char* oid, * On success zero is returned. * **/ -int gnutls_x509_crq_set_version(gnutls_x509_crq crq, int version) +int gnutls_x509_crq_set_version(gnutls_x509_crq crq, unsigned int version) { int result; uint8 null = version; @@ -434,90 +434,17 @@ uint8 null = version; **/ int gnutls_x509_crq_set_key(gnutls_x509_crq crq, gnutls_x509_privkey key) { -const char* pk; -opaque * der; -int der_size, result; - - if (key->pk_algorithm != GNUTLS_PK_RSA) { - gnutls_assert(); - return GNUTLS_E_UNIMPLEMENTED_FEATURE; - } - - pk = _gnutls_x509_pk2oid( key->pk_algorithm); - if (pk == NULL) { - gnutls_assert(); - return GNUTLS_E_UNKNOWN_PK_ALGORITHM; - } - - /* write the RSA OID - */ - result = asn1_write_value( crq->crq, "certificationRequestInfo.subjectPKInfo.algorithm.algorithm", pk, 1); - if (result != ASN1_SUCCESS) { - gnutls_assert(); - return _gnutls_asn2err(result); - } - - /* disable parameters, which are not used in RSA. - */ - result = asn1_write_value( crq->crq, "certificationRequestInfo.subjectPKInfo.algorithm.parameters", NULL, 0); - if (result != ASN1_SUCCESS) { - gnutls_assert(); - return _gnutls_asn2err(result); - } +int result; - _gnutls_x509_write_rsa_params( key->params, key->params_size, NULL, &der_size); + result = _gnutls_x509_encode_and_copy_PKI_params( crq->crq, + "certificationRequestInfo.subjectPKInfo", key->pk_algorithm, + key->params, key->params_size); - der = gnutls_alloca( der_size); - if (der == NULL) { - gnutls_assert(); - return GNUTLS_E_MEMORY_ERROR; - } - - result = _gnutls_x509_write_rsa_params( key->params, key->params_size, der, &der_size); if (result < 0) { gnutls_assert(); - gnutls_afree(der); return result; } - /* Write the DER parameters. (in bits) - */ - result = asn1_write_value( crq->crq, - "certificationRequestInfo.subjectPKInfo.subjectPublicKey", der, der_size*8); - - gnutls_afree(der); - - if (result != ASN1_SUCCESS) { - gnutls_assert(); - return _gnutls_asn2err(result); - } - - /* Step 2. Move up and write the AlgorithmIdentifier, which is also - * the same. Note that requests are self signed. - */ - - pk = _gnutls_x509_sign2oid( key->pk_algorithm, GNUTLS_MAC_SHA); - if (pk == NULL) { - gnutls_assert(); - return GNUTLS_E_INVALID_REQUEST; - } - - /* write the RSA OID - */ - result = asn1_write_value( crq->crq, "signatureAlgorithm.algorithm", pk, 1); - if (result != ASN1_SUCCESS) { - gnutls_assert(); - return _gnutls_asn2err(result); - } - - /* disable parameters, which are not used in RSA. - */ - result = asn1_write_value( crq->crq, "signatureAlgorithm.parameters", NULL, 0); - if (result != ASN1_SUCCESS) { - gnutls_assert(); - return _gnutls_asn2err(result); - } - return 0; } @@ -629,4 +556,35 @@ int gnutls_x509_crq_export( gnutls_x509_crq crq, output_data, output_data_size); } +/** + * gnutls_x509_crq_get_pk_algorithm - This function returns the certificate request's PublicKey algorithm + * @crq: should contain a gnutls_x509_crq structure + * @bits: if bits is non null it will hold the size of the parameters' in bits + * + * This function will return the public key algorithm of a PKCS #10 + * certificate request. + * + * If bits is non null, it should have enough size to hold the parameters + * size in bits. For RSA the bits returned is the modulus. + * For DSA the bits returned are of the public + * exponent. + * + * Returns a member of the gnutls_pk_algorithm enumeration on success, + * or a negative value on error. + * + **/ +int gnutls_x509_crq_get_pk_algorithm( gnutls_x509_crq crq, unsigned int* bits) +{ +int result; + + result = _gnutls_x509_get_pk_algorithm( crq->crq, "certificationRequestInfo.subjectPKInfo", + bits); + if (result < 0) { + gnutls_assert(); + return result; + } + + return result; +} + #endif /* ENABLE_PKI */ diff --git a/lib/x509/crq.h b/lib/x509/crq.h index b0da695497..94c6915c41 100644 --- a/lib/x509/crq.h +++ b/lib/x509/crq.h @@ -1,5 +1,5 @@ -#ifndef CRL_H -# define CRL_H +#ifndef CRQ_H +# define CRQ_H typedef struct gnutls_x509_crq_int { ASN1_TYPE crq; @@ -16,4 +16,6 @@ void gnutls_x509_crq_deinit(gnutls_x509_crq crq); int gnutls_x509_crq_import(gnutls_x509_crq crq, const gnutls_datum * data, gnutls_x509_crt_fmt format); +int gnutls_x509_crq_get_pk_algorithm( gnutls_x509_crq crq, unsigned int* bits); + #endif diff --git a/lib/x509/dn.c b/lib/x509/dn.c index 35f6146363..242ed35cb6 100644 --- a/lib/x509/dn.c +++ b/lib/x509/dn.c @@ -285,6 +285,96 @@ int _gnutls_x509_parse_dn(ASN1_TYPE asn1_struct, return result; } +/* Parses an X509 DN in the src, and puts the output into + * the DN dst. + * + * asn1_rdn_name must be a string in the form "tbsCertificate.issuer.rdnSequence". + * That is to point in the rndSequence. + */ +int _gnutls_x509_copy_cert_dn(ASN1_TYPE *dst, ASN1_TYPE src) +{ +int result; +gnutls_datum der_cert; +ASN1_TYPE new_dst = ASN1_TYPE_EMPTY; + + /* DER Encode the dest certificate. + */ + result = _gnutls_x509_der_encode( *dst, "", &der_cert, 0); + if (result < 0) { + gnutls_assert(); + return result; + } + + /* Generate a Certificate_write structure. + */ + if ((result = + asn1_create_element(_gnutls_get_pkix(), + "PKIX1.Certificate_write", &new_dst + )) != ASN1_SUCCESS) { + gnutls_assert(); + result = _gnutls_asn2err(result); + goto cleanup; + } + + /* Copy the dest certificate into the certificate_write struct. + */ + result = asn1_der_decoding( &new_dst, der_cert.data, der_cert.size, NULL); + if (result != ASN1_SUCCESS) { + gnutls_assert(); + result = _gnutls_asn2err(result); + goto cleanup; + } + + /* Encode the Issuer certificate name and copy into the + * issuer's name of certificate_write. + */ + result = _gnutls_x509_der_encode_and_copy( src, "tbsCertificate.subject", + new_dst, "tbsCertificate.issuer", 0); + if (result < 0) { + gnutls_assert(); + goto cleanup; + } + + /* Decode the new certificate. + */ + + _gnutls_free_datum( &der_cert); + + result = _gnutls_x509_der_encode( new_dst, "", &der_cert, 0); + if (result < 0) { + gnutls_assert(); + goto cleanup; + } + + asn1_delete_structure( dst); + *dst = ASN1_TYPE_EMPTY; + + if ((result = + asn1_create_element(_gnutls_get_pkix(), + "PKIX1.Certificate", dst + )) != ASN1_SUCCESS) { + gnutls_assert(); + result = _gnutls_asn2err(result); + goto cleanup; + } + + /* Copy to the dest certificate. + */ + result = asn1_der_decoding( dst, der_cert.data, der_cert.size, NULL); + if (result != ASN1_SUCCESS) { + gnutls_assert(); + result = _gnutls_asn2err(result); + goto cleanup; + } + + result = 0; + +cleanup: + _gnutls_free_datum( &der_cert); + return result; + +} + /* Parses an X509 DN in the asn1_struct, and searches for the * given OID in the DN. * The output will be encoded in the LDAP way. (#hex for non printable). diff --git a/lib/x509/dn.h b/lib/x509/dn.h index dd6d731c27..93aa209f14 100644 --- a/lib/x509/dn.h +++ b/lib/x509/dn.h @@ -17,6 +17,8 @@ int _gnutls_x509_parse_dn(ASN1_TYPE asn1_struct, const char* asn1_rdn_name, char *buf, int* sizeof_buf); +int _gnutls_x509_copy_cert_dn(ASN1_TYPE *dst, ASN1_TYPE src); + int _gnutls_x509_parse_dn_oid(ASN1_TYPE asn1_struct, const char* asn1_rdn_name, const char* oid, int indx, char *buf, int* sizeof_buf); diff --git a/lib/x509/extensions.c b/lib/x509/extensions.c index 747f743180..7855590134 100644 --- a/lib/x509/extensions.c +++ b/lib/x509/extensions.c @@ -158,6 +158,52 @@ int _gnutls_x509_crt_get_extension( gnutls_x509_crt cert, const char* extension_ } } +/* This function will attempt to set the requested extension in + * the given X509v3 certificate. + * + * Critical will be either 0 or 1. + */ +int _gnutls_x509_crt_set_extension( gnutls_x509_crt cert, const char* extension_id, + const gnutls_datum* ext_data, unsigned int critical) +{ + int result; + const char *str; + + /* Add a new extension in the list. + */ + result = asn1_write_value(cert->cert, "tbsCertificate.extensions", "NEW", 1); + if (result != ASN1_SUCCESS) { + gnutls_assert(); + return _gnutls_asn2err(result); + } + + result = asn1_write_value(cert->cert, "tbsCertificate.extensions.?LAST.extnID", extension_id, 1); + if (result != ASN1_SUCCESS) { + gnutls_assert(); + return _gnutls_asn2err(result); + } + + if (critical==0) str = "FALSE"; + else str = "TRUE"; + + + result = asn1_write_value(cert->cert, "tbsCertificate.extensions.?LAST.critical", str, 1); + if (result != ASN1_SUCCESS) { + gnutls_assert(); + return _gnutls_asn2err(result); + } + + result = _gnutls_x509_write_value( cert->cert, "tbsCertificate.extensions.?LAST.extnValue", + ext_data, 0); + if (result < 0) { + gnutls_assert(); + return result; + } + + return 0; +} + + /* Here we only extract the KeyUsage field, from the DER encoded * extension. */ @@ -244,3 +290,41 @@ int _gnutls_x509_ext_extract_basicConstraints(int *CA, opaque * extnValue, return 0; } + +/* generate the basicConstraints in a DER encoded extension + * Use 0 or 1 (TRUE) for CA. + */ +int _gnutls_x509_ext_gen_basicConstraints(int CA, gnutls_datum* der_ext) +{ + ASN1_TYPE ext = ASN1_TYPE_EMPTY; + const char *str; + int result; + + if (CA == 0) str = "FALSE"; + else str = "TRUE"; + + if ((result=asn1_create_element + (_gnutls_get_pkix(), "PKIX1.BasicConstraints", &ext + )) != ASN1_SUCCESS) { + gnutls_assert(); + return _gnutls_asn2err(result); + } + + result = asn1_write_value(ext, "cA", str, 1); + if (result != ASN1_SUCCESS) { + gnutls_assert(); + asn1_delete_structure(&ext); + return _gnutls_asn2err(result); + } + + result = _gnutls_x509_der_encode( ext, "", der_ext, 0); + + asn1_delete_structure(&ext); + + if (result < 0) { + gnutls_assert(); + return result; + } + + return 0; +} diff --git a/lib/x509/extensions.h b/lib/x509/extensions.h index a0bbd84cbd..d9fb33dc5f 100644 --- a/lib/x509/extensions.h +++ b/lib/x509/extensions.h @@ -4,3 +4,7 @@ int _gnutls_x509_ext_extract_keyUsage(uint16 *keyUsage, opaque * extnValue, int extnValueLen); int _gnutls_x509_ext_extract_basicConstraints(int *CA, opaque * extnValue, int extnValueLen); + +int _gnutls_x509_crt_set_extension( gnutls_x509_crt cert, const char* extension_id, + const gnutls_datum* ext_data, unsigned int critical); +int _gnutls_x509_ext_gen_basicConstraints(int CA, gnutls_datum* der_ext); diff --git a/lib/x509/x509.c b/lib/x509/x509.c index a373a0ca4b..5a1a4cb0f2 100644 --- a/lib/x509/x509.c +++ b/lib/x509/x509.c @@ -500,7 +500,7 @@ int gnutls_x509_crt_get_serial(gnutls_x509_crt cert, char* result, if ((ret = asn1_read_value(cert->cert, "tbsCertificate.serialNumber", result, result_size)) < 0) { gnutls_assert(); - return ret; + return _gnutls_asn2err(ret); } return 0; @@ -527,97 +527,17 @@ int gnutls_x509_crt_get_serial(gnutls_x509_crt cert, char* result, int gnutls_x509_crt_get_pk_algorithm( gnutls_x509_crt cert, unsigned int* bits) { int result; - opaque *str = NULL; - int algo; - char oid[64]; - int len; - GNUTLS_MPI params[MAX_PUBLIC_PARAMS_SIZE]; - - len = sizeof(oid); - result = - asn1_read_value - (cert->cert, - "tbsCertificate.subjectPublicKeyInfo.algorithm.algorithm", - oid, &len); - - if (result != ASN1_SUCCESS) { - gnutls_assert(); - return _gnutls_asn2err(result); - } - - algo = _gnutls_x509_oid2pk_algorithm( oid); - - if ( bits==NULL) { - gnutls_free(str); - return algo; - } - /* Now read the parameters' bits */ + result = _gnutls_x509_get_pk_algorithm( cert->cert, "tbsCertificate.subjectPublicKeyInfo", + bits); - len = 0; - result = - asn1_read_value - (cert->cert, "tbsCertificate.subjectPublicKeyInfo.subjectPublicKey", - NULL, &len); - - if (result != ASN1_MEM_ERROR) { - gnutls_assert(); - return _gnutls_asn2err(result); - } - - if (len % 8 != 0) { - gnutls_assert(); - return GNUTLS_E_CERTIFICATE_ERROR; - } - - len /= 8; - - str = gnutls_malloc( len); - if (str == NULL) { - gnutls_assert(); - return GNUTLS_E_MEMORY_ERROR; - } - - result = - asn1_read_value - (cert->cert, "tbsCertificate.subjectPublicKeyInfo.subjectPublicKey", - str, &len); - - if (result != ASN1_SUCCESS) { + if (result < 0) { gnutls_assert(); - gnutls_free(str); - return _gnutls_asn2err(result); - } - - len /= 8; - - if (algo==GNUTLS_PK_RSA) { - if ((result=_gnutls_x509_read_rsa_params( str, len, params)) < 0) { - gnutls_assert(); - return result; - } - - bits[0] = _gnutls_mpi_get_nbits( params[0]); - - _gnutls_mpi_release( ¶ms[0]); - _gnutls_mpi_release( ¶ms[1]); + return result; } - if (algo==GNUTLS_PK_DSA) { - - if ((result = - _gnutls_x509_read_dsa_pubkey(str, len, params)) < 0) { - gnutls_assert(); - return result; - } - - bits[0] = _gnutls_mpi_get_nbits( params[3]); - - _gnutls_mpi_release( ¶ms[3]); - } + return result; - gnutls_free(str); - return algo; } /** diff --git a/lib/x509/x509_write.c b/lib/x509/x509_write.c new file mode 100644 index 0000000000..bb38dd34f9 --- /dev/null +++ b/lib/x509/x509_write.c @@ -0,0 +1,391 @@ +/* + * Copyright (C) 2003 Nikos Mavroyanopoulos + * + * This file is part of GNUTLS. + * + * The GNUTLS library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +/* This file contains functions to handle PKCS #10 certificate requests. + */ + +#include <gnutls_int.h> + +#ifdef ENABLE_PKI + +#include <gnutls_datum.h> +#include <gnutls_global.h> +#include <gnutls_errors.h> +#include <common.h> +#include <gnutls_x509.h> +#include <x509_b64.h> +#include <crq.h> +#include <dn.h> +#include <mpi.h> +#include <sign.h> +#include <extensions.h> +#include <libtasn1.h> +#include <gnutls_ui.h> + +static void disable_optional_stuff( gnutls_x509_crt cert); + +/** + * gnutls_x509_crt_set_dn_by_oid - This function will set the Certificate request subject's distinguished name + * @crt: should contain a gnutls_x509_crt structure + * @oid: holds an Object Identified in null terminated string + * @name: a pointer to the name + * @sizeof_name: holds the size of 'name' + * + * This function will set the part of the name of the Certificate subject, specified + * by the given OID. + * + * Some helper macros with popular OIDs can be found in gnutls/x509.h + * With this function you can only set the known OIDs. + * + * On success zero is returned. + * + **/ +int gnutls_x509_crt_set_dn_by_oid(gnutls_x509_crt crt, const char* oid, + const char *name, unsigned int sizeof_name) +{ + if (sizeof_name == 0 || name == NULL || crt == NULL) { + return GNUTLS_E_INVALID_REQUEST; + } + + return _gnutls_x509_set_dn_oid( crt->cert, "tbsCertificate.subject", oid, + name, sizeof_name); +} + +/** + * gnutls_x509_crt_set_issuer_dn_by_oid - This function will set the Certificate request issuer's distinguished name + * @crt: should contain a gnutls_x509_crt structure + * @oid: holds an Object Identified in null terminated string + * @name: a pointer to the name + * @sizeof_name: holds the size of 'name' + * + * This function will set the part of the name of the Certificate issuer, specified + * by the given OID. + * + * Some helper macros with popular OIDs can be found in gnutls/x509.h + * With this function you can only set the known OIDs. + * + * On success zero is returned. + * + **/ +int gnutls_x509_crt_set_issuer_dn_by_oid(gnutls_x509_crt crt, const char* oid, + const char *name, unsigned int sizeof_name) +{ + if (sizeof_name == 0 || name == NULL || crt == NULL) { + return GNUTLS_E_INVALID_REQUEST; + } + + return _gnutls_x509_set_dn_oid( crt->cert, "tbsCertificate.issuer", oid, + name, sizeof_name); +} + +/** + * gnutls_x509_crt_set_version - This function will set the Certificate request version + * @crt: should contain a gnutls_x509_crt structure + * @version: holds the version number. For X509v1 certificates must be 0. + * + * This function will set the version of the certificate request. This + * must be zero. + * + * On success zero is returned. + * + **/ +int gnutls_x509_crt_set_version(gnutls_x509_crt crt, unsigned int version) +{ +int result; +uint8 null = version; + + result = asn1_write_value( crt->cert, "tbsCertificate.version", &null, 1); + if (result != ASN1_SUCCESS) { + gnutls_assert(); + return _gnutls_asn2err(result); + } + + return 0; +} + +/** + * gnutls_x509_crt_set_key - This function will associate the Certificate with a key + * @crt: should contain a gnutls_x509_crt structure + * @key: holds a private key + * + * This function will set the public parameters from the given private key to the + * certificate. Only RSA keys are currently supported. + * + * On success zero is returned. + * + **/ +int gnutls_x509_crt_set_key(gnutls_x509_crt crt, gnutls_x509_privkey key) +{ +int result; + + result = _gnutls_x509_encode_and_copy_PKI_params( crt->cert, + "tbsCertificate.subjectPublicKeyInfo", key->pk_algorithm, + key->params, key->params_size); + + if (result < 0) { + gnutls_assert(); + return result; + } + + return 0; +} + +/** + * gnutls_x509_crt_set_crq - This function will associate the Certificate with a request + * @crt: should contain a gnutls_x509_crt structure + * @crq: holds a certificate request + * + * This function will set the name and public parameters from the given certificate request to the + * certificate. Only RSA keys are currently supported. + * + * On success zero is returned. + * + **/ +int gnutls_x509_crt_set_crq(gnutls_x509_crt crt, gnutls_x509_crq crq) +{ +const char* pk; +opaque * der; +int der_size, result; +int pk_algorithm; + + pk_algorithm = gnutls_x509_crq_get_pk_algorithm( crq, NULL); + + if (pk_algorithm != GNUTLS_PK_RSA) { + gnutls_assert(); + return GNUTLS_E_UNIMPLEMENTED_FEATURE; + } + +#warning PUT SOME CODE HERE + + return 0; +} + + +/** + * gnutls_x509_crt_set_ca_status - This function will set the basicConstraints extension + * @crt: should contain a gnutls_x509_crt structure + * @ca: true(1) or false(0). Depending on the Certificat authority status. + * + * This function will set the basicConstraints certificate extension. + * + * On success zero is returned. + * + **/ +int gnutls_x509_crt_set_ca_status(gnutls_x509_crt crt, unsigned int ca) +{ +int result; +gnutls_datum der_data; + + /* generate the extension. + */ + result = _gnutls_x509_ext_gen_basicConstraints( ca, &der_data); + if (result < 0) { + gnutls_assert(); + return result; + } + + result = _gnutls_x509_crt_set_extension( crt, "2.5.29.19", &der_data, 1); + + _gnutls_free_datum( &der_data); + + if (result < 0) { + gnutls_assert(); + return result; + } + + return 0; +} + +/** + * gnutls_x509_crt_sign - This function will sign a Certificate request with a key + * @crt: should contain a gnutls_x509_crt structure + * @issuer: is the certificate of the certificate issuer + * @issuer_key: holds the issuer's private key + * + * This function will sign the certificate with the issuer's private key, and + * will copy the issuer's information into the certificate. + * + * This must be the last step in a certificate generation since all + * the previously set parameters are now signed. + * + * On success zero is returned. + * + **/ +int gnutls_x509_crt_sign(gnutls_x509_crt crt, gnutls_x509_crt issuer, + gnutls_x509_privkey issuer_key) +{ +int result; +gnutls_datum signature; +const char* pk; + + if (issuer_key->pk_algorithm != GNUTLS_PK_RSA) { + gnutls_assert(); + return GNUTLS_E_UNIMPLEMENTED_FEATURE; + } + + /* disable all the unneeded OPTIONAL fields. + */ + disable_optional_stuff( crt); + + /* Step 1. Copy the issuer's name into the certificate. + */ + result = _gnutls_x509_copy_cert_dn( &crt->cert, issuer->cert); + if (result < 0) { + gnutls_assert(); + return result; + } + + /* Step 2. Sign the certificate. + */ + result = _gnutls_x509_sign_tbs( crt->cert, "tbsCertificate", GNUTLS_MAC_SHA, + issuer_key, &signature); + + if (result < 0) { + gnutls_assert(); + return result; + } + + /* write the signature (bits) + */ + result = asn1_write_value( crt->cert, "signature", signature.data, signature.size*8); + + _gnutls_free_datum( &signature); + + if (result != ASN1_SUCCESS) { + gnutls_assert(); + return _gnutls_asn2err(result); + } + + /* Step 2. Move up and write the AlgorithmIdentifier, which is also + * the same. + */ + + pk = _gnutls_x509_sign2oid( issuer_key->pk_algorithm, GNUTLS_MAC_SHA); + if (pk == NULL) { + gnutls_assert(); + return GNUTLS_E_INVALID_REQUEST; + } + + /* write the RSA OID + */ + result = asn1_write_value( crt->cert, "signatureAlgorithm.algorithm", pk, 1); + if (result != ASN1_SUCCESS) { + gnutls_assert(); + return _gnutls_asn2err(result); + } + + /* disable parameters, which are not used in RSA. + */ + result = asn1_write_value( crt->cert, "signatureAlgorithm.parameters", NULL, 0); + if (result != ASN1_SUCCESS) { + gnutls_assert(); + return _gnutls_asn2err(result); + } + + return 0; +} + +/** + * gnutls_x509_crt_set_activation_time - This function will set the Certificate's activation time + * @cert: should contain a gnutls_x509_crt structure + * @act_time: The actual time + * + * This function will set the time this Certificate was or will be activated. + * + * Returns a negative value in case of an error, and 0 on success. + * + **/ +int gnutls_x509_crt_set_activation_time(gnutls_x509_crt cert, time_t act_time) +{ + return _gnutls_x509_set_time( cert->cert, "tbsCertificate.validity.notBefore", act_time); +} + +/** + * gnutls_x509_crt_set_expiration_time - This function will set the Certificate's expiration time + * @cert: should contain a gnutls_x509_crt structure + * @exp_time: The actual time + * + * This function will set the time this Certificate will expire. + * + * Returns a negative value in case of an error, and 0 on success. + * + **/ +int gnutls_x509_crt_set_expiration_time(gnutls_x509_crt cert, time_t exp_time) +{ + return _gnutls_x509_set_time( cert->cert, "tbsCertificate.validity.notAfter", exp_time); +} + +/** + * gnutls_x509_crt_set_serial - This function will set the certificate's serial number + * @cert: should contain a gnutls_x509_crt structure + * @serial: The serial number + * @result_size: Holds the size of the serial field. + * + * This function will set the X.509 certificate's serial number. + * Serial is not always a 32 or 64bit number. Some CAs use + * large serial numbers, thus it may be wise to handle it as something + * opaque. + * + * Returns a negative value in case of an error, and 0 on success. + * + **/ +int gnutls_x509_crt_set_serial(gnutls_x509_crt cert, const unsigned char* serial, + size_t serial_size) +{ + int ret; + + if ((ret = asn1_write_value(cert->cert, "tbsCertificate.serialNumber", serial, serial_size)) < 0) + { + gnutls_assert(); + return _gnutls_asn2err(ret); + } + + return 0; + +} + +/* If OPTIONAL fields have not been initialized then + * disable them. + */ +static void disable_optional_stuff( gnutls_x509_crt cert) +{ +int ret, len = 1; +opaque tmp; + + ret = asn1_read_value( cert->cert, "tbsCertificate.issuerUniqueID", &tmp, &len); + if (ret == ASN1_VALUE_NOT_FOUND) + asn1_write_value( cert->cert, "tbsCertificate.issuerUniqueID", NULL, 0); + + len = 1; + ret = asn1_read_value( cert->cert, "tbsCertificate.subjectUniqueID", &tmp, &len); + if (ret == ASN1_VALUE_NOT_FOUND) + asn1_write_value( cert->cert, "tbsCertificate.subjectUniqueID", NULL, 0); + + len = 1; + ret = asn1_read_value( cert->cert, "tbsCertificate.extensions", &tmp, &len); + if (ret == ASN1_VALUE_NOT_FOUND) + asn1_write_value( cert->cert, "tbsCertificate.extensions", NULL, 0); + + return; +} + + +#endif /* ENABLE_PKI */ diff --git a/libgcrypt.m4 b/libgcrypt.m4 index 6bd1784fd2..b57b5b33c4 100644 --- a/libgcrypt.m4 +++ b/libgcrypt.m4 @@ -1,24 +1,24 @@ dnl Autoconf macros for libgcrypt -dnl $id$ +dnl Copyright (C) 2002 Free Software Foundation, Inc. +dnl +dnl This file is free software; as a special exception the author gives +dnl unlimited permission to copy and/or distribute it, with or without +dnl modifications, as long as this notice is preserved. +dnl +dnl This file is distributed in the hope that it will be useful, but +dnl WITHOUT ANY WARRANTY, to the extent permitted by law; without even the +dnl implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -# Configure paths for LIBGCRYPT -# Shamelessly stolen from the one of XDELTA by Owen Taylor -# Werner Koch 99-12-09 -dnl AM_PATH_LIBGCRYPT([MINIMUM-VERSION, [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND ]]]) -dnl Test for libgcrypt, and define GCRYPT_CFLAGS and GCRYPT_LIBS +dnl AM_PATH_LIBGCRYPT([MINIMUM-VERSION, +dnl [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND ]]]) +dnl Test for liblibgcrypt and define LIBGCRYPT_CFLAGS and LIBGCRYPT_LIBS dnl AC_DEFUN(AM_PATH_LIBGCRYPT, -[dnl -dnl Get the cflags and libraries from the libgcrypt-config script -dnl -AC_ARG_WITH(libgcrypt-prefix, - [ --with-libgcrypt-prefix=PFX Prefix where libgcrypt is installed (optional)], - libgcrypt_config_prefix="$withval", libgcrypt_config_prefix="") -AC_ARG_ENABLE(libgcrypttest, - [ --disable-libgcrypttest Do not try to compile and run a test libgcrypt program], - , enable_libgcrypttest=yes) - +[ AC_ARG_WITH(libgcrypt-prefix, + AC_HELP_STRING([--with-libgcrypt-prefix=PFX], + [prefix where LIBGCRYPT is installed (optional)]), + libgcrypt_config_prefix="$withval", libgcrypt_config_prefix="") if test x$libgcrypt_config_prefix != x ; then libgcrypt_config_args="$libgcrypt_config_args --prefix=$libgcrypt_config_prefix" if test x${LIBGCRYPT_CONFIG+set} != xset ; then @@ -27,137 +27,50 @@ AC_ARG_ENABLE(libgcrypttest, fi AC_PATH_PROG(LIBGCRYPT_CONFIG, libgcrypt-config, no) - min_libgcrypt_version=ifelse([$1], ,1.1.0,$1) - AC_MSG_CHECKING(for libgcrypt - version >= $min_libgcrypt_version) - no_libgcrypt="" - if test "$LIBGCRYPT_CONFIG" = "no" ; then - no_libgcrypt=yes - else - LIBGCRYPT_CFLAGS=`$LIBGCRYPT_CONFIG $libgcrypt_config_args --cflags` - LIBGCRYPT_LIBS=`$LIBGCRYPT_CONFIG $libgcrypt_config_args --libs` + min_libgcrypt_version=ifelse([$1], ,0.4.4,$1) + AC_MSG_CHECKING(for LIBGCRYPT - version >= $min_libgcrypt_version) + ok=no + if test "$LIBGCRYPT_CONFIG" != "no" ; then + req_major=`echo $min_libgcrypt_version | \ + sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\)/\1/'` + req_minor=`echo $min_libgcrypt_version | \ + sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\)/\2/'` + req_micro=`echo $min_libgcrypt_version | \ + sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\)/\3/'` libgcrypt_config_version=`$LIBGCRYPT_CONFIG $libgcrypt_config_args --version` - if test "x$enable_libgcrypttest" = "xyes" ; then - ac_save_CFLAGS="$CFLAGS" - ac_save_LIBS="$LIBS" - CFLAGS="$CFLAGS $LIBGCRYPT_CFLAGS" - LIBS="$LIBS $LIBGCRYPT_LIBS" -dnl -dnl Now check if the installed libgcrypt is sufficiently new. Also sanity -dnl checks the results of libgcrypt-config to some extent -dnl - rm -f conf.libgcrypttest - AC_TRY_RUN([ -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <gcrypt.h> - -int -main () -{ - system ("touch conf.libgcrypttest"); - - if( strcmp( gcry_check_version(NULL), "$libgcrypt_config_version" ) ) - { - printf("\n*** 'libgcrypt-config --version' returned %s, but LIBGCRYPT (%s)\n", - "$libgcrypt_config_version", gcry_check_version(NULL) ); - printf("*** was found! If libgcrypt-config was correct, then it is best\n"); - printf("*** to remove the old version of LIBGCRYPT. You may also be able to fix the error\n"); - printf("*** by modifying your LD_LIBRARY_PATH enviroment variable, or by editing\n"); - printf("*** /etc/ld.so.conf. Make sure you have run ldconfig if that is\n"); - printf("*** required on your system.\n"); - printf("*** If libgcrypt-config was wrong, set the environment variable LIBGCRYPT_CONFIG\n"); - printf("*** to point to the correct copy of libgcrypt-config, and remove the file config.cache\n"); - printf("*** before re-running configure\n"); - } - else if ( strcmp(gcry_check_version(NULL), GCRYPT_VERSION ) ) - { - printf("\n*** LIBGCRYPT header file (version %s) does not match\n", GCRYPT_VERSION); - printf("*** library (version %s)\n", gcry_check_version(NULL) ); - } - else - { - if ( gcry_check_version( "$min_libgcrypt_version" ) ) - { - return 0; - } - else - { - printf("no\n*** An old version of LIBGCRYPT (%s) was found.\n", - gcry_check_version(NULL) ); - printf("*** You need a version of LIBGCRYPT newer than %s. The latest version of\n", - "$min_libgcrypt_version" ); - printf("*** LIBGCRYPT is always available from ftp://ftp.gnupg.org/pub/libgcrypt/gnupg.\n"); - printf("*** (It is distributed along with GnuPG).\n"); - printf("*** \n"); - printf("*** If you have already installed a sufficiently new version, this error\n"); - printf("*** probably means that the wrong copy of the libgcrypt-config shell script is\n"); - printf("*** being found. The easiest way to fix this is to remove the old version\n"); - printf("*** of LIBGCRYPT, but you can also set the LIBGCRYPT_CONFIG environment to point to the\n"); - printf("*** correct copy of libgcrypt-config. (In this case, you will have to\n"); - printf("*** modify your LD_LIBRARY_PATH enviroment variable, or edit /etc/ld.so.conf\n"); - printf("*** so that the correct libraries are found at run-time))\n"); - } - } - return 1; -} -],, no_libgcrypt=yes,[echo $ac_n "cross compiling; assumed OK... $ac_c"]) - CFLAGS="$ac_save_CFLAGS" - LIBS="$ac_save_LIBS" - fi + major=`echo $libgcrypt_config_version | \ + sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\).*/\1/'` + minor=`echo $libgcrypt_config_version | \ + sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\).*/\2/'` + micro=`echo $libgcrypt_config_version | \ + sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\).*/\3/'` + if test "$major" -gt "$req_major"; then + ok=yes + else + if test "$major" -eq "$req_major"; then + if test "$minor" -gt "$req_minor"; then + ok=yes + else + if test "$minor" -eq "$req_minor"; then + if test "$micro" -ge "$req_micro"; then + ok=yes + fi + fi + fi + fi + fi fi - if test "x$no_libgcrypt" = x ; then - AC_MSG_RESULT(yes) - ifelse([$2], , :, [$2]) + if test $ok = yes; then + LIBGCRYPT_CFLAGS=`$LIBGCRYPT_CONFIG $libgcrypt_config_args --cflags` + LIBGCRYPT_LIBS=`$LIBGCRYPT_CONFIG $libgcrypt_config_args --libs` + AC_MSG_RESULT(yes) + ifelse([$2], , :, [$2]) else - if test -f conf.libgcrypttest ; then - : - else - AC_MSG_RESULT(no) - fi - if test "$LIBGCRYPT_CONFIG" = "no" ; then - echo "*** The libgcrypt-config script installed by LIBGCRYPT could not be found" - echo "*** If LIBGCRYPT was installed in PREFIX, make sure PREFIX/bin is in" - echo "*** your path, or set the LIBGCRYPT_CONFIG environment variable to the" - echo "*** full path to libgcrypt-config." - else - if test -f conf.libgcrypttest ; then - : - else - echo "*** Could not run libgcrypt test program, checking why..." - CFLAGS="$CFLAGS $LIBGCRYPT_CFLAGS" - LIBS="$LIBS $LIBGCRYPT_LIBS" - AC_TRY_LINK([ -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <gcrypt.h> -], [ return !!gcry_check_version(NULL); ], - [ echo "*** The test program compiled, but did not run. This usually means" - echo "*** that the run-time linker is not finding LIBGCRYPT or finding the wrong" - echo "*** version of LIBGCRYPT. If it is not finding LIBGCRYPT, you'll need to set your" - echo "*** LD_LIBRARY_PATH environment variable, or edit /etc/ld.so.conf to point" - echo "*** to the installed location Also, make sure you have run ldconfig if that" - echo "*** is required on your system" - echo "***" - echo "*** If you have an old version installed, it is best to remove it, although" - echo "*** you may also be able to get things to work by modifying LD_LIBRARY_PATH" - echo "***" ], - [ echo "*** The test program failed to compile or link. See the file config.log for the" - echo "*** exact error that occured. This usually means LIBGCRYPT was incorrectly installed" - echo "*** or that you have moved LIBGCRYPT since it was installed. In the latter case, you" - echo "*** may want to edit the libgcrypt-config script: $LIBGCRYPT_CONFIG" ]) - CFLAGS="$ac_save_CFLAGS" - LIBS="$ac_save_LIBS" - fi - fi - LIBGCRYPT_CFLAGS="" - LIBGCRYPT_LIBS="" - ifelse([$3], , :, [$3]) + LIBGCRYPT_CFLAGS="" + LIBGCRYPT_LIBS="" + AC_MSG_RESULT(no) + ifelse([$3], , :, [$3]) fi AC_SUBST(LIBGCRYPT_CFLAGS) AC_SUBST(LIBGCRYPT_LIBS) - rm -f conf.libgcrypttest ]) - -dnl *-*wedit:notab*-* Please keep this as the last line. |