From: Simon Josefsson Date: Wed, 31 Jan 2007 14:20:44 +0000 (+0000) Subject: Add proxy certificate APIs. X-Git-Tag: gnutls_1_7_3~22 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=404150406bfc11cdc4163d76755d7b65d754cc68;p=thirdparty%2Fgnutls.git Add proxy certificate APIs. --- diff --git a/NEWS b/NEWS index 093ccfd4e8..aeebd83300 100644 --- a/NEWS +++ b/NEWS @@ -22,8 +22,12 @@ Reported and tiny patch provided by Matthias Scheler . ** Fix import of ASCII armored OpenPGP keys. Patch by ludovic.courtes@laas.fr (Ludovic Courtès). +** New APIs to set proxy subject names and add proxy cert extension. +This makes it possible to generate Proxy Certificates using GnuTLS. + ** API and ABI modifications: -No changes since last version. +gnutls_x509_crt_set_proxy_dn: ADD. +gnutls_x509_crt_set_proxy: ADD. * Version 1.7.2 (released 2007-01-14) diff --git a/includes/gnutls/x509.h b/includes/gnutls/x509.h index 62d6847698..828435cdb5 100644 --- a/includes/gnutls/x509.h +++ b/includes/gnutls/x509.h @@ -257,6 +257,16 @@ extern "C" int gnutls_x509_crt_set_subject_key_id (gnutls_x509_crt_t cert, const void *id, size_t id_size); + int gnutls_x509_crt_set_proxy_dn (gnutls_x509_crt_t crt, + gnutls_x509_crt_t eecrt, + unsigned int raw_flag, + const void *name, + unsigned int sizeof_name); + int gnutls_x509_crt_set_proxy (gnutls_x509_crt_t crt, + int pathLenConstraint, + const char *policyLanguage, + const char *policy, + size_t sizeof_policy); /* RDN handling. */ diff --git a/lib/pkix.asn b/lib/pkix.asn index 979ff9c0ac..10876c252a 100644 --- a/lib/pkix.asn +++ b/lib/pkix.asn @@ -1215,4 +1215,19 @@ id-pda-countryOfResidence AttributeType ::= { id-pda 5 } CountryOfResidence ::= PrintableString (SIZE (2)) -- ISO 3166 Country Code +-- rfc3820 + +id-pe-proxyCertInfo OBJECT IDENTIFIER ::= { id-pe 14 } + +id-ppl-inheritAll OBJECT IDENTIFIER ::= { id-pkix 21 1 } +id-ppl-independent OBJECT IDENTIFIER ::= { id-pkix 21 2 } + +ProxyCertInfo ::= SEQUENCE { + pCPathLenConstraint INTEGER (0..MAX) OPTIONAL, + proxyPolicy ProxyPolicy } + +ProxyPolicy ::= SEQUENCE { + policyLanguage OBJECT IDENTIFIER, + policy OCTET STRING OPTIONAL } + END diff --git a/lib/pkix_asn1_tab.c b/lib/pkix_asn1_tab.c index b25bf5b187..fae87548c3 100644 --- a/lib/pkix_asn1_tab.c +++ b/lib/pkix_asn1_tab.c @@ -1091,7 +1091,25 @@ extern const ASN1_ARRAY_TYPE pkix_asn1_tab[]={ {"id-pda-countryOfResidence",1880096780,"AttributeType"}, {0,1073741825,"id-pda"}, {0,1,"5"}, - {"CountryOfResidence",538968066,"PrintableString"}, + {"CountryOfResidence",1612709890,"PrintableString"}, {0,1048586,"2"}, + {"id-pe-proxyCertInfo",1879048204,0}, + {0,1073741825,"id-pe"}, + {0,1,"14"}, + {"id-ppl-inheritAll",1879048204,0}, + {0,1073741825,"id-pkix"}, + {0,1073741825,"21"}, + {0,1,"1"}, + {"id-ppl-independent",1879048204,0}, + {0,1073741825,"id-pkix"}, + {0,1073741825,"21"}, + {0,1,"2"}, + {"ProxyCertInfo",1610612741,0}, + {"pCPathLenConstraint",1611153411,0}, + {"0",10,"MAX"}, + {"proxyPolicy",2,"ProxyPolicy"}, + {"ProxyPolicy",536870917,0}, + {"policyLanguage",1073741836,0}, + {"policy",16391,0}, {0,0,0} }; diff --git a/lib/x509/extensions.c b/lib/x509/extensions.c index 38f46bb35d..6b2238d780 100644 --- a/lib/x509/extensions.c +++ b/lib/x509/extensions.c @@ -945,3 +945,71 @@ cleanup: return result; } + +/* generate the proxyCertInfo in a DER encoded extension + */ +int +_gnutls_x509_ext_gen_proxyCertInfo (int pathLenConstraint, + const char *policyLanguage, + const char *policy, + size_t sizeof_policy, + gnutls_datum_t * der_ext) +{ + ASN1_TYPE ext = ASN1_TYPE_EMPTY; + const char *str; + int result; + + result = asn1_create_element (_gnutls_get_pkix (), + "PKIX1.ProxyCertInfo", &ext); + if (result != ASN1_SUCCESS) + { + gnutls_assert (); + return _gnutls_asn2err (result); + } + + if (pathLenConstraint < 0) + { + result = asn1_write_value (ext, "pCPathLenConstraint", NULL, 0); + if (result < 0) + result = _gnutls_asn2err (result); + } + else + result = _gnutls_x509_write_uint32 (ext, "pCPathLenConstraint", + pathLenConstraint); + if (result < 0) + { + gnutls_assert (); + asn1_delete_structure (&ext); + return result; + } + + result = asn1_write_value (ext, "proxyPolicy.policyLanguage", + policyLanguage, 1); + if (result < 0) + { + gnutls_assert (); + asn1_delete_structure (&ext); + return _gnutls_asn2err (result); + } + + result = asn1_write_value (ext, "proxyPolicy.policy", + policy, sizeof_policy); + if (result < 0) + { + 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 1ef5fcfe5f..bcb8bbf9b2 100644 --- a/lib/x509/extensions.h +++ b/lib/x509/extensions.h @@ -55,3 +55,8 @@ int _gnutls_x509_ext_gen_key_id (const void *id, size_t id_size, gnutls_datum_t * der_data); int _gnutls_x509_ext_gen_auth_key_id (const void *id, size_t id_size, gnutls_datum_t * der_data); +int _gnutls_x509_ext_gen_proxyCertInfo (int pathLenConstraint, + const char *policyLanguage, + const char *policy, + size_t sizeof_policy, + gnutls_datum_t * der_ext); diff --git a/lib/x509/x509_write.c b/lib/x509/x509_write.c index 6c8753d986..00441150be 100644 --- a/lib/x509/x509_write.c +++ b/lib/x509/x509_write.c @@ -117,6 +117,47 @@ gnutls_x509_crt_set_issuer_dn_by_oid (gnutls_x509_crt_t crt, raw_flag, name, sizeof_name); } +/** + * gnutls_x509_crt_set_proxy_dn - Set Proxy Certificate subject's distinguished name + * @crt: a gnutls_x509_crt_t structure with the new proxy cert + * @eecrt: the end entity certificate that will be issuing the proxy + * @raw_flag: must be 0, or 1 if the CN is DER encoded + * @name: a pointer to the CN name + * @sizeof_name: holds the size of @name + * + * This function will set the subject in @crt to the end entity's + * @eecrt subject name, and add a single Common Name component @name + * of size @sizeof_name. This corresponds to the required proxy + * certificate naming style. + * + * Returns 0 on success. + * + **/ +int +gnutls_x509_crt_set_proxy_dn (gnutls_x509_crt_t crt,gnutls_x509_crt_t eecrt, + unsigned int raw_flag, const void *name, + unsigned int sizeof_name) +{ + int result; + + if (sizeof_name == 0 || name == NULL || crt == NULL || eecrt == NULL) + { + return GNUTLS_E_INVALID_REQUEST; + } + + result = asn1_copy_node (crt->cert, "tbsCertificate.subject", + eecrt->cert, "tbsCertificate.subject"); + if (result != ASN1_SUCCESS) + { + gnutls_assert (); + return _gnutls_asn2err (result); + } + + return _gnutls_x509_set_dn_oid (crt->cert, "tbsCertificate.subject", + GNUTLS_OID_X520_COMMON_NAME, + raw_flag, name, sizeof_name); +} + /** * gnutls_x509_crt_set_version - This function will set the Certificate request version * @crt: should contain a gnutls_x509_crt_t structure @@ -282,7 +323,7 @@ gnutls_x509_crt_set_extension_by_oid (gnutls_x509_crt_t crt, } /** - * gnutls_x509_crt_set_ca_status - This function will set the basicConstraints extension + * gnutls_x509_crt_set_basic_constraints - This function will set the basicConstraints extension * @crt: should contain a gnutls_x509_crt_t structure * @ca: true(1) or false(0). Depending on the Certificate authority status. * @pathLenConstraint: non-negative values indicate maximum length of path, @@ -462,6 +503,65 @@ gnutls_x509_crt_set_subject_alternative_name (gnutls_x509_crt_t crt, return 0; } +/** + * gnutls_x509_crt_set_proxy - Set the proxyCertInfo extension + * @crt: should contain a gnutls_x509_crt_t structure + * @pathLenConstraint: non-negative values indicate maximum length of path, + * and negative values indicate that the pathLenConstraints field should + * not be present. + * @policyLanguage: OID describing the language of @policy. + * @policy: opaque byte array with policy language, can be %NULL + * @sizeof_policy: size of @policy. + * + * This function will set the proxyCertInfo extension. + * + * Returns 0 on success. + * + **/ +int +gnutls_x509_crt_set_proxy (gnutls_x509_crt_t crt, + int pathLenConstraint, + const char *policyLanguage, + const char *policy, + size_t sizeof_policy) +{ + int result; + gnutls_datum_t der_data; + + if (crt == NULL) + { + gnutls_assert (); + return GNUTLS_E_INVALID_REQUEST; + } + + /* generate the extension. + */ + result = _gnutls_x509_ext_gen_proxyCertInfo (pathLenConstraint, + policyLanguage, + policy, sizeof_policy, + &der_data); + if (result < 0) + { + gnutls_assert (); + return result; + } + + result = _gnutls_x509_crt_set_extension (crt, "1.3.6.1.5.5.7.1.14", + &der_data, 1); + + _gnutls_free_datum (&der_data); + + if (result < 0) + { + gnutls_assert (); + return result; + } + + crt->use_extensions = 1; + + return 0; +} + /** * gnutls_x509_crt_sign2 - This function will sign a certificate with a key * @crt: should contain a gnutls_x509_crt_t structure