summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikos Mavrogiannopoulos <nmav@gnutls.org>2003-10-23 19:16:16 +0000
committerNikos Mavrogiannopoulos <nmav@gnutls.org>2003-10-23 19:16:16 +0000
commit98303f5328dce05ca179aaa05a5c09e40e69189d (patch)
tree7b05613599f744803567f3a7e67da5c66c0e206b
parent0b63f1a2b945ddf1d64cadc422af031f1509cc96 (diff)
downloadgnutls-98303f5328dce05ca179aaa05a5c09e40e69189d.tar.gz
Added some support for writable gnutls_x509_crt structures. Not ready yet.
-rw-r--r--NEWS3
-rw-r--r--THANKS2
-rw-r--r--configure.in2
-rw-r--r--includes/gnutls/x509.h26
-rw-r--r--lib/Makefile.am2
-rw-r--r--lib/pkix.asn21
-rw-r--r--lib/pkix_asn1_tab.c20
-rw-r--r--lib/x509/Makefile.am2
-rw-r--r--lib/x509/common.c257
-rw-r--r--lib/x509/common.h9
-rw-r--r--lib/x509/crq.c116
-rw-r--r--lib/x509/crq.h6
-rw-r--r--lib/x509/dn.c90
-rw-r--r--lib/x509/dn.h2
-rw-r--r--lib/x509/extensions.c84
-rw-r--r--lib/x509/extensions.h4
-rw-r--r--lib/x509/x509.c92
-rw-r--r--lib/x509/x509_write.c391
-rw-r--r--libgcrypt.m4199
19 files changed, 1004 insertions, 324 deletions
diff --git a/NEWS b/NEWS
index e2af7a4716..31b7da822c 100644
--- a/NEWS
+++ b/NEWS
@@ -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.
diff --git a/THANKS b/THANKS
index aa6c24999c..3a13c79723 100644
--- a/THANKS
+++ b/THANKS
@@ -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( &gtime, &_tm);
+
+ ret = strftime( str_time, str_time_size, "%y%m%d%H%M00Z", &_tm);
+#else
+struct tm* _tm;
+
+ _tm = gmtime( &gtime);
+
+ 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( &params[0]);
+ _gnutls_mpi_release( &params[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( &params[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( &params[0]);
- _gnutls_mpi_release( &params[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( &params[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.