diff options
author | Nikos Mavrogiannopoulos <nmav@redhat.com> | 2016-07-11 11:43:10 +0200 |
---|---|---|
committer | GitLab <gitlab@gitlab.com> | 2016-07-13 12:28:11 +0000 |
commit | ac51009cc237141c8787a49b75226a2f87f124f5 (patch) | |
tree | 1620dabbd2615585df97c32abf118031eec66088 /src | |
parent | 2f88e2b5b4b27ad67d68d6d4ad872a2b2fb93f9e (diff) | |
download | gnutls-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.def | 8 | ||||
-rw-r--r-- | src/certtool-cfg.c | 89 | ||||
-rw-r--r-- | src/certtool-cfg.h | 1 | ||||
-rw-r--r-- | src/certtool.c | 2 |
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(); |