summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikos Mavrogiannopoulos <nmav@gnutls.org>2003-10-25 09:54:19 +0000
committerNikos Mavrogiannopoulos <nmav@gnutls.org>2003-10-25 09:54:19 +0000
commit4a288531e874f10a0c250ca52d1cd102bce4ffa6 (patch)
treee22a6e2ec6ff985cff60e1f62b14a0ea74da4de2
parenta617e053a680f037e8e7d08f40346cc65cb3f799 (diff)
downloadgnutls-4a288531e874f10a0c250ca52d1cd102bce4ffa6.tar.gz
Almost finished the X.509 certificate generation.
-rw-r--r--NEWS1
-rw-r--r--doc/TODO1
-rw-r--r--includes/gnutls/x509.h2
-rw-r--r--lib/pkix.asn21
-rw-r--r--lib/pkix_asn1_tab.c20
-rw-r--r--lib/x509/common.c41
-rw-r--r--lib/x509/common.h7
-rw-r--r--lib/x509/dn.c90
-rw-r--r--lib/x509/dn.h2
-rw-r--r--lib/x509/sign.c2
-rw-r--r--lib/x509/x509_write.c51
11 files changed, 89 insertions, 149 deletions
diff --git a/NEWS b/NEWS
index 31b7da822c..38810e67f9 100644
--- a/NEWS
+++ b/NEWS
@@ -1,5 +1,6 @@
Version 0.9.92
- The RFC2818 hostname verification is now case insensitive.
+- Added support for generating X.509 certificates.
Version 0.9.91 (17/10/2003)
- Fixed a compilation issue in the openpgp authentication part.
diff --git a/doc/TODO b/doc/TODO
index 1ffbb96bd1..deacafc4b2 100644
--- a/doc/TODO
+++ b/doc/TODO
@@ -5,7 +5,6 @@ in order to avoid having people working on the same thing.
Current list:
* Add a callback function in certificate authentication, to receive
the certificate and the private key.
-* Add support for writing to X.509 certificates
* Add support for generating and handling DSA keys
* Convert documentation to texinfo format
* Audit the code
diff --git a/includes/gnutls/x509.h b/includes/gnutls/x509.h
index 425e6b96a0..f40076e5a6 100644
--- a/includes/gnutls/x509.h
+++ b/includes/gnutls/x509.h
@@ -120,7 +120,6 @@ 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
@@ -293,6 +292,7 @@ int gnutls_x509_crq_get_challenge_password(gnutls_x509_crq crq,
int gnutls_x509_crq_export( gnutls_x509_crq crq,
gnutls_x509_crt_fmt format, unsigned char* output_data, size_t* output_data_size);
+int gnutls_x509_crt_set_crq(gnutls_x509_crt crt, gnutls_x509_crq crq);
#ifdef __cplusplus
diff --git a/lib/pkix.asn b/lib/pkix.asn
index 9902e781d6..aa9ac0ec1e 100644
--- a/lib/pkix.asn
+++ b/lib/pkix.asn
@@ -539,27 +539,6 @@ 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 1954899c5b..9922313d05 100644
--- a/lib/pkix_asn1_tab.c
+++ b/lib/pkix_asn1_tab.c
@@ -533,26 +533,6 @@ 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/common.c b/lib/x509/common.c
index b86db3ac65..c7ce6fb5c1 100644
--- a/lib/x509/common.c
+++ b/lib/x509/common.c
@@ -549,7 +549,7 @@ int _gnutls_x509_set_time(ASN1_TYPE c2, const char *where, time_t tim)
_gnutls_str_cpy(name, sizeof(name), where);
- if ((result = asn1_write_value(c2, name, "UTCTime", 1)) < 0) {
+ if ((result = asn1_write_value(c2, name, "utcTime", 1)) < 0) {
gnutls_assert();
return _gnutls_asn2err(result);
}
@@ -1087,3 +1087,42 @@ char name[128];
gnutls_free(str);
return algo;
}
+
+ASN1_TYPE _asn1_find_node(ASN1_TYPE pointer,const char *name);
+
+int _gnutls_asn1_copy_node( ASN1_TYPE *dst, const char* dst_name,
+ ASN1_TYPE src, const char* src_name)
+{
+
+ int result;
+ gnutls_datum der;
+ ASN1_TYPE dst_node;
+
+ result = _gnutls_x509_der_encode( src, src_name, &der, 0);
+ if (result < 0) {
+ gnutls_assert();
+ return result;
+ }
+
+ dst_node=_asn1_find_node(*dst, dst_name);
+ if(dst_node==NULL) {
+ gnutls_assert();
+ return _gnutls_asn2err(ASN1_ELEMENT_NOT_FOUND);
+ }
+
+ result = asn1_der_decoding( &dst_node, der.data, der.size, NULL);
+
+#if 0
+ result = asn1_der_decoding_element( dst, dst_name, der.data,
+ der.size, NULL);
+#endif
+
+ _gnutls_free_datum( &der);
+
+ if (result != ASN1_SUCCESS) {
+ gnutls_assert();
+ return _gnutls_asn2err(result);
+ }
+
+ return 0;
+}
diff --git a/lib/x509/common.h b/lib/x509/common.h
index 3878714d82..6f286fafb4 100644
--- a/lib/x509/common.h
+++ b/lib/x509/common.h
@@ -58,7 +58,10 @@ 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);
+
+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_asn1_copy_node( ASN1_TYPE *dst, const char* dst_name,
+ ASN1_TYPE src, const char* src_name);
diff --git a/lib/x509/dn.c b/lib/x509/dn.c
index 242ed35cb6..35f6146363 100644
--- a/lib/x509/dn.c
+++ b/lib/x509/dn.c
@@ -285,96 +285,6 @@ 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 93aa209f14..dd6d731c27 100644
--- a/lib/x509/dn.h
+++ b/lib/x509/dn.h
@@ -17,8 +17,6 @@ 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/sign.c b/lib/x509/sign.c
index 790fc66f5d..d1708121db 100644
--- a/lib/x509/sign.c
+++ b/lib/x509/sign.c
@@ -219,7 +219,7 @@ gnutls_datum tbs;
}
result = asn1_der_coding( cert, tbs_name, buf, &buf_size, NULL);
-
+
if (result != ASN1_SUCCESS) {
gnutls_assert();
gnutls_afree(buf);
diff --git a/lib/x509/x509_write.c b/lib/x509/x509_write.c
index bb38dd34f9..a35d4882a2 100644
--- a/lib/x509/x509_write.c
+++ b/lib/x509/x509_write.c
@@ -161,9 +161,7 @@ int result;
**/
int gnutls_x509_crt_set_crq(gnutls_x509_crt crt, gnutls_x509_crq crq)
{
-const char* pk;
-opaque * der;
-int der_size, result;
+int result;
int pk_algorithm;
pk_algorithm = gnutls_x509_crq_get_pk_algorithm( crq, NULL);
@@ -172,8 +170,20 @@ int pk_algorithm;
gnutls_assert();
return GNUTLS_E_UNIMPLEMENTED_FEATURE;
}
+
+ result = _gnutls_asn1_copy_node( &crt->cert, "tbsCertificate.subject",
+ crq->crq, "subject");
+ if (result < 0) {
+ gnutls_assert();
+ return result;
+ }
-#warning PUT SOME CODE HERE
+ result = _gnutls_asn1_copy_node( &crt->cert, "tbsCertificate.subjectPublicKeyInfo",
+ crq->crq, "subjectPKInfo");
+ if (result < 0) {
+ gnutls_assert();
+ return result;
+ }
return 0;
}
@@ -247,12 +257,38 @@ const char* pk;
/* Step 1. Copy the issuer's name into the certificate.
*/
- result = _gnutls_x509_copy_cert_dn( &crt->cert, issuer->cert);
+ result = _gnutls_asn1_copy_node( &crt->cert, "tbsCertificate.issuer",
+ issuer->cert, "tbsCertificate.subject");
if (result < 0) {
gnutls_assert();
return result;
}
+ /* Step 1.5. Write the signature stuff in the tbsCertificate.
+ */
+ /* write the RSA OID
+ */
+ pk = _gnutls_x509_sign2oid( issuer_key->pk_algorithm, GNUTLS_MAC_SHA);
+ if (pk == NULL) {
+ gnutls_assert();
+ return GNUTLS_E_INVALID_REQUEST;
+ }
+
+ result = asn1_write_value( crt->cert, "tbsCertificate.signature.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, "tbsCertificate.signature.parameters", NULL, 0);
+ if (result != ASN1_SUCCESS) {
+ gnutls_assert();
+ return _gnutls_asn2err(result);
+ }
+
+
/* Step 2. Sign the certificate.
*/
result = _gnutls_x509_sign_tbs( crt->cert, "tbsCertificate", GNUTLS_MAC_SHA,
@@ -278,11 +314,6 @@ const char* pk;
* 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
*/