]> git.ipfire.org Git - thirdparty/gnutls.git/commitdiff
certtool: added options to set arbitrary extensions to certificates and requests
authorNikos Mavrogiannopoulos <nmav@redhat.com>
Mon, 11 Jul 2016 09:43:10 +0000 (11:43 +0200)
committerGitLab <gitlab@gitlab.com>
Wed, 13 Jul 2016 12:28:11 +0000 (12:28 +0000)
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.

src/certtool-args.def
src/certtool-cfg.c
src/certtool-cfg.h
src/certtool.c

index 931cbe8832ddf52b24668071a248b2a75d8608e3..e0325b00f2b1deaa68e9e5a5b1a44b8f9956c14f 100644 (file)
@@ -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.
index b5bef5ffb8d502b3ee69fb1251cb671567ba1f79..bd9ff4336b08ecfc89e1b92eea5e8e4f5a0720d7 100644 (file)
@@ -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;
index 2c54d7f1af560e70eab4a1dd92d97cd2b4d95f59..8d1daadca967a103f9ca54b5b64e62eef49489e9 100644 (file)
@@ -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);
index 28d7893f5730b2669c6dee4c1d3b1c7af080d5a7..e6563ea8b8a6eb2d0f936639275baca71be91020 100644 (file)
@@ -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();