diff options
author | Nikos Mavrogiannopoulos <nmav@gnutls.org> | 2003-10-25 09:54:19 +0000 |
---|---|---|
committer | Nikos Mavrogiannopoulos <nmav@gnutls.org> | 2003-10-25 09:54:19 +0000 |
commit | 4a288531e874f10a0c250ca52d1cd102bce4ffa6 (patch) | |
tree | e22a6e2ec6ff985cff60e1f62b14a0ea74da4de2 | |
parent | a617e053a680f037e8e7d08f40346cc65cb3f799 (diff) | |
download | gnutls-4a288531e874f10a0c250ca52d1cd102bce4ffa6.tar.gz |
Almost finished the X.509 certificate generation.
-rw-r--r-- | NEWS | 1 | ||||
-rw-r--r-- | doc/TODO | 1 | ||||
-rw-r--r-- | includes/gnutls/x509.h | 2 | ||||
-rw-r--r-- | lib/pkix.asn | 21 | ||||
-rw-r--r-- | lib/pkix_asn1_tab.c | 20 | ||||
-rw-r--r-- | lib/x509/common.c | 41 | ||||
-rw-r--r-- | lib/x509/common.h | 7 | ||||
-rw-r--r-- | lib/x509/dn.c | 90 | ||||
-rw-r--r-- | lib/x509/dn.h | 2 | ||||
-rw-r--r-- | lib/x509/sign.c | 2 | ||||
-rw-r--r-- | lib/x509/x509_write.c | 51 |
11 files changed, 89 insertions, 149 deletions
@@ -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. @@ -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 */ |