summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--NEWS5
-rw-r--r--lib/includes/gnutls/x509.h3
-rw-r--r--lib/libgnutls.map1
-rw-r--r--lib/x509/x509_write.c135
-rw-r--r--src/certtool-args.def6
-rw-r--r--src/certtool-cfg.c58
-rw-r--r--src/certtool-cfg.h2
-rw-r--r--src/certtool.c2
8 files changed, 210 insertions, 2 deletions
diff --git a/NEWS b/NEWS
index 45c7a6396f..f747ce085c 100644
--- a/NEWS
+++ b/NEWS
@@ -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)
{