1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
18 | |
19 | |
20 | |
21 | |
22 | |
23 | #include <config.h> |
24 | |
25 | #include <stdio.h> |
26 | #include <stdlib.h> |
27 | #include <certtool-cfg.h> |
28 | #include <cfg+.h> |
29 | #include <gnutls/x509.h> |
30 | #include <string.h> |
31 | #include <limits.h> |
32 | #include <inttypes.h> |
33 | #include <time.h> |
34 | |
35 | |
36 | #include <sys/types.h> |
37 | |
38 | #if HAVE_SYS_SOCKET_H1 |
39 | # include <sys/socket.h> |
40 | #elif HAVE_WS2TCPIP_H |
41 | # include <ws2tcpip.h> |
42 | #endif |
43 | #include <arpa/inet.h> |
44 | |
45 | |
46 | #include <getpass.h> |
47 | #include "certtool-common.h" |
48 | |
49 | extern int batch; |
50 | |
51 | typedef struct _cfg_ctx |
52 | { |
53 | char *organization; |
54 | char *unit; |
55 | char *locality; |
56 | char *state; |
57 | char *cn; |
58 | char *uid; |
59 | char *challenge_password; |
60 | char *pkcs9_email; |
61 | char *country; |
62 | char **dns_name; |
63 | char **ip_addr; |
64 | char **email; |
65 | char **dn_oid; |
66 | char *crl_dist_points; |
67 | char *password; |
68 | char *pkcs12_key_name; |
69 | int serial; |
70 | int expiration_days; |
71 | int ca; |
72 | int path_len; |
73 | int tls_www_client; |
74 | int tls_www_server; |
75 | int signing_key; |
76 | int encryption_key; |
77 | int cert_sign_key; |
78 | int crl_sign_key; |
79 | int code_sign_key; |
80 | int ocsp_sign_key; |
81 | int time_stamping_key; |
82 | int ipsec_ike_key; |
83 | char **key_purpose_oids; |
84 | int crl_next_update; |
85 | int crl_number; |
86 | int crq_extensions; |
87 | char *proxy_policy_language; |
88 | } cfg_ctx; |
89 | |
90 | cfg_ctx cfg; |
91 | |
92 | void |
93 | cfg_init (void) |
94 | { |
95 | memset (&cfg, 0, sizeof (cfg)); |
96 | cfg.path_len = -1; |
97 | cfg.serial = -1; |
98 | } |
99 | |
100 | int |
101 | template_parse (const char *template) |
102 | { |
103 | |
104 | CFG_CONTEXT con; |
105 | |
106 | |
107 | register int ret; |
108 | |
109 | |
110 | |
111 | |
112 | struct cfg_option options[] = { |
113 | {NULL((void*)0), '\0', "organization", CFG_STR, (void *) &cfg.organization, |
114 | 0}, |
115 | {NULL((void*)0), '\0', "unit", CFG_STR, (void *) &cfg.unit, 0}, |
116 | {NULL((void*)0), '\0', "locality", CFG_STR, (void *) &cfg.locality, 0}, |
117 | {NULL((void*)0), '\0', "state", CFG_STR, (void *) &cfg.state, 0}, |
118 | {NULL((void*)0), '\0', "cn", CFG_STR, (void *) &cfg.cn, 0}, |
119 | {NULL((void*)0), '\0', "uid", CFG_STR, (void *) &cfg.uid, 0}, |
120 | {NULL((void*)0), '\0', "challenge_password", CFG_STR, |
121 | (void *) &cfg.challenge_password, 0}, |
122 | {NULL((void*)0), '\0', "password", CFG_STR, (void *) &cfg.password, 0}, |
123 | {NULL((void*)0), '\0', "pkcs9_email", CFG_STR, (void *) &cfg.pkcs9_email, 0}, |
124 | {NULL((void*)0), '\0', "country", CFG_STR, (void *) &cfg.country, 0}, |
125 | {NULL((void*)0), '\0', "dns_name", CFG_STR | CFG_MULTI_ARRAY, |
126 | (void *) &cfg.dns_name, 0}, |
127 | {NULL((void*)0), '\0', "ip_address", CFG_STR | CFG_MULTI_ARRAY, |
128 | (void *) &cfg.ip_addr, 0}, |
129 | {NULL((void*)0), '\0', "email", CFG_STR | CFG_MULTI_ARRAY, (void *) &cfg.email, 0}, |
130 | |
131 | {NULL((void*)0), '\0', "dn_oid", CFG_STR + CFG_MULTI_SEPARATED, |
132 | (void *) &cfg.dn_oid, 0}, |
133 | {NULL((void*)0), '\0', "key_purpose_oids", CFG_STR + CFG_MULTI_SEPARATED, |
134 | (void *) &cfg.key_purpose_oids, 0}, |
135 | |
136 | {NULL((void*)0), '\0', "crl_dist_points", CFG_STR, |
137 | (void *) &cfg.crl_dist_points, 0}, |
138 | {NULL((void*)0), '\0', "pkcs12_key_name", CFG_STR, |
139 | (void *) &cfg.pkcs12_key_name, 0}, |
140 | |
141 | {NULL((void*)0), '\0', "serial", CFG_INT, (void *) &cfg.serial, 0}, |
142 | {NULL((void*)0), '\0', "expiration_days", CFG_INT, |
143 | (void *) &cfg.expiration_days, 0}, |
144 | |
145 | {NULL((void*)0), '\0', "crl_next_update", CFG_INT, |
146 | (void *) &cfg.crl_next_update, 0}, |
147 | |
148 | {NULL((void*)0), '\0', "crl_number", CFG_INT, |
149 | (void *) &cfg.crl_number, 0}, |
150 | |
151 | {NULL((void*)0), '\0', "ca", CFG_BOOL, (void *) &cfg.ca, 0}, |
152 | {NULL((void*)0), '\0', "honor_crq_extensions", CFG_BOOL, |
153 | (void *) &cfg.crq_extensions, 0}, |
154 | {NULL((void*)0), '\0', "path_len", CFG_INT, (void *) &cfg.path_len, 0}, |
155 | {NULL((void*)0), '\0', "tls_www_client", CFG_BOOL, |
156 | (void *) &cfg.tls_www_client, 0}, |
157 | {NULL((void*)0), '\0', "tls_www_server", CFG_BOOL, |
158 | (void *) &cfg.tls_www_server, 0}, |
159 | {NULL((void*)0), '\0', "signing_key", CFG_BOOL, (void *) &cfg.signing_key, |
160 | 0}, |
161 | {NULL((void*)0), '\0', "encryption_key", CFG_BOOL, |
162 | (void *) &cfg.encryption_key, 0}, |
163 | {NULL((void*)0), '\0', "cert_signing_key", CFG_BOOL, |
164 | (void *) &cfg.cert_sign_key, 0}, |
165 | {NULL((void*)0), '\0', "crl_signing_key", CFG_BOOL, |
166 | (void *) &cfg.crl_sign_key, 0}, |
167 | {NULL((void*)0), '\0', "code_signing_key", CFG_BOOL, |
168 | (void *) &cfg.code_sign_key, 0}, |
169 | {NULL((void*)0), '\0', "ocsp_signing_key", CFG_BOOL, |
170 | (void *) &cfg.ocsp_sign_key, 0}, |
171 | {NULL((void*)0), '\0', "time_stamping_key", CFG_BOOL, |
172 | (void *) &cfg.time_stamping_key, 0}, |
173 | {NULL((void*)0), '\0', "ipsec_ike_key", CFG_BOOL, |
174 | (void *) &cfg.ipsec_ike_key, 0}, |
175 | {NULL((void*)0), '\0', "proxy_policy_language", CFG_STR, |
176 | (void *) &cfg.proxy_policy_language, 0}, |
177 | CFG_END_OF_LIST{ ((void*)0), '\0', ((void*)0), CFG_END, ((void*)0), 0 } |
178 | }; |
179 | |
180 | |
181 | con = cfg_get_context (options); |
182 | if (con == NULL((void*)0)) |
183 | { |
184 | puts ("Not enough memory"); |
185 | exit (1); |
186 | } |
187 | |
188 | cfg_set_cfgfile_context (con, 0, -1, (char *) template); |
189 | |
190 | |
191 | ret = cfg_parse (con); |
192 | |
193 | if (ret != CFG_OK) |
194 | { |
195 | printf ("error parsing command line: %s: ", template); |
196 | cfg_fprint_error (con, stdoutstdout); |
197 | putchar ('\n'); |
198 | exit (ret < 0 ? -ret : ret); |
199 | } |
200 | |
201 | return 0; |
202 | } |
203 | |
204 | #define IS_NEWLINE(x)((x[0] == '\n') || (x[0] == '\r')) ((x[0] == '\n') || (x[0] == '\r')) |
205 | |
206 | void |
207 | read_crt_set (gnutls_x509_crt_t crt, const char *input_str, const char *oid) |
208 | { |
209 | char input[128]; |
210 | int ret; |
211 | |
212 | fputs (input_str, stderrstderr); |
213 | if (fgets (input, sizeof (input), stdinstdin) == NULL((void*)0)) |
214 | return; |
215 | |
216 | if (IS_NEWLINE(input)((input[0] == '\n') || (input[0] == '\r'))) |
217 | return; |
218 | |
219 | ret = |
220 | gnutls_x509_crt_set_dn_by_oid (crt, oid, 0, input, strlen (input) - 1); |
221 | if (ret < 0) |
222 | { |
223 | fprintf (stderrstderr, "set_dn: %s\n", gnutls_strerror (ret)); |
224 | exit (1); |
225 | } |
226 | } |
227 | |
228 | void |
229 | read_crq_set (gnutls_x509_crq_t crq, const char *input_str, const char *oid) |
230 | { |
231 | char input[128]; |
232 | int ret; |
233 | |
234 | fputs (input_str, stderrstderr); |
235 | if (fgets (input, sizeof (input), stdinstdin) == NULL((void*)0)) |
236 | return; |
237 | |
238 | if (IS_NEWLINE(input)((input[0] == '\n') || (input[0] == '\r'))) |
239 | return; |
240 | |
241 | ret = |
242 | gnutls_x509_crq_set_dn_by_oid (crq, oid, 0, input, strlen (input) - 1); |
243 | if (ret < 0) |
244 | { |
245 | fprintf (stderrstderr, "set_dn: %s\n", gnutls_strerror (ret)); |
246 | exit (1); |
247 | } |
248 | } |
249 | |
250 | |
251 | |
252 | static int |
253 | read_int_with_default (const char *input_str, int def) |
254 | { |
255 | char *endptr; |
256 | long l, len; |
257 | static char input[128]; |
258 | |
259 | fprintf (stderrstderr, input_str, def); |
260 | if (fgets (input, sizeof (input), stdinstdin) == NULL((void*)0)) |
261 | return def; |
262 | |
263 | if (IS_NEWLINE(input)((input[0] == '\n') || (input[0] == '\r'))) |
264 | return def; |
265 | |
266 | len = strlen (input); |
| Value stored to 'len' is never read |
267 | |
268 | l = strtol (input, &endptr, 0); |
269 | |
270 | if (*endptr != '\0' && *endptr != '\r' && *endptr != '\n') |
271 | { |
272 | fprintf (stderrstderr, "Trailing garbage ignored: `%s'\n", endptr); |
273 | return 0; |
274 | } |
275 | |
276 | if (l <= INT_MIN(-2147483647 -1) || l >= INT_MAX2147483647) |
277 | { |
278 | fprintf (stderrstderr, "Integer out of range: `%s'\n", input); |
279 | return 0; |
280 | } |
281 | |
282 | if (input == endptr) |
283 | l = def; |
284 | |
285 | return (int) l; |
286 | } |
287 | |
288 | int |
289 | read_int (const char *input_str) |
290 | { |
291 | return read_int_with_default (input_str, 0); |
292 | } |
293 | |
294 | const char * |
295 | read_str (const char *input_str) |
296 | { |
297 | static char input[128]; |
298 | int len; |
299 | |
300 | fputs (input_str, stderrstderr); |
301 | if (fgets (input, sizeof (input), stdinstdin) == NULL((void*)0)) |
302 | return NULL((void*)0); |
303 | |
304 | if (IS_NEWLINE(input)((input[0] == '\n') || (input[0] == '\r'))) |
305 | return NULL((void*)0); |
306 | |
307 | len = strlen (input); |
308 | if ((len > 0) && (input[len - 1] == '\n')) |
309 | input[len - 1] = 0; |
310 | if (input[0] == 0) |
311 | return NULL((void*)0); |
312 | |
313 | return input; |
314 | } |
315 | |
316 | |
317 | |
318 | int |
319 | read_yesno (const char *input_str) |
320 | { |
321 | char input[128]; |
322 | |
323 | fputs (input_str, stderrstderr); |
324 | if (fgets (input, sizeof (input), stdinstdin) == NULL((void*)0)) |
325 | return 0; |
326 | |
327 | if (IS_NEWLINE(input)((input[0] == '\n') || (input[0] == '\r'))) |
328 | return 0; |
329 | |
330 | if (input[0] == 'y' || input[0] == 'Y') |
331 | return 1; |
332 | |
333 | return 0; |
334 | } |
335 | |
336 | |
337 | |
338 | |
339 | const char * |
340 | get_pass (void) |
341 | { |
342 | if (batch) |
343 | return cfg.password; |
344 | else |
345 | return getpass ("Enter password: "); |
346 | } |
347 | |
348 | const char * |
349 | get_confirmed_pass (bool_Bool empty_ok) |
350 | { |
351 | if (batch) |
352 | return cfg.password; |
353 | else |
354 | { |
355 | const char *pass = NULL((void*)0); |
356 | char *copy = NULL((void*)0); |
357 | |
358 | do |
359 | { |
360 | if (pass) |
361 | printf ("Password missmatch, try again.\n"); |
362 | |
363 | free (copy); |
364 | |
365 | pass = getpass ("Enter password: "); |
366 | copy = strdup (pass); |
367 | pass = getpass ("Confirm password: "); |
368 | } |
369 | while (strcmp (pass, copy) != 0 && !(empty_ok && *pass == '\0')); |
370 | |
371 | free (copy); |
372 | |
373 | return pass; |
374 | } |
375 | } |
376 | |
377 | const char * |
378 | get_challenge_pass (void) |
379 | { |
380 | if (batch) |
381 | return cfg.challenge_password; |
382 | else |
383 | return getpass ("Enter a challenge password: "); |
384 | } |
385 | |
386 | const char * |
387 | get_crl_dist_point_url (void) |
388 | { |
389 | if (batch) |
390 | return cfg.crl_dist_points; |
391 | else |
392 | return read_str ("Enter the URI of the CRL distribution point: "); |
393 | } |
394 | |
395 | void |
396 | get_country_crt_set (gnutls_x509_crt_t crt) |
397 | { |
398 | int ret; |
399 | |
400 | if (batch) |
401 | { |
402 | if (!cfg.country) |
403 | return; |
404 | ret = |
405 | gnutls_x509_crt_set_dn_by_oid (crt, |
406 | GNUTLS_OID_X520_COUNTRY_NAME"2.5.4.6", 0, |
407 | cfg.country, strlen (cfg.country)); |
408 | if (ret < 0) |
409 | { |
410 | fprintf (stderrstderr, "set_dn: %s\n", gnutls_strerror (ret)); |
411 | exit (1); |
412 | } |
413 | } |
414 | else |
415 | { |
416 | read_crt_set (crt, "Country name (2 chars): ", |
417 | GNUTLS_OID_X520_COUNTRY_NAME"2.5.4.6"); |
418 | } |
419 | |
420 | } |
421 | |
422 | void |
423 | get_organization_crt_set (gnutls_x509_crt_t crt) |
424 | { |
425 | int ret; |
426 | |
427 | if (batch) |
428 | { |
429 | if (!cfg.organization) |
430 | return; |
431 | |
432 | ret = |
433 | gnutls_x509_crt_set_dn_by_oid (crt, |
434 | GNUTLS_OID_X520_ORGANIZATION_NAME"2.5.4.10", |
435 | 0, cfg.organization, |
436 | strlen (cfg.organization)); |
437 | if (ret < 0) |
438 | { |
439 | fprintf (stderrstderr, "set_dn: %s\n", gnutls_strerror (ret)); |
440 | exit (1); |
441 | } |
442 | } |
443 | else |
444 | { |
445 | read_crt_set (crt, "Organization name: ", |
446 | GNUTLS_OID_X520_ORGANIZATION_NAME"2.5.4.10"); |
447 | } |
448 | |
449 | } |
450 | |
451 | void |
452 | get_unit_crt_set (gnutls_x509_crt_t crt) |
453 | { |
454 | int ret; |
455 | |
456 | if (batch) |
457 | { |
458 | if (!cfg.unit) |
459 | return; |
460 | |
461 | ret = |
462 | gnutls_x509_crt_set_dn_by_oid (crt, |
463 | GNUTLS_OID_X520_ORGANIZATIONAL_UNIT_NAME"2.5.4.11", |
464 | 0, cfg.unit, strlen (cfg.unit)); |
465 | if (ret < 0) |
466 | { |
467 | fprintf (stderrstderr, "set_dn: %s\n", gnutls_strerror (ret)); |
468 | exit (1); |
469 | } |
470 | } |
471 | else |
472 | { |
473 | read_crt_set (crt, "Organizational unit name: ", |
474 | GNUTLS_OID_X520_ORGANIZATIONAL_UNIT_NAME"2.5.4.11"); |
475 | } |
476 | |
477 | } |
478 | |
479 | void |
480 | get_state_crt_set (gnutls_x509_crt_t crt) |
481 | { |
482 | int ret; |
483 | |
484 | if (batch) |
485 | { |
486 | if (!cfg.state) |
487 | return; |
488 | ret = |
489 | gnutls_x509_crt_set_dn_by_oid (crt, |
490 | GNUTLS_OID_X520_STATE_OR_PROVINCE_NAME"2.5.4.8", |
491 | 0, cfg.state, strlen (cfg.state)); |
492 | if (ret < 0) |
493 | { |
494 | fprintf (stderrstderr, "set_dn: %s\n", gnutls_strerror (ret)); |
495 | exit (1); |
496 | } |
497 | } |
498 | else |
499 | { |
500 | read_crt_set (crt, "State or province name: ", |
501 | GNUTLS_OID_X520_STATE_OR_PROVINCE_NAME"2.5.4.8"); |
502 | } |
503 | |
504 | } |
505 | |
506 | void |
507 | get_locality_crt_set (gnutls_x509_crt_t crt) |
508 | { |
509 | int ret; |
510 | |
511 | if (batch) |
512 | { |
513 | if (!cfg.locality) |
514 | return; |
515 | ret = |
516 | gnutls_x509_crt_set_dn_by_oid (crt, |
517 | GNUTLS_OID_X520_LOCALITY_NAME"2.5.4.7", 0, |
518 | cfg.locality, strlen (cfg.locality)); |
519 | if (ret < 0) |
520 | { |
521 | fprintf (stderrstderr, "set_dn: %s\n", gnutls_strerror (ret)); |
522 | exit (1); |
523 | } |
524 | } |
525 | else |
526 | { |
527 | read_crt_set (crt, "Locality name: ", GNUTLS_OID_X520_LOCALITY_NAME"2.5.4.7"); |
528 | } |
529 | |
530 | } |
531 | |
532 | void |
533 | get_cn_crt_set (gnutls_x509_crt_t crt) |
534 | { |
535 | int ret; |
536 | |
537 | if (batch) |
538 | { |
539 | if (!cfg.cn) |
540 | return; |
541 | ret = |
542 | gnutls_x509_crt_set_dn_by_oid (crt, GNUTLS_OID_X520_COMMON_NAME"2.5.4.3", |
543 | 0, cfg.cn, strlen (cfg.cn)); |
544 | if (ret < 0) |
545 | { |
546 | fprintf (stderrstderr, "set_dn: %s\n", gnutls_strerror (ret)); |
547 | exit (1); |
548 | } |
549 | } |
550 | else |
551 | { |
552 | read_crt_set (crt, "Common name: ", GNUTLS_OID_X520_COMMON_NAME"2.5.4.3"); |
553 | } |
554 | |
555 | } |
556 | |
557 | void |
558 | get_uid_crt_set (gnutls_x509_crt_t crt) |
559 | { |
560 | int ret; |
561 | |
562 | if (batch) |
563 | { |
564 | if (!cfg.uid) |
565 | return; |
566 | ret = gnutls_x509_crt_set_dn_by_oid (crt, GNUTLS_OID_LDAP_UID"0.9.2342.19200300.100.1.1", 0, |
567 | cfg.uid, strlen (cfg.uid)); |
568 | if (ret < 0) |
569 | { |
570 | fprintf (stderrstderr, "set_dn: %s\n", gnutls_strerror (ret)); |
571 | exit (1); |
572 | } |
573 | } |
574 | else |
575 | { |
576 | read_crt_set (crt, "UID: ", GNUTLS_OID_LDAP_UID"0.9.2342.19200300.100.1.1"); |
577 | } |
578 | |
579 | } |
580 | |
581 | void |
582 | get_oid_crt_set (gnutls_x509_crt_t crt) |
583 | { |
584 | int ret, i; |
585 | |
586 | if (batch) |
587 | { |
588 | if (!cfg.dn_oid) |
589 | return; |
590 | for (i = 0; cfg.dn_oid[i] != NULL((void*)0); i += 2) |
591 | { |
592 | if (cfg.dn_oid[i + 1] == NULL((void*)0)) |
593 | { |
594 | fprintf (stderrstderr, "dn_oid: %s does not have an argument.\n", |
595 | cfg.dn_oid[i]); |
596 | exit (1); |
597 | } |
598 | ret = gnutls_x509_crt_set_dn_by_oid (crt, cfg.dn_oid[i], 0, |
599 | cfg.dn_oid[i + 1], |
600 | strlen (cfg.dn_oid[i + 1])); |
601 | |
602 | if (ret < 0) |
603 | { |
604 | fprintf (stderrstderr, "set_dn_oid: %s\n", gnutls_strerror (ret)); |
605 | exit (1); |
606 | } |
607 | } |
608 | } |
609 | } |
610 | |
611 | void |
612 | get_key_purpose_set (gnutls_x509_crt_t crt) |
613 | { |
614 | int ret, i; |
615 | |
616 | if (batch) |
617 | { |
618 | if (!cfg.key_purpose_oids) |
619 | return; |
620 | for (i = 0; cfg.key_purpose_oids[i] != NULL((void*)0); i++) |
621 | { |
622 | ret = |
623 | gnutls_x509_crt_set_key_purpose_oid (crt, cfg.key_purpose_oids[i], |
624 | 0); |
625 | |
626 | if (ret < 0) |
627 | { |
628 | fprintf (stderrstderr, "set_key_purpose_oid (%s): %s\n", |
629 | cfg.key_purpose_oids[i], gnutls_strerror (ret)); |
630 | exit (1); |
631 | } |
632 | } |
633 | } |
634 | |
635 | } |
636 | |
637 | |
638 | void |
639 | get_pkcs9_email_crt_set (gnutls_x509_crt_t crt) |
640 | { |
641 | int ret; |
642 | |
643 | if (batch) |
644 | { |
645 | if (!cfg.pkcs9_email) |
646 | return; |
647 | ret = gnutls_x509_crt_set_dn_by_oid (crt, GNUTLS_OID_PKCS9_EMAIL"1.2.840.113549.1.9.1", 0, |
648 | cfg.pkcs9_email, |
649 | strlen (cfg.pkcs9_email)); |
650 | if (ret < 0) |
651 | { |
652 | fprintf (stderrstderr, "set_dn: %s\n", gnutls_strerror (ret)); |
653 | exit (1); |
654 | } |
655 | } |
656 | else |
657 | { |
658 | read_crt_set (crt, "E-mail: ", GNUTLS_OID_PKCS9_EMAIL"1.2.840.113549.1.9.1"); |
659 | } |
660 | |
661 | } |
662 | |
663 | int |
664 | get_serial (void) |
665 | { |
666 | int default_serial = time (NULL((void*)0)); |
667 | |
668 | if (batch) |
669 | { |
670 | if (cfg.serial < 0) |
671 | return default_serial; |
672 | return cfg.serial; |
673 | } |
674 | else |
675 | { |
676 | return read_int_with_default |
677 | ("Enter the certificate's serial number in decimal (default: %u): ", |
678 | default_serial); |
679 | } |
680 | } |
681 | |
682 | int |
683 | get_days (void) |
684 | { |
685 | int days; |
686 | |
687 | if (batch) |
688 | { |
689 | if (cfg.expiration_days <= 0) |
690 | return 365; |
691 | else |
692 | return cfg.expiration_days; |
693 | } |
694 | else |
695 | { |
696 | do |
697 | { |
698 | days = read_int ("The certificate will expire in (days): "); |
699 | } |
700 | while (days == 0); |
701 | return days; |
702 | } |
703 | } |
704 | |
705 | int |
706 | get_ca_status (void) |
707 | { |
708 | if (batch) |
709 | { |
710 | return cfg.ca; |
711 | } |
712 | else |
713 | { |
714 | return |
715 | read_yesno ("Does the certificate belong to an authority? (y/N): "); |
716 | } |
717 | } |
718 | |
719 | int |
720 | get_crq_extensions_status (void) |
721 | { |
722 | if (batch) |
723 | { |
724 | return cfg.crq_extensions; |
725 | } |
726 | else |
727 | { |
728 | return |
729 | read_yesno |
730 | ("Do you want to honour the extensions from the request? (y/N): "); |
731 | } |
732 | } |
733 | |
734 | int |
735 | get_crl_number (void) |
736 | { |
737 | if (batch) |
738 | { |
739 | return cfg.crl_number; |
740 | } |
741 | else |
742 | { |
743 | return read_int_with_default ("CRL Number: ", 1); |
744 | } |
745 | } |
746 | |
747 | int |
748 | get_path_len (void) |
749 | { |
750 | if (batch) |
751 | { |
752 | return cfg.path_len; |
753 | } |
754 | else |
755 | { |
756 | return read_int_with_default |
757 | ("Path length constraint (decimal, %d for no constraint): ", -1); |
758 | } |
759 | } |
760 | |
761 | const char * |
762 | get_pkcs12_key_name (void) |
763 | { |
764 | const char *name; |
765 | |
766 | if (batch) |
767 | { |
768 | if (!cfg.pkcs12_key_name) |
769 | return "Anonymous"; |
770 | return cfg.pkcs12_key_name; |
771 | } |
772 | else |
773 | { |
774 | do |
775 | { |
776 | name = read_str ("Enter a name for the key: "); |
777 | } |
778 | while (name == NULL((void*)0)); |
779 | } |
780 | return name; |
781 | } |
782 | |
783 | int |
784 | get_tls_client_status (void) |
785 | { |
786 | if (batch) |
787 | { |
788 | return cfg.tls_www_client; |
789 | } |
790 | else |
791 | { |
792 | return read_yesno ("Is this a TLS web client certificate? (y/N): "); |
793 | } |
794 | } |
795 | |
796 | int |
797 | get_tls_server_status (void) |
798 | { |
799 | if (batch) |
800 | { |
801 | return cfg.tls_www_server; |
802 | } |
803 | else |
804 | { |
805 | return |
806 | read_yesno ("Is this also a TLS web server certificate? (y/N): "); |
807 | } |
808 | } |
809 | |
810 | |
811 | static int |
812 | string_to_ip (unsigned char *ip, const char *str) |
813 | { |
814 | int len = strlen (str); |
815 | int ret; |
816 | |
817 | #if HAVE_IPV61 |
818 | if (strchr (str, ':') != NULL((void*)0) || len > 16) |
819 | { |
820 | ret = inet_pton (AF_INET610, str, ip); |
821 | if (ret <= 0) |
822 | { |
823 | fprintf (stderrstderr, "Error in IPv6 address %s\n", str); |
824 | exit (1); |
825 | } |
826 | |
827 | |
828 | return 16; |
829 | } |
830 | else |
831 | #endif |
832 | { |
833 | ret = inet_pton (AF_INET2, str, ip); |
834 | if (ret <= 0) |
835 | { |
836 | fprintf (stderrstderr, "Error in IPv4 address %s\n", str); |
837 | exit (1); |
838 | } |
839 | |
840 | return 4; |
841 | } |
842 | |
843 | } |
844 | |
845 | void |
846 | get_ip_addr_set (int type, void *crt) |
847 | { |
848 | int ret = 0, i; |
849 | unsigned char ip[16]; |
850 | int len; |
851 | |
852 | if (batch) |
853 | { |
854 | if (!cfg.ip_addr) |
855 | return; |
856 | |
857 | for (i = 0; cfg.ip_addr[i] != NULL((void*)0); i++) |
858 | { |
859 | len = string_to_ip (ip, cfg.ip_addr[i]); |
860 | if (len <= 0) |
861 | { |
862 | fprintf (stderrstderr, "Error parsing address: %s\n", cfg.ip_addr[i]); |
863 | exit (1); |
864 | } |
865 | |
866 | if (type == TYPE_CRT1) |
867 | ret = |
868 | gnutls_x509_crt_set_subject_alt_name (crt, GNUTLS_SAN_IPADDRESS, |
869 | ip, len, |
870 | GNUTLS_FSAN_APPEND1); |
871 | else |
872 | ret = |
873 | gnutls_x509_crq_set_subject_alt_name (crt, GNUTLS_SAN_IPADDRESS, |
874 | ip, len, |
875 | GNUTLS_FSAN_APPEND1); |
876 | |
877 | if (ret < 0) |
878 | break; |
879 | } |
880 | } |
881 | else |
882 | { |
883 | const char *p; |
884 | |
885 | p = |
886 | read_str ("Enter the IP address of the subject of the certificate: "); |
887 | if (!p) |
888 | return; |
889 | |
890 | len = string_to_ip (ip, p); |
891 | if (len <= 0) |
892 | { |
893 | fprintf (stderrstderr, "Error parsing address: %s\n", p); |
894 | exit (1); |
895 | } |
896 | |
897 | if (type == TYPE_CRT1) |
898 | ret = gnutls_x509_crt_set_subject_alt_name (crt, GNUTLS_SAN_IPADDRESS, |
899 | ip, len, |
900 | GNUTLS_FSAN_APPEND1); |
901 | else |
902 | ret = gnutls_x509_crq_set_subject_alt_name (crt, GNUTLS_SAN_IPADDRESS, |
903 | ip, len, |
904 | GNUTLS_FSAN_APPEND1); |
905 | } |
906 | |
907 | if (ret < 0) |
908 | { |
909 | fprintf (stderrstderr, "set_subject_alt_name: %s\n", gnutls_strerror (ret)); |
910 | exit (1); |
911 | } |
912 | } |
913 | |
914 | |
915 | void |
916 | get_email_set (int type, void *crt) |
917 | { |
918 | int ret = 0, i; |
919 | |
920 | if (batch) |
921 | { |
922 | if (!cfg.email) |
923 | return; |
924 | |
925 | for (i = 0; cfg.email[i] != NULL((void*)0); i++) |
926 | { |
927 | if (type == TYPE_CRT1) |
928 | ret = |
929 | gnutls_x509_crt_set_subject_alt_name (crt, |
930 | GNUTLS_SAN_RFC822NAME, |
931 | cfg.email[i], |
932 | strlen (cfg.email[i]), |
933 | GNUTLS_FSAN_APPEND1); |
934 | else |
935 | ret = |
936 | gnutls_x509_crq_set_subject_alt_name (crt, |
937 | GNUTLS_SAN_RFC822NAME, |
938 | cfg.email[i], |
939 | strlen (cfg.email[i]), |
940 | GNUTLS_FSAN_APPEND1); |
941 | |
942 | if (ret < 0) |
943 | break; |
944 | } |
945 | } |
946 | else |
947 | { |
948 | const char *p; |
949 | |
950 | p = read_str ("Enter the e-mail of the subject of the certificate: "); |
951 | if (!p) |
952 | return; |
953 | |
954 | if (type == TYPE_CRT1) |
955 | ret = |
956 | gnutls_x509_crt_set_subject_alt_name (crt, GNUTLS_SAN_RFC822NAME, p, |
957 | strlen (p), |
958 | GNUTLS_FSAN_APPEND1); |
959 | else |
960 | ret = |
961 | gnutls_x509_crq_set_subject_alt_name (crt, GNUTLS_SAN_RFC822NAME, p, |
962 | strlen (p), |
963 | GNUTLS_FSAN_APPEND1); |
964 | } |
965 | |
966 | if (ret < 0) |
967 | { |
968 | fprintf (stderrstderr, "set_subject_alt_name: %s\n", gnutls_strerror (ret)); |
969 | exit (1); |
970 | } |
971 | } |
972 | |
973 | void |
974 | get_dns_name_set (int type, void *crt) |
975 | { |
976 | int ret = 0, i; |
977 | |
978 | if (batch) |
979 | { |
980 | if (!cfg.dns_name) |
981 | return; |
982 | |
983 | for (i = 0; cfg.dns_name[i] != NULL((void*)0); i++) |
984 | { |
985 | if (type == TYPE_CRT1) |
986 | ret = |
987 | gnutls_x509_crt_set_subject_alt_name (crt, GNUTLS_SAN_DNSNAME, |
988 | cfg.dns_name[i], |
989 | strlen (cfg.dns_name[i]), |
990 | GNUTLS_FSAN_APPEND1); |
991 | else |
992 | ret = |
993 | gnutls_x509_crq_set_subject_alt_name (crt, GNUTLS_SAN_DNSNAME, |
994 | cfg.dns_name[i], |
995 | strlen (cfg.dns_name[i]), |
996 | GNUTLS_FSAN_APPEND1); |
997 | |
998 | if (ret < 0) |
999 | break; |
1000 | } |
1001 | } |
1002 | else |
1003 | { |
1004 | const char *p; |
1005 | |
1006 | do |
1007 | { |
1008 | p = |
1009 | read_str ("Enter a dnsName of the subject of the certificate: "); |
1010 | if (!p) |
1011 | return; |
1012 | |
1013 | if (type == TYPE_CRT1) |
1014 | ret = gnutls_x509_crt_set_subject_alt_name |
1015 | (crt, GNUTLS_SAN_DNSNAME, p, strlen (p), GNUTLS_FSAN_APPEND1); |
1016 | else |
1017 | ret = gnutls_x509_crq_set_subject_alt_name |
1018 | (crt, GNUTLS_SAN_DNSNAME, p, strlen (p), GNUTLS_FSAN_APPEND1); |
1019 | } |
1020 | while (p); |
1021 | } |
1022 | |
1023 | if (ret < 0) |
1024 | { |
1025 | fprintf (stderrstderr, "set_subject_alt_name: %s\n", gnutls_strerror (ret)); |
1026 | exit (1); |
1027 | } |
1028 | } |
1029 | |
1030 | |
1031 | int |
1032 | get_sign_status (int server) |
1033 | { |
1034 | const char *msg; |
1035 | |
1036 | if (batch) |
1037 | { |
1038 | return cfg.signing_key; |
1039 | } |
1040 | else |
1041 | { |
1042 | if (server) |
1043 | msg = |
1044 | "Will the certificate be used for signing (DHE and RSA-EXPORT ciphersuites)? (y/N): "; |
1045 | else |
1046 | msg = |
1047 | "Will the certificate be used for signing (required for TLS)? (y/N): "; |
1048 | return read_yesno (msg); |
1049 | } |
1050 | } |
1051 | |
1052 | int |
1053 | get_encrypt_status (int server) |
1054 | { |
1055 | const char *msg; |
1056 | |
1057 | if (batch) |
1058 | { |
1059 | return cfg.encryption_key; |
1060 | } |
1061 | else |
1062 | { |
1063 | if (server) |
1064 | msg = |
1065 | "Will the certificate be used for encryption (RSA ciphersuites)? (y/N): "; |
1066 | else |
1067 | msg = |
1068 | "Will the certificate be used for encryption (not required for TLS)? (y/N): "; |
1069 | return read_yesno (msg); |
1070 | } |
1071 | } |
1072 | |
1073 | int |
1074 | get_cert_sign_status (void) |
1075 | { |
1076 | if (batch) |
1077 | { |
1078 | return cfg.cert_sign_key; |
1079 | } |
1080 | else |
1081 | { |
1082 | return |
1083 | read_yesno |
1084 | ("Will the certificate be used to sign other certificates? (y/N): "); |
1085 | } |
1086 | } |
1087 | |
1088 | int |
1089 | get_crl_sign_status (void) |
1090 | { |
1091 | if (batch) |
1092 | { |
1093 | return cfg.crl_sign_key; |
1094 | } |
1095 | else |
1096 | { |
1097 | return |
1098 | read_yesno ("Will the certificate be used to sign CRLs? (y/N): "); |
1099 | } |
1100 | } |
1101 | |
1102 | int |
1103 | get_code_sign_status (void) |
1104 | { |
1105 | if (batch) |
1106 | { |
1107 | return cfg.code_sign_key; |
1108 | } |
1109 | else |
1110 | { |
1111 | return |
1112 | read_yesno ("Will the certificate be used to sign code? (y/N): "); |
1113 | } |
1114 | } |
1115 | |
1116 | int |
1117 | get_ocsp_sign_status (void) |
1118 | { |
1119 | if (batch) |
1120 | { |
1121 | return cfg.ocsp_sign_key; |
1122 | } |
1123 | else |
1124 | { |
1125 | return |
1126 | read_yesno |
1127 | ("Will the certificate be used to sign OCSP requests? (y/N): "); |
1128 | } |
1129 | } |
1130 | |
1131 | int |
1132 | get_time_stamp_status (void) |
1133 | { |
1134 | if (batch) |
1135 | { |
1136 | return cfg.time_stamping_key; |
1137 | } |
1138 | else |
1139 | { |
1140 | return |
1141 | read_yesno |
1142 | ("Will the certificate be used for time stamping? (y/N): "); |
1143 | } |
1144 | } |
1145 | |
1146 | int |
1147 | get_ipsec_ike_status (void) |
1148 | { |
1149 | if (batch) |
1150 | { |
1151 | return cfg.ipsec_ike_key; |
1152 | } |
1153 | else |
1154 | { |
1155 | return |
1156 | read_yesno |
1157 | ("Will the certificate be used for IPsec IKE operations? (y/N): "); |
1158 | } |
1159 | } |
1160 | |
1161 | int |
1162 | get_crl_next_update (void) |
1163 | { |
1164 | int days; |
1165 | |
1166 | if (batch) |
1167 | { |
1168 | if (cfg.crl_next_update <= 0) |
1169 | return 365; |
1170 | else |
1171 | return cfg.crl_next_update; |
1172 | } |
1173 | else |
1174 | { |
1175 | do |
1176 | { |
1177 | days = read_int ("The next CRL will be issued in (days): "); |
1178 | } |
1179 | while (days == 0); |
1180 | return days; |
1181 | } |
1182 | } |
1183 | |
1184 | const char * |
1185 | get_proxy_policy (char **policy, size_t * policylen) |
1186 | { |
1187 | const char *ret; |
1188 | |
1189 | if (batch) |
1190 | { |
1191 | ret = cfg.proxy_policy_language; |
1192 | if (!ret) |
1193 | ret = "1.3.6.1.5.5.7.21.1"; |
1194 | } |
1195 | else |
1196 | { |
1197 | do |
1198 | { |
1199 | ret = read_str ("Enter the OID of the proxy policy language: "); |
1200 | } |
1201 | while (ret == NULL((void*)0)); |
1202 | } |
1203 | |
1204 | *policy = NULL((void*)0); |
1205 | *policylen = 0; |
1206 | |
1207 | if (strcmp (ret, "1.3.6.1.5.5.7.21.1") != 0 && |
1208 | strcmp (ret, "1.3.6.1.5.5.7.21.2") != 0) |
1209 | { |
1210 | fprintf (stderrstderr, "Reading non-standard proxy policy not supported.\n"); |
1211 | } |
1212 | |
1213 | return ret; |
1214 | } |
1215 | |
1216 | |
1217 | |
1218 | void |
1219 | get_country_crq_set (gnutls_x509_crq_t crq) |
1220 | { |
1221 | int ret; |
1222 | |
1223 | if (batch) |
1224 | { |
1225 | if (!cfg.country) |
1226 | return; |
1227 | ret = |
1228 | gnutls_x509_crq_set_dn_by_oid (crq, |
1229 | GNUTLS_OID_X520_COUNTRY_NAME"2.5.4.6", 0, |
1230 | cfg.country, strlen (cfg.country)); |
1231 | if (ret < 0) |
1232 | { |
1233 | fprintf (stderrstderr, "set_dn: %s\n", gnutls_strerror (ret)); |
1234 | exit (1); |
1235 | } |
1236 | } |
1237 | else |
1238 | { |
1239 | read_crq_set (crq, "Country name (2 chars): ", |
1240 | GNUTLS_OID_X520_COUNTRY_NAME"2.5.4.6"); |
1241 | } |
1242 | |
1243 | } |
1244 | |
1245 | void |
1246 | get_organization_crq_set (gnutls_x509_crq_t crq) |
1247 | { |
1248 | int ret; |
1249 | |
1250 | if (batch) |
1251 | { |
1252 | if (!cfg.organization) |
1253 | return; |
1254 | |
1255 | ret = |
1256 | gnutls_x509_crq_set_dn_by_oid (crq, |
1257 | GNUTLS_OID_X520_ORGANIZATION_NAME"2.5.4.10", |
1258 | 0, cfg.organization, |
1259 | strlen (cfg.organization)); |
1260 | if (ret < 0) |
1261 | { |
1262 | fprintf (stderrstderr, "set_dn: %s\n", gnutls_strerror (ret)); |
1263 | exit (1); |
1264 | } |
1265 | } |
1266 | else |
1267 | { |
1268 | read_crq_set (crq, "Organization name: ", |
1269 | GNUTLS_OID_X520_ORGANIZATION_NAME"2.5.4.10"); |
1270 | } |
1271 | |
1272 | } |
1273 | |
1274 | void |
1275 | get_unit_crq_set (gnutls_x509_crq_t crq) |
1276 | { |
1277 | int ret; |
1278 | |
1279 | if (batch) |
1280 | { |
1281 | if (!cfg.unit) |
1282 | return; |
1283 | |
1284 | ret = |
1285 | gnutls_x509_crq_set_dn_by_oid (crq, |
1286 | GNUTLS_OID_X520_ORGANIZATIONAL_UNIT_NAME"2.5.4.11", |
1287 | 0, cfg.unit, strlen (cfg.unit)); |
1288 | if (ret < 0) |
1289 | { |
1290 | fprintf (stderrstderr, "set_dn: %s\n", gnutls_strerror (ret)); |
1291 | exit (1); |
1292 | } |
1293 | } |
1294 | else |
1295 | { |
1296 | read_crq_set (crq, "Organizational unit name: ", |
1297 | GNUTLS_OID_X520_ORGANIZATIONAL_UNIT_NAME"2.5.4.11"); |
1298 | } |
1299 | |
1300 | } |
1301 | |
1302 | void |
1303 | get_state_crq_set (gnutls_x509_crq_t crq) |
1304 | { |
1305 | int ret; |
1306 | |
1307 | if (batch) |
1308 | { |
1309 | if (!cfg.state) |
1310 | return; |
1311 | ret = |
1312 | gnutls_x509_crq_set_dn_by_oid (crq, |
1313 | GNUTLS_OID_X520_STATE_OR_PROVINCE_NAME"2.5.4.8", |
1314 | 0, cfg.state, strlen (cfg.state)); |
1315 | if (ret < 0) |
1316 | { |
1317 | fprintf (stderrstderr, "set_dn: %s\n", gnutls_strerror (ret)); |
1318 | exit (1); |
1319 | } |
1320 | } |
1321 | else |
1322 | { |
1323 | read_crq_set (crq, "State or province name: ", |
1324 | GNUTLS_OID_X520_STATE_OR_PROVINCE_NAME"2.5.4.8"); |
1325 | } |
1326 | |
1327 | } |
1328 | |
1329 | void |
1330 | get_locality_crq_set (gnutls_x509_crq_t crq) |
1331 | { |
1332 | int ret; |
1333 | |
1334 | if (batch) |
1335 | { |
1336 | if (!cfg.locality) |
1337 | return; |
1338 | ret = |
1339 | gnutls_x509_crq_set_dn_by_oid (crq, |
1340 | GNUTLS_OID_X520_LOCALITY_NAME"2.5.4.7", 0, |
1341 | cfg.locality, strlen (cfg.locality)); |
1342 | if (ret < 0) |
1343 | { |
1344 | fprintf (stderrstderr, "set_dn: %s\n", gnutls_strerror (ret)); |
1345 | exit (1); |
1346 | } |
1347 | } |
1348 | else |
1349 | { |
1350 | read_crq_set (crq, "Locality name: ", GNUTLS_OID_X520_LOCALITY_NAME"2.5.4.7"); |
1351 | } |
1352 | |
1353 | } |
1354 | |
1355 | void |
1356 | get_cn_crq_set (gnutls_x509_crq_t crq) |
1357 | { |
1358 | int ret; |
1359 | |
1360 | if (batch) |
1361 | { |
1362 | if (!cfg.cn) |
1363 | return; |
1364 | ret = |
1365 | gnutls_x509_crq_set_dn_by_oid (crq, GNUTLS_OID_X520_COMMON_NAME"2.5.4.3", |
1366 | 0, cfg.cn, strlen (cfg.cn)); |
1367 | if (ret < 0) |
1368 | { |
1369 | fprintf (stderrstderr, "set_dn: %s\n", gnutls_strerror (ret)); |
1370 | exit (1); |
1371 | } |
1372 | } |
1373 | else |
1374 | { |
1375 | read_crq_set (crq, "Common name: ", GNUTLS_OID_X520_COMMON_NAME"2.5.4.3"); |
1376 | } |
1377 | |
1378 | } |
1379 | |
1380 | void |
1381 | get_uid_crq_set (gnutls_x509_crq_t crq) |
1382 | { |
1383 | int ret; |
1384 | |
1385 | if (batch) |
1386 | { |
1387 | if (!cfg.uid) |
1388 | return; |
1389 | ret = gnutls_x509_crq_set_dn_by_oid (crq, GNUTLS_OID_LDAP_UID"0.9.2342.19200300.100.1.1", 0, |
1390 | cfg.uid, strlen (cfg.uid)); |
1391 | if (ret < 0) |
1392 | { |
1393 | fprintf (stderrstderr, "set_dn: %s\n", gnutls_strerror (ret)); |
1394 | exit (1); |
1395 | } |
1396 | } |
1397 | else |
1398 | { |
1399 | read_crq_set (crq, "UID: ", GNUTLS_OID_LDAP_UID"0.9.2342.19200300.100.1.1"); |
1400 | } |
1401 | |
1402 | } |
1403 | |
1404 | void |
1405 | get_oid_crq_set (gnutls_x509_crq_t crq) |
1406 | { |
1407 | int ret, i; |
1408 | |
1409 | if (batch) |
1410 | { |
1411 | if (!cfg.dn_oid) |
1412 | return; |
1413 | for (i = 0; cfg.dn_oid[i] != NULL((void*)0); i += 2) |
1414 | { |
1415 | if (cfg.dn_oid[i + 1] == NULL((void*)0)) |
1416 | { |
1417 | fprintf (stderrstderr, "dn_oid: %s does not have an argument.\n", |
1418 | cfg.dn_oid[i]); |
1419 | exit (1); |
1420 | } |
1421 | ret = gnutls_x509_crq_set_dn_by_oid (crq, cfg.dn_oid[i], 0, |
1422 | cfg.dn_oid[i + 1], |
1423 | strlen (cfg.dn_oid[i + 1])); |
1424 | |
1425 | if (ret < 0) |
1426 | { |
1427 | fprintf (stderrstderr, "set_dn_oid: %s\n", gnutls_strerror (ret)); |
1428 | exit (1); |
1429 | } |
1430 | } |
1431 | } |
1432 | |
1433 | } |