summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorNikos Mavrogiannopoulos <nmav@redhat.com>2016-07-11 11:43:10 +0200
committerGitLab <gitlab@gitlab.com>2016-07-13 12:28:11 +0000
commitac51009cc237141c8787a49b75226a2f87f124f5 (patch)
tree1620dabbd2615585df97c32abf118031eec66088 /src
parent2f88e2b5b4b27ad67d68d6d4ad872a2b2fb93f9e (diff)
downloadgnutls-ac51009cc237141c8787a49b75226a2f87f124f5.tar.gz
certtool: added options to set arbitrary extensions to certificates and requests
This allows setting arbitrary extensions using the following new template options: add_extension = "5.6.7.8 0x0001020304050607AAABCD" add_critical_extension = "9.10.11.12.13.14.15.16.17.1.5 0xCAFE" The "0x" prefix can be omitted.
Diffstat (limited to 'src')
-rw-r--r--src/certtool-args.def8
-rw-r--r--src/certtool-cfg.c89
-rw-r--r--src/certtool-cfg.h1
-rw-r--r--src/certtool.c2
4 files changed, 100 insertions, 0 deletions
diff --git a/src/certtool-args.def b/src/certtool-args.def
index 931cbe8832..e0325b00f2 100644
--- a/src/certtool-args.def
+++ b/src/certtool-args.def
@@ -903,6 +903,14 @@ encryption_key
### end of key purpose OIDs
+### Adding arbitrary extensions
+# This requires to provide the extension OIDs, as well as the extension data in
+# hex format.
+#add_extension = "1.2.3.4 0x0AAB01ACFE"
+
+# For portability critical extensions shouldn't be set to certificates.
+#add_critical_extension = "5.6.7.8 0x1AAB01ACFE"
+
# When generating a certificate from a certificate
# request, then honor the extensions stored in the request
# and store them in the real certificate.
diff --git a/src/certtool-cfg.c b/src/certtool-cfg.c
index b5bef5ffb8..bd9ff4336b 100644
--- a/src/certtool-cfg.c
+++ b/src/certtool-cfg.c
@@ -97,6 +97,8 @@ static struct cfg_options available_options[] = {
{ .name = "nc_permit_ip", .type = OPTION_MULTI_LINE },
{ .name = "nc_permit_email", .type = OPTION_MULTI_LINE },
{ .name = "dn_oid", .type = OPTION_MULTI_LINE },
+ { .name = "add_extension", .type = OPTION_MULTI_LINE },
+ { .name = "add_critical_extension", .type = OPTION_MULTI_LINE },
{ .name = "crl_dist_points", .type = OPTION_MULTI_LINE },
{ .name = "ocsp_uri", .type = OPTION_MULTI_LINE },
{ .name = "ca_issuers_uri", .type = OPTION_MULTI_LINE },
@@ -172,6 +174,8 @@ typedef struct _cfg_ctx {
char **other_name_octet;
char **xmpp_name;
char **dn_oid;
+ char **extensions;
+ char **crit_extensions;
char **permitted_nc_ip;
char **excluded_nc_ip;
char **permitted_nc_dns;
@@ -486,6 +490,9 @@ int template_parse(const char *template)
READ_MULTI_LINE_TOKENIZED("dn_oid", cfg.dn_oid);
+ READ_MULTI_LINE_TOKENIZED("add_extension", cfg.extensions);
+ READ_MULTI_LINE_TOKENIZED("add_critical_extension", cfg.crit_extensions);
+
READ_MULTI_LINE("crl_dist_points", cfg.crl_dist_points);
val = optionGetValue(pov, "pkcs12_key_name");
@@ -1222,6 +1229,88 @@ void get_oid_crt_set(gnutls_x509_crt_t crt)
}
}
+void get_extensions_crt_set(int type, void *crt)
+{
+ int ret, i;
+ unsigned char *raw = NULL;
+ unsigned raw_size;
+ char *p;
+
+ if (batch) {
+ if (!cfg.extensions)
+ return;
+ for (i = 0; cfg.extensions[i] != NULL; i += 2) {
+ if (cfg.extensions[i + 1] == NULL) {
+ fprintf(stderr,
+ "extensions: %s does not have an argument.\n",
+ cfg.extensions[i]);
+ exit(1);
+ }
+
+ /* convert hex to bin */
+ if (strncmp(cfg.extensions[i+1], "0x", 2) == 0)
+ p = cfg.extensions[i+1]+2;
+ else
+ p = cfg.extensions[i+1];
+ HEX_DECODE(p, raw, raw_size);
+
+ if (type == TYPE_CRT)
+ ret =
+ gnutls_x509_crt_set_extension_by_oid(crt,
+ cfg.extensions[i],
+ raw, raw_size, 0);
+ else
+ ret =
+ gnutls_x509_crq_set_extension_by_oid(crt,
+ cfg.extensions[i],
+ raw, raw_size, 0);
+
+ gnutls_free(raw);
+ if (ret < 0) {
+ fprintf(stderr, "set_extensions: %s\n",
+ gnutls_strerror(ret));
+ exit(1);
+ }
+ }
+
+ if (!cfg.crit_extensions)
+ return;
+ for (i = 0; cfg.crit_extensions[i] != NULL; i += 2) {
+ if (cfg.crit_extensions[i + 1] == NULL) {
+ fprintf(stderr,
+ "extensions: %s does not have an argument.\n",
+ cfg.crit_extensions[i]);
+ exit(1);
+ }
+ /* convert hex to bin */
+ if (strncmp(cfg.crit_extensions[i+1], "0x", 2) == 0)
+ p = cfg.crit_extensions[i+1]+2;
+ else
+ p = cfg.crit_extensions[i+1];
+ HEX_DECODE(p, raw, raw_size);
+
+ if (type == TYPE_CRT)
+ ret =
+ gnutls_x509_crt_set_extension_by_oid(crt,
+ cfg.crit_extensions[i],
+ raw, raw_size, 1);
+ else
+ ret =
+ gnutls_x509_crq_set_extension_by_oid(crt,
+ cfg.crit_extensions[i],
+ raw, raw_size, 1);
+
+ gnutls_free(raw);
+
+ if (ret < 0) {
+ fprintf(stderr, "set_extensions: %s\n",
+ gnutls_strerror(ret));
+ exit(1);
+ }
+ }
+ }
+}
+
void get_key_purpose_set(int type, void *crt)
{
int ret, i;
diff --git a/src/certtool-cfg.h b/src/certtool-cfg.h
index 2c54d7f1af..8d1daadca9 100644
--- a/src/certtool-cfg.h
+++ b/src/certtool-cfg.h
@@ -75,6 +75,7 @@ int get_sign_status(int server);
void get_ip_addr_set(int type, void *crt);
void get_dns_name_set(int type, void *crt);
void get_other_name_set(int type, void *crt);
+void get_extensions_crt_set(int type, void *crt);
void get_policy_set(gnutls_x509_crt_t);
void get_uri_set(int type, void *crt);
void get_email_set(int type, void *crt);
diff --git a/src/certtool.c b/src/certtool.c
index 28d7893f57..e6563ea8b8 100644
--- a/src/certtool.c
+++ b/src/certtool.c
@@ -295,6 +295,7 @@ generate_certificate(gnutls_privkey_t * ret_key,
get_oid_crt_set(crt);
get_key_purpose_set(TYPE_CRT, crt);
+ get_extensions_crt_set(TYPE_CRT, crt);
if (!batch)
fprintf(stderr,
@@ -1985,6 +1986,7 @@ void generate_request(common_info_st * cinfo)
get_ip_addr_set(TYPE_CRQ, crq);
get_email_set(TYPE_CRQ, crq);
get_other_name_set(TYPE_CRQ, crq);
+ get_extensions_crt_set(TYPE_CRQ, crq);
pass = get_challenge_pass();