diff options
-rw-r--r-- | NEWS | 5 | ||||
-rw-r--r-- | lib/includes/gnutls/x509.h | 3 | ||||
-rw-r--r-- | lib/libgnutls.map | 1 | ||||
-rw-r--r-- | lib/x509/x509_write.c | 135 | ||||
-rw-r--r-- | src/certtool-args.def | 6 | ||||
-rw-r--r-- | src/certtool-cfg.c | 58 | ||||
-rw-r--r-- | src/certtool-cfg.h | 2 | ||||
-rw-r--r-- | src/certtool.c | 2 |
8 files changed, 210 insertions, 2 deletions
@@ -14,10 +14,11 @@ See the end for copying conditions. line option. ** certtool: The template option allows for setting the domain -component (DC) option of the distinguished name. +component (DC) option of the distinguished name, and the ocsp_uri +as well as the ca_issuers_uri options. ** API and ABI modifications: -No changes since last version. +gnutls_x509_crt_set_authority_info_access: Added * Version 3.0.15 (released 2012-03-02) diff --git a/lib/includes/gnutls/x509.h b/lib/includes/gnutls/x509.h index a0b11f1418..ac6de53595 100644 --- a/lib/includes/gnutls/x509.h +++ b/lib/includes/gnutls/x509.h @@ -295,6 +295,9 @@ extern "C" unsigned int *critical); int gnutls_x509_crt_set_key_usage (gnutls_x509_crt_t crt, unsigned int usage); + int gnutls_x509_crt_set_authority_info_access (gnutls_x509_crt_t crt, + int what, + gnutls_datum_t * data); int gnutls_x509_crt_get_proxy (gnutls_x509_crt_t cert, unsigned int *critical, diff --git a/lib/libgnutls.map b/lib/libgnutls.map index 5849918055..519d5fcbd7 100644 --- a/lib/libgnutls.map +++ b/lib/libgnutls.map @@ -780,6 +780,7 @@ GNUTLS_3_0_0 { gnutls_tdb_set_store_commitment_func; gnutls_tdb_set_verify_func; gnutls_tdb_deinit; + gnutls_x509_crt_set_authority_info_access; } GNUTLS_2_12; GNUTLS_PRIVATE { diff --git a/lib/x509/x509_write.c b/lib/x509/x509_write.c index 4e3149357b..e2a28c4e85 100644 --- a/lib/x509/x509_write.c +++ b/lib/x509/x509_write.c @@ -1337,3 +1337,138 @@ gnutls_x509_crt_privkey_sign (gnutls_x509_crt_t crt, gnutls_x509_crt_t issuer, return 0; } + +static const char* what_to_oid(int what) +{ + switch(what) + { + case GNUTLS_IA_OCSP_URI: + return GNUTLS_OID_AD_OCSP; + case GNUTLS_IA_CAISSUERS_URI: + return GNUTLS_OID_AD_CAISSUERS; + default: + return NULL; + } +} + +/** + * gnutls_x509_crt_set_authority_info_access: + * @crt: Holds the certificate + * @what: what data to get, a #gnutls_info_access_what_t type. + * @data: output data to be freed with gnutls_free(). + * + * This function sets the Authority Information Access (AIA) + * extension, see RFC 5280 section 4.2.2.1 for more information. + * + * The type of data stored in @data is specified via @what which + * should be #gnutls_info_access_what_t values. + * + * If @what is %GNUTLS_IA_OCSP_URI, @data will hold the OCSP URI. + * If @what is %GNUTLS_IA_CAISSUERS_URI, @data will hold the caIssuers + * URI. + * + * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a + * negative error value. + * + * Since: 3.0 + **/ +int +gnutls_x509_crt_set_authority_info_access (gnutls_x509_crt_t crt, + int what, + gnutls_datum_t * data) +{ + int ret, result; + gnutls_datum_t aia = { NULL, 0 }; + gnutls_datum_t der_data = { NULL, 0 }; + ASN1_TYPE c2 = ASN1_TYPE_EMPTY; + const char* oid; + unsigned int c; + + if (crt == NULL) + return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST); + + oid = what_to_oid(what); + if (oid == NULL) + return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST); + + ret = asn1_create_element (_gnutls_get_pkix (), + "PKIX1.AuthorityInfoAccessSyntax", &c2); + if (ret != ASN1_SUCCESS) + { + gnutls_assert (); + return _gnutls_asn2err (ret); + } + + ret = _gnutls_x509_crt_get_extension (crt, GNUTLS_OID_AIA, 0, &aia, + &c); + if (ret >= 0) /* decode it */ + { + ret = asn1_der_decoding (&c2, aia.data, aia.size, NULL); + if (ret != ASN1_SUCCESS) + { + gnutls_assert (); + ret = _gnutls_asn2err (ret); + goto cleanup; + } + } + + /* generate the extension. + */ + /* 1. create a new element. + */ + result = asn1_write_value (c2, "", "NEW", 1); + if (result != ASN1_SUCCESS) + { + gnutls_assert (); + ret = _gnutls_asn2err (result); + goto cleanup; + } + + /* 2. Add the OID. + */ + result = asn1_write_value (c2, "?LAST.accessMethod", oid, 1); + if (result != ASN1_SUCCESS) + { + gnutls_assert (); + ret = _gnutls_asn2err (result); + goto cleanup; + } + + /* accessLocation is a choice */ + result = asn1_write_value (c2, "?LAST.accessLocation", "uniformResourceIdentifier", 1); + if (result != ASN1_SUCCESS) + { + gnutls_assert (); + ret = _gnutls_asn2err (result); + goto cleanup; + } + + result = asn1_write_value (c2, "?LAST.accessLocation.uniformResourceIdentifier", data->data, data->size); + if (result != ASN1_SUCCESS) + { + gnutls_assert (); + ret = _gnutls_asn2err (result); + goto cleanup; + } + + ret = _gnutls_x509_der_encode (c2, "", &der_data, 0); + if (ret < 0) + { + gnutls_assert (); + goto cleanup; + } + + ret = _gnutls_x509_crt_set_extension (crt, GNUTLS_OID_AIA, + &der_data, 0); + if (ret < 0) + gnutls_assert (); + + crt->use_extensions = 1; + +cleanup: + _gnutls_free_datum (&der_data); + _gnutls_free_datum(&aia); + asn1_delete_structure (&c2); + + return ret; +} diff --git a/src/certtool-args.def b/src/certtool-args.def index c9726af496..27d14d9b6d 100644 --- a/src/certtool-args.def +++ b/src/certtool-args.def @@ -616,6 +616,12 @@ signing_key #path_len = -1 #path_len = 2 +# OCSP URI +# ocsp_uri = http://my.ocsp.server/ocsp + +# CA issuers URI +# ca_issuers_uri = http://my.ca.issuer + # Options for proxy certificates # proxy_policy_language = 1.3.6.1.5.5.7.21.1 diff --git a/src/certtool-cfg.c b/src/certtool-cfg.c index f92a5075b9..d47ef764ef 100644 --- a/src/certtool-cfg.c +++ b/src/certtool-cfg.c @@ -88,6 +88,8 @@ typedef struct _cfg_ctx int crl_number; int crq_extensions; char *proxy_policy_language; + char **ocsp_uris; + char **ca_issuers_uris; } cfg_ctx; cfg_ctx cfg; @@ -254,6 +256,9 @@ template_parse (const char *template) val = optionGetValue(pov, "proxy_policy_language"); if (val != NULL && val->valType == OPARG_TYPE_STRING) cfg.proxy_policy_language = strdup(val->v.strVal); + + READ_MULTI_LINE("ocsp_uri", cfg.ocsp_uris); + READ_MULTI_LINE("ca_issuers_uri", cfg.ca_issuers_uris); READ_BOOLEAN("ca", cfg.ca); READ_BOOLEAN("honor_crq_extensions", cfg.crq_extensions); @@ -704,7 +709,60 @@ get_key_purpose_set (gnutls_x509_crt_t crt) } } } +} + +void +get_ocsp_issuer_set (gnutls_x509_crt_t crt) +{ + int ret, i; + gnutls_datum_t uri; + + if (batch) + { + if (!cfg.ocsp_uris) + return; + for (i = 0; cfg.ocsp_uris[i] != NULL; i++) + { + uri.data = cfg.ocsp_uris[i]; + uri.size = strlen(cfg.ocsp_uris[i]); + ret = + gnutls_x509_crt_set_authority_info_access (crt, GNUTLS_IA_OCSP_URI, + &uri); + if (ret < 0) + { + fprintf (stderr, "set OCSP URI (%s): %s\n", + cfg.ocsp_uris[i], gnutls_strerror (ret)); + exit (1); + } + } + } +} +void +get_ca_issuers_set (gnutls_x509_crt_t crt) +{ + int ret, i; + gnutls_datum_t uri; + + if (batch) + { + if (!cfg.ca_issuers_uris) + return; + for (i = 0; cfg.ca_issuers_uris[i] != NULL; i++) + { + uri.data = cfg.ca_issuers_uris[i]; + uri.size = strlen(cfg.ca_issuers_uris[i]); + ret = + gnutls_x509_crt_set_authority_info_access (crt, GNUTLS_IA_CAISSUERS_URI, + &uri); + if (ret < 0) + { + fprintf (stderr, "set CA ISSUERS URI (%s): %s\n", + cfg.ca_issuers_uris[i], gnutls_strerror (ret)); + exit (1); + } + } + } } diff --git a/src/certtool-cfg.h b/src/certtool-cfg.h index 9587f8635e..5181425ae2 100644 --- a/src/certtool-cfg.h +++ b/src/certtool-cfg.h @@ -70,6 +70,8 @@ void get_dns_name_set (int type, void *crt); void get_email_set (int type, void *crt); int get_ipsec_ike_status (void); void get_dc_set (int type, void *crt); +void get_ca_issuers_set (gnutls_x509_crt_t crt); +void get_ocsp_issuer_set (gnutls_x509_crt_t crt); void get_cn_crq_set (gnutls_x509_crq_t crq); void get_uid_crq_set (gnutls_x509_crq_t crq); diff --git a/src/certtool.c b/src/certtool.c index a8bd26b67c..df2303304f 100644 --- a/src/certtool.c +++ b/src/certtool.c @@ -584,6 +584,8 @@ generate_certificate (gnutls_privkey_t * ret_key, gnutls_strerror (result)); } } + get_ocsp_issuer_set(crt); + get_ca_issuers_set(crt); if (usage != 0) { |