2 * Copyright (C) 2004, 2005, 2006, 2007 Free Software Foundation
4 * This file is part of GNUTLS.
6 * GNUTLS is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * GNUTLS is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
25 #include <certtool-cfg.h>
27 #include <gnutls/x509.h>
33 /* Gnulib portability files. */
39 typedef struct _cfg_ctx
47 char *challenge_password
;
54 char *crl_dist_points
;
56 char *pkcs12_key_name
;
69 int time_stamping_key
;
71 char *proxy_policy_language
;
79 memset (&cfg
, 0, sizeof (cfg
));
85 template_parse (const char *template)
87 /* libcfg+ parsing context */
90 /* Parsing return code */
93 /* Option variables */
96 struct cfg_option options
[] = {
97 {NULL
, '\0', "organization", CFG_STR
, (void *) &cfg
.organization
,
99 {NULL
, '\0', "unit", CFG_STR
, (void *) &cfg
.unit
, 0},
100 {NULL
, '\0', "locality", CFG_STR
, (void *) &cfg
.locality
, 0},
101 {NULL
, '\0', "state", CFG_STR
, (void *) &cfg
.state
, 0},
102 {NULL
, '\0', "cn", CFG_STR
, (void *) &cfg
.cn
, 0},
103 {NULL
, '\0', "uid", CFG_STR
, (void *) &cfg
.uid
, 0},
104 {NULL
, '\0', "challenge_password", CFG_STR
,
105 (void *) &cfg
.challenge_password
, 0},
106 {NULL
, '\0', "password", CFG_STR
, (void *) &cfg
.password
, 0},
107 {NULL
, '\0', "pkcs9_email", CFG_STR
, (void *) &cfg
.pkcs9_email
, 0},
108 {NULL
, '\0', "country", CFG_STR
, (void *) &cfg
.country
, 0},
109 {NULL
, '\0', "dns_name", CFG_STR
, (void *) &cfg
.dns_name
, 0},
110 {NULL
, '\0', "ip_address", CFG_STR
, (void *) &cfg
.ip_addr
, 0},
111 {NULL
, '\0', "email", CFG_STR
, (void *) &cfg
.email
, 0},
113 {NULL
, '\0', "dn_oid", CFG_STR
+ CFG_MULTI_SEPARATED
,
114 (void *) &cfg
.dn_oid
, 0},
116 {NULL
, '\0', "crl_dist_points", CFG_STR
,
117 (void *) &cfg
.crl_dist_points
, 0},
118 {NULL
, '\0', "pkcs12_key_name", CFG_STR
,
119 (void *) &cfg
.pkcs12_key_name
, 0},
121 {NULL
, '\0', "serial", CFG_INT
, (void *) &cfg
.serial
, 0},
122 {NULL
, '\0', "expiration_days", CFG_INT
,
123 (void *) &cfg
.expiration_days
, 0},
125 {NULL
, '\0', "crl_next_update", CFG_INT
,
126 (void *) &cfg
.crl_next_update
, 0},
128 {NULL
, '\0', "ca", CFG_BOOL
, (void *) &cfg
.ca
, 0},
129 {NULL
, '\0', "path_len", CFG_INT
, (void *) &cfg
.path_len
, 0},
130 {NULL
, '\0', "tls_www_client", CFG_BOOL
,
131 (void *) &cfg
.tls_www_client
, 0},
132 {NULL
, '\0', "tls_www_server", CFG_BOOL
,
133 (void *) &cfg
.tls_www_server
, 0},
134 {NULL
, '\0', "signing_key", CFG_BOOL
, (void *) &cfg
.signing_key
,
136 {NULL
, '\0', "encryption_key", CFG_BOOL
,
137 (void *) &cfg
.encryption_key
, 0},
138 {NULL
, '\0', "cert_signing_key", CFG_BOOL
,
139 (void *) &cfg
.cert_sign_key
, 0},
140 {NULL
, '\0', "crl_signing_key", CFG_BOOL
,
141 (void *) &cfg
.crl_sign_key
, 0},
142 {NULL
, '\0', "code_signing_key", CFG_BOOL
,
143 (void *) &cfg
.code_sign_key
, 0},
144 {NULL
, '\0', "ocsp_signing_key", CFG_BOOL
,
145 (void *) &cfg
.ocsp_sign_key
, 0},
146 {NULL
, '\0', "time_stamping_key", CFG_BOOL
,
147 (void *) &cfg
.time_stamping_key
, 0},
148 {NULL
, '\0', "proxy_policy_language", CFG_STR
,
149 (void *) &cfg
.proxy_policy_language
, 0},
153 /* Creating context */
154 con
= cfg_get_context (options
);
157 puts ("Not enough memory");
161 cfg_set_cfgfile_context (con
, 0, -1, (char *) template);
163 /* Parsing command line */
164 ret
= cfg_parse (con
);
168 printf ("error parsing command line: %s: ", template);
169 cfg_fprint_error (con
, stdout
);
171 exit (ret
< 0 ? -ret
: ret
);
178 read_crt_set (gnutls_x509_crt crt
, const char *input_str
, const char *oid
)
183 fputs (input_str
, stderr
);
184 fgets (input
, sizeof (input
), stdin
);
186 if (strlen (input
) == 1) /* only newline */
190 gnutls_x509_crt_set_dn_by_oid (crt
, oid
, 0, input
, strlen (input
) - 1);
193 fprintf (stderr
, "set_dn: %s\n", gnutls_strerror (ret
));
199 read_crq_set (gnutls_x509_crq crq
, const char *input_str
, const char *oid
)
204 fputs (input_str
, stderr
);
205 fgets (input
, sizeof (input
), stdin
);
207 if (strlen (input
) == 1) /* only newline */
211 gnutls_x509_crq_set_dn_by_oid (crq
, oid
, 0, input
, strlen (input
) - 1);
214 fprintf (stderr
, "set_dn: %s\n", gnutls_strerror (ret
));
220 read_int_with_default (const char *input_str
, int def
)
226 in
= readline (input_str
);
228 l
= strtol (in
, &endptr
, 0);
232 fprintf (stderr
, "Trailing garbage ignored: `%s'\n", endptr
);
237 if (l
<= INT_MIN
|| l
>= INT_MAX
)
239 fprintf (stderr
, "Integer out of range: `%s'\n", in
);
253 read_int (const char *input_str
)
255 return read_int_with_default (input_str
, 0);
259 read_str (const char *input_str
)
261 static char input
[128];
264 fputs (input_str
, stderr
);
265 if (fgets (input
, sizeof (input
), stdin
) == NULL
)
268 len
= strlen (input
);
269 if ((len
> 0) && (input
[len
- 1] == '\n'))
278 read_yesno (const char *input_str
)
282 fputs (input_str
, stderr
);
283 fgets (input
, sizeof (input
), stdin
);
285 if (strlen (input
) == 1) /* only newline */
288 if (input
[0] == 'y' || input
[0] == 'Y')
295 /* Wrapper functions for non-interactive mode.
303 return getpass ("Enter password: ");
307 get_challenge_pass (void)
310 return cfg
.challenge_password
;
312 return getpass ("Enter a challenge password: ");
316 get_crl_dist_point_url (void)
319 return cfg
.crl_dist_points
;
321 return read_str ("Enter the URI of the CRL distribution point: ");
325 get_country_crt_set (gnutls_x509_crt crt
)
334 gnutls_x509_crt_set_dn_by_oid (crt
,
335 GNUTLS_OID_X520_COUNTRY_NAME
, 0,
336 cfg
.country
, strlen (cfg
.country
));
339 fprintf (stderr
, "set_dn: %s\n", gnutls_strerror (ret
));
345 read_crt_set (crt
, "Country name (2 chars): ",
346 GNUTLS_OID_X520_COUNTRY_NAME
);
352 get_organization_crt_set (gnutls_x509_crt crt
)
358 if (!cfg
.organization
)
362 gnutls_x509_crt_set_dn_by_oid (crt
,
363 GNUTLS_OID_X520_ORGANIZATION_NAME
,
365 strlen (cfg
.organization
));
368 fprintf (stderr
, "set_dn: %s\n", gnutls_strerror (ret
));
374 read_crt_set (crt
, "Organization name: ",
375 GNUTLS_OID_X520_ORGANIZATION_NAME
);
381 get_unit_crt_set (gnutls_x509_crt crt
)
391 gnutls_x509_crt_set_dn_by_oid (crt
,
392 GNUTLS_OID_X520_ORGANIZATIONAL_UNIT_NAME
,
393 0, cfg
.unit
, strlen (cfg
.unit
));
396 fprintf (stderr
, "set_dn: %s\n", gnutls_strerror (ret
));
402 read_crt_set (crt
, "Organizational unit name: ",
403 GNUTLS_OID_X520_ORGANIZATIONAL_UNIT_NAME
);
409 get_state_crt_set (gnutls_x509_crt crt
)
418 gnutls_x509_crt_set_dn_by_oid (crt
,
419 GNUTLS_OID_X520_STATE_OR_PROVINCE_NAME
,
420 0, cfg
.state
, strlen (cfg
.state
));
423 fprintf (stderr
, "set_dn: %s\n", gnutls_strerror (ret
));
429 read_crt_set (crt
, "State or province name: ",
430 GNUTLS_OID_X520_STATE_OR_PROVINCE_NAME
);
436 get_locality_crt_set (gnutls_x509_crt crt
)
445 gnutls_x509_crt_set_dn_by_oid (crt
,
446 GNUTLS_OID_X520_LOCALITY_NAME
, 0,
447 cfg
.locality
, strlen (cfg
.locality
));
450 fprintf (stderr
, "set_dn: %s\n", gnutls_strerror (ret
));
456 read_crt_set (crt
, "Locality name: ", GNUTLS_OID_X520_LOCALITY_NAME
);
462 get_cn_crt_set (gnutls_x509_crt crt
)
471 gnutls_x509_crt_set_dn_by_oid (crt
, GNUTLS_OID_X520_COMMON_NAME
,
472 0, cfg
.cn
, strlen (cfg
.cn
));
475 fprintf (stderr
, "set_dn: %s\n", gnutls_strerror (ret
));
481 read_crt_set (crt
, "Common name: ", GNUTLS_OID_X520_COMMON_NAME
);
487 get_uid_crt_set (gnutls_x509_crt crt
)
495 ret
= gnutls_x509_crt_set_dn_by_oid (crt
, GNUTLS_OID_LDAP_UID
, 0,
496 cfg
.uid
, strlen (cfg
.uid
));
499 fprintf (stderr
, "set_dn: %s\n", gnutls_strerror (ret
));
505 read_crt_set (crt
, "UID: ", GNUTLS_OID_LDAP_UID
);
511 get_oid_crt_set (gnutls_x509_crt crt
)
519 for (i
= 0; cfg
.dn_oid
[i
] != NULL
; i
+= 2)
521 if (cfg
.dn_oid
[i
+ 1] == NULL
)
523 fprintf (stderr
, "dn_oid: %s does not have an argument.\n",
527 ret
= gnutls_x509_crt_set_dn_by_oid (crt
, cfg
.dn_oid
[i
], 0,
529 strlen (cfg
.dn_oid
[i
+ 1]));
533 fprintf (stderr
, "set_dn_oid: %s\n", gnutls_strerror (ret
));
543 get_pkcs9_email_crt_set (gnutls_x509_crt crt
)
549 if (!cfg
.pkcs9_email
)
551 ret
= gnutls_x509_crt_set_dn_by_oid (crt
, GNUTLS_OID_PKCS9_EMAIL
, 0,
553 strlen (cfg
.pkcs9_email
));
556 fprintf (stderr
, "set_dn: %s\n", gnutls_strerror (ret
));
562 read_crt_set (crt
, "E-mail: ", GNUTLS_OID_PKCS9_EMAIL
);
570 int default_serial
= time (NULL
);
575 return default_serial
;
580 return read_int_with_default
581 ("Enter the certificate's serial number (decimal): ", default_serial
);
592 if (cfg
.expiration_days
<= 0)
595 return cfg
.expiration_days
;
601 days
= read_int ("The certificate will expire in (days): ");
618 read_yesno ("Does the certificate belong to an authority? (Y/N): ");
631 return read_int_with_default
632 ("Path length constraint (decimal, -1 for no constraint): ", -1);
637 get_pkcs12_key_name (void)
643 if (!cfg
.pkcs12_key_name
)
645 return cfg
.pkcs12_key_name
;
651 name
= read_str ("Enter a name for the key: ");
653 while (name
== NULL
);
659 get_tls_client_status (void)
663 return cfg
.tls_www_client
;
667 return read_yesno ("Is this a TLS web client certificate? (Y/N): ");
672 get_tls_server_status (void)
676 return cfg
.tls_www_server
;
681 read_yesno ("Is this also a TLS web server certificate? (Y/N): ");
695 read_str ("Enter the dnsName of the subject of the certificate: ");
709 read_str ("Enter the IP address of the subject of the certificate: ");
723 read_str ("Enter the e-mail of the subject of the certificate: ");
728 get_sign_status (int server
)
734 return cfg
.signing_key
;
740 "Will the certificate be used for signing (DHE and RSA-EXPORT ciphersuites)? (Y/N): ";
743 "Will the certificate be used for signing (required for TLS)? (Y/N): ";
744 return read_yesno (msg
);
749 get_encrypt_status (int server
)
755 return cfg
.encryption_key
;
761 "Will the certificate be used for encryption (RSA ciphersuites)? (Y/N): ";
764 "Will the certificate be used for encryption (not required for TLS)? (Y/N): ";
765 return read_yesno (msg
);
770 get_cert_sign_status (void)
774 return cfg
.cert_sign_key
;
780 ("Will the certificate be used to sign other certificates? (Y/N): ");
785 get_crl_sign_status (void)
789 return cfg
.crl_sign_key
;
794 read_yesno ("Will the certificate be used to sign CRLs? (Y/N): ");
799 get_code_sign_status (void)
803 return cfg
.code_sign_key
;
808 read_yesno ("Will the certificate be used to sign code? (Y/N): ");
813 get_ocsp_sign_status (void)
817 return cfg
.ocsp_sign_key
;
823 ("Will the certificate be used to sign OCSP requests? (Y/N): ");
828 get_time_stamp_status (void)
832 return cfg
.time_stamping_key
;
838 ("Will the certificate be used for time stamping? (Y/N): ");
843 get_crl_next_update (void)
849 if (cfg
.crl_next_update
<= 0)
852 return cfg
.crl_next_update
;
858 days
= read_int ("The next CRL will be issued in (days): ");
866 get_proxy_policy (char **policy
, size_t *policylen
)
872 ret
= cfg
.proxy_policy_language
;
874 ret
= "1.3.6.1.5.5.7.21.1";
880 ret
= read_str ("Enter the OID of the proxy policy language: ");
888 if (strcmp (ret
, "1.3.6.1.5.5.7.21.1") != 0 &&
889 strcmp (ret
, "1.3.6.1.5.5.7.21.2") != 0)
891 fprintf (stderr
, "Reading non-standard proxy policy not supported.\n");
900 get_country_crq_set (gnutls_x509_crq crq
)
909 gnutls_x509_crq_set_dn_by_oid (crq
,
910 GNUTLS_OID_X520_COUNTRY_NAME
, 0,
911 cfg
.country
, strlen (cfg
.country
));
914 fprintf (stderr
, "set_dn: %s\n", gnutls_strerror (ret
));
920 read_crq_set (crq
, "Country name (2 chars): ",
921 GNUTLS_OID_X520_COUNTRY_NAME
);
927 get_organization_crq_set (gnutls_x509_crq crq
)
933 if (!cfg
.organization
)
937 gnutls_x509_crq_set_dn_by_oid (crq
,
938 GNUTLS_OID_X520_ORGANIZATION_NAME
,
940 strlen (cfg
.organization
));
943 fprintf (stderr
, "set_dn: %s\n", gnutls_strerror (ret
));
949 read_crq_set (crq
, "Organization name: ",
950 GNUTLS_OID_X520_ORGANIZATION_NAME
);
956 get_unit_crq_set (gnutls_x509_crq crq
)
966 gnutls_x509_crq_set_dn_by_oid (crq
,
967 GNUTLS_OID_X520_ORGANIZATIONAL_UNIT_NAME
,
968 0, cfg
.unit
, strlen (cfg
.unit
));
971 fprintf (stderr
, "set_dn: %s\n", gnutls_strerror (ret
));
977 read_crq_set (crq
, "Organizational unit name: ",
978 GNUTLS_OID_X520_ORGANIZATIONAL_UNIT_NAME
);
984 get_state_crq_set (gnutls_x509_crq crq
)
993 gnutls_x509_crq_set_dn_by_oid (crq
,
994 GNUTLS_OID_X520_STATE_OR_PROVINCE_NAME
,
995 0, cfg
.state
, strlen (cfg
.state
));
998 fprintf (stderr
, "set_dn: %s\n", gnutls_strerror (ret
));
1004 read_crq_set (crq
, "State or province name: ",
1005 GNUTLS_OID_X520_STATE_OR_PROVINCE_NAME
);
1011 get_locality_crq_set (gnutls_x509_crq crq
)
1020 gnutls_x509_crq_set_dn_by_oid (crq
,
1021 GNUTLS_OID_X520_LOCALITY_NAME
, 0,
1022 cfg
.locality
, strlen (cfg
.locality
));
1025 fprintf (stderr
, "set_dn: %s\n", gnutls_strerror (ret
));
1031 read_crq_set (crq
, "Locality name: ", GNUTLS_OID_X520_LOCALITY_NAME
);
1037 get_cn_crq_set (gnutls_x509_crq crq
)
1046 gnutls_x509_crq_set_dn_by_oid (crq
, GNUTLS_OID_X520_COMMON_NAME
,
1047 0, cfg
.cn
, strlen (cfg
.cn
));
1050 fprintf (stderr
, "set_dn: %s\n", gnutls_strerror (ret
));
1056 read_crq_set (crq
, "Common name: ", GNUTLS_OID_X520_COMMON_NAME
);
1062 get_uid_crq_set (gnutls_x509_crq crq
)
1070 ret
= gnutls_x509_crq_set_dn_by_oid (crq
, GNUTLS_OID_LDAP_UID
, 0,
1071 cfg
.uid
, strlen (cfg
.uid
));
1074 fprintf (stderr
, "set_dn: %s\n", gnutls_strerror (ret
));
1080 read_crq_set (crq
, "UID: ", GNUTLS_OID_LDAP_UID
);
1086 get_oid_crq_set (gnutls_x509_crq crq
)
1094 for (i
= 0; cfg
.dn_oid
[i
] != NULL
; i
+= 2)
1096 if (cfg
.dn_oid
[i
+ 1] == NULL
)
1098 fprintf (stderr
, "dn_oid: %s does not have an argument.\n",
1102 ret
= gnutls_x509_crq_set_dn_by_oid (crq
, cfg
.dn_oid
[i
], 0,
1104 strlen (cfg
.dn_oid
[i
+ 1]));
1108 fprintf (stderr
, "set_dn_oid: %s\n", gnutls_strerror (ret
));