PageRenderTime 45ms CodeModel.GetById 9ms RepoModel.GetById 0ms app.codeStats 1ms

/src/certtool-cfg.c

https://gitlab.com/axil/gnutls
C | 1902 lines | 1596 code | 264 blank | 42 comment | 457 complexity | f56d1cc288d1c18b03aef45d3bac7c65 MD5 | raw file
Possible License(s): LGPL-3.0, GPL-3.0, LGPL-2.1, LGPL-2.0
  1. /*
  2. * Copyright (C) 2004-2014 Free Software Foundation, Inc.
  3. * Copyright (C) 2013,2014 Nikos Mavrogiannopoulos
  4. *
  5. * This file is part of GnuTLS.
  6. *
  7. * GnuTLS is free software: you can redistribute it and/or modify it
  8. * under the terms of the GNU General Public License as published by
  9. * the Free Software Foundation, either version 3 of the License, or
  10. * (at your option) any later version.
  11. *
  12. * GnuTLS is distributed in the hope that it will be useful, but
  13. * WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  15. * General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License
  18. * along with this program. If not, see
  19. * <http://www.gnu.org/licenses/>.
  20. *
  21. * Written by Nikos Mavrogiannopoulos <nmav@gnutls.org>.
  22. */
  23. #include <config.h>
  24. #include <stdio.h>
  25. #include <stdlib.h>
  26. #include <stdint.h>
  27. #include <certtool-cfg.h>
  28. #include <gnutls/x509.h>
  29. #include <string.h>
  30. #include <limits.h>
  31. #include <inttypes.h>
  32. #include <time.h>
  33. #include <parse-datetime.h>
  34. #include <autoopts/options.h>
  35. #include <intprops.h>
  36. #include <gnutls/crypto.h>
  37. /* for inet_pton */
  38. #include <sys/types.h>
  39. #if HAVE_SYS_SOCKET_H
  40. #include <sys/socket.h>
  41. #elif HAVE_WS2TCPIP_H
  42. #include <ws2tcpip.h>
  43. #endif
  44. /* Gnulib portability files. */
  45. #include <getpass.h>
  46. #include "certtool-common.h"
  47. extern int batch;
  48. extern int ask_pass;
  49. #define MAX_ENTRIES 128
  50. #define MAX_POLICIES 8
  51. typedef struct _cfg_ctx {
  52. char *organization;
  53. char *unit;
  54. char *locality;
  55. char *state;
  56. char *dn;
  57. char *cn;
  58. char *uid;
  59. char *challenge_password;
  60. char *pkcs9_email;
  61. char *country;
  62. char *policy_oid[MAX_POLICIES];
  63. char *policy_txt[MAX_POLICIES];
  64. char *policy_url[MAX_POLICIES];
  65. char **dc;
  66. char **dns_name;
  67. char **uri;
  68. char **ip_addr;
  69. char **email;
  70. char **dn_oid;
  71. char **permitted_nc_dns;
  72. char **excluded_nc_dns;
  73. char **permitted_nc_email;
  74. char **excluded_nc_email;
  75. char *crl_dist_points;
  76. char *password;
  77. char *pkcs12_key_name;
  78. char *expiration_date;
  79. char *activation_date;
  80. int64_t serial;
  81. int expiration_days;
  82. int ca;
  83. int path_len;
  84. int tls_www_client;
  85. int tls_www_server;
  86. int signing_key;
  87. int encryption_key;
  88. int cert_sign_key;
  89. int crl_sign_key;
  90. int code_sign_key;
  91. int ocsp_sign_key;
  92. int time_stamping_key;
  93. int ipsec_ike_key;
  94. char **key_purpose_oids;
  95. int crl_next_update;
  96. int crl_number;
  97. int crq_extensions;
  98. char *proxy_policy_language;
  99. char **ocsp_uris;
  100. char **ca_issuers_uris;
  101. } cfg_ctx;
  102. cfg_ctx cfg;
  103. void cfg_init(void)
  104. {
  105. memset(&cfg, 0, sizeof(cfg));
  106. cfg.path_len = -1;
  107. cfg.serial = -1;
  108. }
  109. #define READ_MULTI_LINE(name, s_name) \
  110. val = optionGetValue(pov, name); \
  111. if (val != NULL && val->valType == OPARG_TYPE_STRING) \
  112. { \
  113. if (s_name == NULL) { \
  114. i = 0; \
  115. s_name = malloc(sizeof(char*)*MAX_ENTRIES); \
  116. do { \
  117. if (val && !strcmp(val->pzName, name)==0) \
  118. continue; \
  119. s_name[i] = strdup(val->v.strVal); \
  120. i++; \
  121. if (i>=MAX_ENTRIES) \
  122. break; \
  123. } while((val = optionNextValue(pov, val)) != NULL); \
  124. s_name[i] = NULL; \
  125. } \
  126. }
  127. #define READ_MULTI_LINE_TOKENIZED(name, s_name) \
  128. val = optionGetValue(pov, name); \
  129. if (val != NULL && val->valType == OPARG_TYPE_STRING) \
  130. { \
  131. char str[512]; \
  132. char * p; \
  133. if (s_name == NULL) { \
  134. i = 0; \
  135. s_name = malloc(sizeof(char*)*MAX_ENTRIES); \
  136. do { \
  137. if (val && !strcmp(val->pzName, name)==0) \
  138. continue; \
  139. strncpy(str, val->v.strVal, sizeof(str)-1); \
  140. str[sizeof(str)-1] = 0; \
  141. if ((p=strchr(str, ' ')) == NULL && (p=strchr(str, '\t')) == NULL) { \
  142. fprintf(stderr, "Error parsing %s\n", name); \
  143. exit(1); \
  144. } \
  145. p[0] = 0; \
  146. p++; \
  147. s_name[i] = strdup(str); \
  148. while(*p==' ' || *p == '\t') p++; \
  149. if (p[0] == 0) { \
  150. fprintf(stderr, "Error (2) parsing %s\n", name); \
  151. exit(1); \
  152. } \
  153. s_name[i+1] = strdup(p); \
  154. i+=2; \
  155. if (i>=MAX_ENTRIES) \
  156. break; \
  157. } while((val = optionNextValue(pov, val)) != NULL); \
  158. s_name[i] = NULL; \
  159. } \
  160. }
  161. #define READ_BOOLEAN(name, s_name) \
  162. val = optionGetValue(pov, name); \
  163. if (val != NULL) \
  164. { \
  165. s_name = 1; \
  166. }
  167. #define READ_NUMERIC(name, s_name) \
  168. val = optionGetValue(pov, name); \
  169. if (val != NULL) \
  170. { \
  171. if (val->valType == OPARG_TYPE_NUMERIC) \
  172. s_name = val->v.longVal; \
  173. else if (val->valType == OPARG_TYPE_STRING) \
  174. s_name = strtol(val->v.strVal, NULL, 10); \
  175. }
  176. int template_parse(const char *template)
  177. {
  178. /* Parsing return code */
  179. int ret;
  180. unsigned int i;
  181. tOptionValue const *pov;
  182. const tOptionValue *val;
  183. char tmpstr[256];
  184. pov = configFileLoad(template);
  185. if (pov == NULL) {
  186. perror("configFileLoad");
  187. fprintf(stderr, "Error loading template: %s\n", template);
  188. exit(1);
  189. }
  190. /* Option variables */
  191. val = optionGetValue(pov, "organization");
  192. if (val != NULL && val->valType == OPARG_TYPE_STRING)
  193. cfg.organization = strdup(val->v.strVal);
  194. val = optionGetValue(pov, "unit");
  195. if (val != NULL && val->valType == OPARG_TYPE_STRING)
  196. cfg.unit = strdup(val->v.strVal);
  197. val = optionGetValue(pov, "locality");
  198. if (val != NULL && val->valType == OPARG_TYPE_STRING)
  199. cfg.locality = strdup(val->v.strVal);
  200. val = optionGetValue(pov, "state");
  201. if (val != NULL && val->valType == OPARG_TYPE_STRING)
  202. cfg.state = strdup(val->v.strVal);
  203. val = optionGetValue(pov, "dn");
  204. if (val != NULL && val->valType == OPARG_TYPE_STRING)
  205. cfg.dn = strdup(val->v.strVal);
  206. val = optionGetValue(pov, "cn");
  207. if (val != NULL && val->valType == OPARG_TYPE_STRING)
  208. cfg.cn = strdup(val->v.strVal);
  209. val = optionGetValue(pov, "uid");
  210. if (val != NULL && val->valType == OPARG_TYPE_STRING)
  211. cfg.uid = strdup(val->v.strVal);
  212. val = optionGetValue(pov, "challenge_password");
  213. if (val != NULL && val->valType == OPARG_TYPE_STRING)
  214. cfg.challenge_password = strdup(val->v.strVal);
  215. val = optionGetValue(pov, "password");
  216. if (val != NULL && val->valType == OPARG_TYPE_STRING)
  217. cfg.password = strdup(val->v.strVal);
  218. val = optionGetValue(pov, "pkcs9_email");
  219. if (val != NULL && val->valType == OPARG_TYPE_STRING)
  220. cfg.pkcs9_email = strdup(val->v.strVal);
  221. val = optionGetValue(pov, "country");
  222. if (val != NULL && val->valType == OPARG_TYPE_STRING)
  223. cfg.country = strdup(val->v.strVal);
  224. val = optionGetValue(pov, "expiration_date");
  225. if (val != NULL && val->valType == OPARG_TYPE_STRING)
  226. cfg.expiration_date = strdup(val->v.strVal);
  227. val = optionGetValue(pov, "activation_date");
  228. if (val != NULL && val->valType == OPARG_TYPE_STRING)
  229. cfg.activation_date = strdup(val->v.strVal);
  230. for (i = 0; i < MAX_POLICIES; i++) {
  231. snprintf(tmpstr, sizeof(tmpstr), "policy%d", i + 1);
  232. val = optionGetValue(pov, tmpstr);
  233. if (val != NULL && val->valType == OPARG_TYPE_STRING)
  234. cfg.policy_oid[i] = strdup(val->v.strVal);
  235. if (cfg.policy_oid[i] != NULL) {
  236. snprintf(tmpstr, sizeof(tmpstr), "policy%d_url",
  237. i + 1);
  238. val = optionGetValue(pov, tmpstr);
  239. if (val != NULL
  240. && val->valType == OPARG_TYPE_STRING)
  241. cfg.policy_url[i] = strdup(val->v.strVal);
  242. snprintf(tmpstr, sizeof(tmpstr), "policy%d_txt",
  243. i + 1);
  244. val = optionGetValue(pov, tmpstr);
  245. if (val != NULL
  246. && val->valType == OPARG_TYPE_STRING) {
  247. cfg.policy_txt[i] = strdup(val->v.strVal);
  248. }
  249. }
  250. }
  251. READ_MULTI_LINE("dc", cfg.dc);
  252. READ_MULTI_LINE("dns_name", cfg.dns_name);
  253. READ_MULTI_LINE("uri", cfg.uri);
  254. READ_MULTI_LINE("ip_address", cfg.ip_addr);
  255. READ_MULTI_LINE("email", cfg.email);
  256. READ_MULTI_LINE("key_purpose_oid", cfg.key_purpose_oids);
  257. READ_MULTI_LINE("nc_exclude_dns", cfg.excluded_nc_dns);
  258. READ_MULTI_LINE("nc_exclude_email", cfg.excluded_nc_email);
  259. READ_MULTI_LINE("nc_permit_dns", cfg.permitted_nc_dns);
  260. READ_MULTI_LINE("nc_permit_email", cfg.permitted_nc_email);
  261. READ_MULTI_LINE_TOKENIZED("dn_oid", cfg.dn_oid);
  262. val = optionGetValue(pov, "crl_dist_points");
  263. if (val != NULL && val->valType == OPARG_TYPE_STRING)
  264. cfg.crl_dist_points = strdup(val->v.strVal);
  265. val = optionGetValue(pov, "pkcs12_key_name");
  266. if (val != NULL && val->valType == OPARG_TYPE_STRING)
  267. cfg.pkcs12_key_name = strdup(val->v.strVal);
  268. READ_NUMERIC("serial", cfg.serial);
  269. READ_NUMERIC("expiration_days", cfg.expiration_days);
  270. READ_NUMERIC("crl_next_update", cfg.crl_next_update);
  271. READ_NUMERIC("crl_number", cfg.crl_number);
  272. READ_NUMERIC("path_len", cfg.path_len);
  273. val = optionGetValue(pov, "proxy_policy_language");
  274. if (val != NULL && val->valType == OPARG_TYPE_STRING)
  275. cfg.proxy_policy_language = strdup(val->v.strVal);
  276. READ_MULTI_LINE("ocsp_uri", cfg.ocsp_uris);
  277. READ_MULTI_LINE("ca_issuers_uri", cfg.ca_issuers_uris);
  278. READ_BOOLEAN("ca", cfg.ca);
  279. READ_BOOLEAN("honor_crq_extensions", cfg.crq_extensions);
  280. READ_BOOLEAN("tls_www_client", cfg.tls_www_client);
  281. READ_BOOLEAN("tls_www_server", cfg.tls_www_server);
  282. READ_BOOLEAN("signing_key", cfg.signing_key);
  283. READ_BOOLEAN("encryption_key", cfg.encryption_key);
  284. READ_BOOLEAN("cert_signing_key", cfg.cert_sign_key);
  285. READ_BOOLEAN("crl_signing_key", cfg.crl_sign_key);
  286. READ_BOOLEAN("code_signing_key", cfg.code_sign_key);
  287. READ_BOOLEAN("ocsp_signing_key", cfg.ocsp_sign_key);
  288. READ_BOOLEAN("time_stamping_key", cfg.time_stamping_key);
  289. READ_BOOLEAN("ipsec_ike_key", cfg.ipsec_ike_key);
  290. optionUnloadNested(pov);
  291. return 0;
  292. }
  293. #define IS_NEWLINE(x) ((x[0] == '\n') || (x[0] == '\r'))
  294. void
  295. read_crt_set(gnutls_x509_crt_t crt, const char *input_str, const char *oid)
  296. {
  297. char input[128];
  298. int ret;
  299. fputs(input_str, stderr);
  300. if (fgets(input, sizeof(input), stdin) == NULL)
  301. return;
  302. if (IS_NEWLINE(input))
  303. return;
  304. ret =
  305. gnutls_x509_crt_set_dn_by_oid(crt, oid, 0, input,
  306. strlen(input) - 1);
  307. if (ret < 0) {
  308. fprintf(stderr, "set_dn: %s\n", gnutls_strerror(ret));
  309. exit(1);
  310. }
  311. }
  312. void
  313. read_crq_set(gnutls_x509_crq_t crq, const char *input_str, const char *oid)
  314. {
  315. char input[128];
  316. int ret;
  317. fputs(input_str, stderr);
  318. if (fgets(input, sizeof(input), stdin) == NULL)
  319. return;
  320. if (IS_NEWLINE(input))
  321. return;
  322. ret =
  323. gnutls_x509_crq_set_dn_by_oid(crq, oid, 0, input,
  324. strlen(input) - 1);
  325. if (ret < 0) {
  326. fprintf(stderr, "set_dn: %s\n", gnutls_strerror(ret));
  327. exit(1);
  328. }
  329. }
  330. /* The input_str should contain %d or %u to print the default.
  331. */
  332. static long read_int_with_default(const char *input_str, long def)
  333. {
  334. char *endptr;
  335. long l, len;
  336. static char input[128];
  337. fprintf(stderr, input_str, def);
  338. if (fgets(input, sizeof(input), stdin) == NULL)
  339. return def;
  340. if (IS_NEWLINE(input))
  341. return def;
  342. len = strlen(input);
  343. l = strtol(input, &endptr, 0);
  344. if (*endptr != '\0' && *endptr != '\r' && *endptr != '\n') {
  345. fprintf(stderr, "Trailing garbage ignored: `%s'\n",
  346. endptr);
  347. return 0;
  348. }
  349. if (l <= INT_MIN || l >= INT_MAX) {
  350. fprintf(stderr, "Integer out of range: `%s'\n", input);
  351. return 0;
  352. }
  353. if (input == endptr)
  354. l = def;
  355. return l;
  356. }
  357. long read_int(const char *input_str)
  358. {
  359. return read_int_with_default(input_str, 0);
  360. }
  361. const char *read_str(const char *input_str)
  362. {
  363. static char input[128];
  364. int len;
  365. fputs(input_str, stderr);
  366. if (fgets(input, sizeof(input), stdin) == NULL)
  367. return NULL;
  368. if (IS_NEWLINE(input))
  369. return NULL;
  370. len = strlen(input);
  371. if ((len > 0) && (input[len - 1] == '\n'))
  372. input[len - 1] = 0;
  373. if (input[0] == 0)
  374. return NULL;
  375. return input;
  376. }
  377. /* Default is:
  378. * def: 0 -> no
  379. * def: 1 -> yes
  380. */
  381. int read_yesno(const char *input_str, int def)
  382. {
  383. char input[128];
  384. restart:
  385. fputs(input_str, stderr);
  386. if (fgets(input, sizeof(input), stdin) == NULL)
  387. return def;
  388. if (IS_NEWLINE(input))
  389. return def;
  390. if (input[0] == 'y' || input[0] == 'Y')
  391. return 1;
  392. else if (input[0] == 'n' || input[0] == 'N')
  393. return 0;
  394. else
  395. goto restart;
  396. }
  397. /* Wrapper functions for non-interactive mode.
  398. */
  399. const char *get_pass(void)
  400. {
  401. if (batch && !ask_pass)
  402. return cfg.password;
  403. else
  404. return getpass("Enter password: ");
  405. }
  406. const char *get_confirmed_pass(bool empty_ok)
  407. {
  408. if (batch && !ask_pass)
  409. return cfg.password;
  410. else {
  411. const char *pass = NULL;
  412. char *copy = NULL;
  413. do {
  414. if (pass)
  415. fprintf(stderr,
  416. "Password missmatch, try again.\n");
  417. free(copy);
  418. pass = getpass("Enter password: ");
  419. copy = strdup(pass);
  420. pass = getpass("Confirm password: ");
  421. }
  422. while (strcmp(pass, copy) != 0
  423. && !(empty_ok && *pass == '\0'));
  424. free(copy);
  425. return pass;
  426. }
  427. }
  428. const char *get_challenge_pass(void)
  429. {
  430. if (batch && !ask_pass)
  431. return cfg.challenge_password;
  432. else
  433. return getpass("Enter a challenge password: ");
  434. }
  435. const char *get_crl_dist_point_url(void)
  436. {
  437. if (batch)
  438. return cfg.crl_dist_points;
  439. else
  440. return
  441. read_str
  442. ("Enter the URI of the CRL distribution point: ");
  443. }
  444. void get_country_crt_set(gnutls_x509_crt_t crt)
  445. {
  446. int ret;
  447. if (batch) {
  448. if (!cfg.country)
  449. return;
  450. ret =
  451. gnutls_x509_crt_set_dn_by_oid(crt,
  452. GNUTLS_OID_X520_COUNTRY_NAME,
  453. 0, cfg.country,
  454. strlen(cfg.country));
  455. if (ret < 0) {
  456. fprintf(stderr, "set_dn: %s\n",
  457. gnutls_strerror(ret));
  458. exit(1);
  459. }
  460. } else {
  461. read_crt_set(crt, "Country name (2 chars): ",
  462. GNUTLS_OID_X520_COUNTRY_NAME);
  463. }
  464. }
  465. void get_organization_crt_set(gnutls_x509_crt_t crt)
  466. {
  467. int ret;
  468. if (batch) {
  469. if (!cfg.organization)
  470. return;
  471. ret =
  472. gnutls_x509_crt_set_dn_by_oid(crt,
  473. GNUTLS_OID_X520_ORGANIZATION_NAME,
  474. 0, cfg.organization,
  475. strlen(cfg.
  476. organization));
  477. if (ret < 0) {
  478. fprintf(stderr, "set_dn: %s\n",
  479. gnutls_strerror(ret));
  480. exit(1);
  481. }
  482. } else {
  483. read_crt_set(crt, "Organization name: ",
  484. GNUTLS_OID_X520_ORGANIZATION_NAME);
  485. }
  486. }
  487. void get_unit_crt_set(gnutls_x509_crt_t crt)
  488. {
  489. int ret;
  490. if (batch) {
  491. if (!cfg.unit)
  492. return;
  493. ret =
  494. gnutls_x509_crt_set_dn_by_oid(crt,
  495. GNUTLS_OID_X520_ORGANIZATIONAL_UNIT_NAME,
  496. 0, cfg.unit,
  497. strlen(cfg.unit));
  498. if (ret < 0) {
  499. fprintf(stderr, "set_dn: %s\n",
  500. gnutls_strerror(ret));
  501. exit(1);
  502. }
  503. } else {
  504. read_crt_set(crt, "Organizational unit name: ",
  505. GNUTLS_OID_X520_ORGANIZATIONAL_UNIT_NAME);
  506. }
  507. }
  508. void get_state_crt_set(gnutls_x509_crt_t crt)
  509. {
  510. int ret;
  511. if (batch) {
  512. if (!cfg.state)
  513. return;
  514. ret =
  515. gnutls_x509_crt_set_dn_by_oid(crt,
  516. GNUTLS_OID_X520_STATE_OR_PROVINCE_NAME,
  517. 0, cfg.state,
  518. strlen(cfg.state));
  519. if (ret < 0) {
  520. fprintf(stderr, "set_dn: %s\n",
  521. gnutls_strerror(ret));
  522. exit(1);
  523. }
  524. } else {
  525. read_crt_set(crt, "State or province name: ",
  526. GNUTLS_OID_X520_STATE_OR_PROVINCE_NAME);
  527. }
  528. }
  529. void get_locality_crt_set(gnutls_x509_crt_t crt)
  530. {
  531. int ret;
  532. if (batch) {
  533. if (!cfg.locality)
  534. return;
  535. ret =
  536. gnutls_x509_crt_set_dn_by_oid(crt,
  537. GNUTLS_OID_X520_LOCALITY_NAME,
  538. 0, cfg.locality,
  539. strlen(cfg.locality));
  540. if (ret < 0) {
  541. fprintf(stderr, "set_dn: %s\n",
  542. gnutls_strerror(ret));
  543. exit(1);
  544. }
  545. } else {
  546. read_crt_set(crt, "Locality name: ",
  547. GNUTLS_OID_X520_LOCALITY_NAME);
  548. }
  549. }
  550. void get_cn_crt_set(gnutls_x509_crt_t crt)
  551. {
  552. int ret;
  553. if (batch) {
  554. if (!cfg.cn)
  555. return;
  556. ret =
  557. gnutls_x509_crt_set_dn_by_oid(crt,
  558. GNUTLS_OID_X520_COMMON_NAME,
  559. 0, cfg.cn,
  560. strlen(cfg.cn));
  561. if (ret < 0) {
  562. fprintf(stderr, "set_dn_by_oid: %s\n",
  563. gnutls_strerror(ret));
  564. exit(1);
  565. }
  566. } else {
  567. read_crt_set(crt, "Common name: ",
  568. GNUTLS_OID_X520_COMMON_NAME);
  569. }
  570. }
  571. void get_dn_crt_set(gnutls_x509_crt_t crt)
  572. {
  573. int ret;
  574. const char *err;
  575. if (batch) {
  576. if (!cfg.dn)
  577. return;
  578. ret = gnutls_x509_crt_set_dn(crt, cfg.dn, &err);
  579. if (ret < 0) {
  580. fprintf(stderr, "set_dn: %s at: %s\n",
  581. gnutls_strerror(ret), err);
  582. exit(1);
  583. }
  584. }
  585. }
  586. void crt_constraints_set(gnutls_x509_crt_t crt)
  587. {
  588. int ret;
  589. const char *err;
  590. unsigned i;
  591. gnutls_x509_name_constraints_t nc;
  592. gnutls_datum_t name;
  593. if (batch) {
  594. if (cfg.permitted_nc_dns == NULL && cfg.permitted_nc_email == NULL &&
  595. cfg.excluded_nc_dns == NULL && cfg.excluded_nc_email == NULL)
  596. return; /* nothing to do */
  597. ret = gnutls_x509_name_constraints_init(&nc);
  598. if (ret < 0) {
  599. fprintf(stderr, "nc_init: %s\n", gnutls_strerror(ret));
  600. exit(1);
  601. }
  602. if (cfg.permitted_nc_dns) {
  603. for (i = 0; cfg.permitted_nc_dns[i] != NULL; i++) {
  604. name.data = cfg.permitted_nc_dns[i];
  605. name.size = strlen((char*)name.data);
  606. ret = gnutls_x509_name_constraints_add_permitted(nc, GNUTLS_SAN_DNSNAME, &name);
  607. if (ret < 0) {
  608. fprintf(stderr, "error adding constraint: %s\n", gnutls_strerror(ret));
  609. exit(1);
  610. }
  611. }
  612. }
  613. if (cfg.excluded_nc_dns) {
  614. for (i = 0; cfg.excluded_nc_dns[i] != NULL; i++) {
  615. name.data = cfg.excluded_nc_dns[i];
  616. name.size = strlen((char*)name.data);
  617. ret = gnutls_x509_name_constraints_add_excluded(nc, GNUTLS_SAN_DNSNAME, &name);
  618. if (ret < 0) {
  619. fprintf(stderr, "error adding constraint: %s\n", gnutls_strerror(ret));
  620. exit(1);
  621. }
  622. }
  623. }
  624. if (cfg.permitted_nc_email) {
  625. for (i = 0; cfg.permitted_nc_email[i] != NULL; i++) {
  626. name.data = cfg.permitted_nc_email[i];
  627. name.size = strlen((char*)name.data);
  628. ret = gnutls_x509_name_constraints_add_permitted(nc, GNUTLS_SAN_RFC822NAME, &name);
  629. if (ret < 0) {
  630. fprintf(stderr, "error adding constraint: %s\n", gnutls_strerror(ret));
  631. exit(1);
  632. }
  633. }
  634. }
  635. if (cfg.permitted_nc_email) {
  636. for (i = 0; cfg.excluded_nc_email[i] != NULL; i++) {
  637. name.data = cfg.excluded_nc_email[i];
  638. name.size = strlen((char*)name.data);
  639. ret = gnutls_x509_name_constraints_add_excluded(nc, GNUTLS_SAN_RFC822NAME, &name);
  640. if (ret < 0) {
  641. fprintf(stderr, "error adding constraint: %s\n", gnutls_strerror(ret));
  642. exit(1);
  643. }
  644. }
  645. }
  646. ret = gnutls_x509_crt_set_name_constraints(crt, nc, 1);
  647. if (ret < 0) {
  648. fprintf(stderr, "error setting constraints: %s\n", gnutls_strerror(ret));
  649. exit(1);
  650. }
  651. gnutls_x509_name_constraints_deinit(nc);
  652. }
  653. }
  654. void get_uid_crt_set(gnutls_x509_crt_t crt)
  655. {
  656. int ret;
  657. if (batch) {
  658. if (!cfg.uid)
  659. return;
  660. ret =
  661. gnutls_x509_crt_set_dn_by_oid(crt, GNUTLS_OID_LDAP_UID,
  662. 0, cfg.uid,
  663. strlen(cfg.uid));
  664. if (ret < 0) {
  665. fprintf(stderr, "set_dn: %s\n",
  666. gnutls_strerror(ret));
  667. exit(1);
  668. }
  669. } else {
  670. read_crt_set(crt, "UID: ", GNUTLS_OID_LDAP_UID);
  671. }
  672. }
  673. void get_oid_crt_set(gnutls_x509_crt_t crt)
  674. {
  675. int ret, i;
  676. if (batch) {
  677. if (!cfg.dn_oid)
  678. return;
  679. for (i = 0; cfg.dn_oid[i] != NULL; i += 2) {
  680. if (cfg.dn_oid[i + 1] == NULL) {
  681. fprintf(stderr,
  682. "dn_oid: %s does not have an argument.\n",
  683. cfg.dn_oid[i]);
  684. exit(1);
  685. }
  686. ret =
  687. gnutls_x509_crt_set_dn_by_oid(crt,
  688. cfg.dn_oid[i], 0,
  689. cfg.dn_oid[i +
  690. 1],
  691. strlen(cfg.
  692. dn_oid[i +
  693. 1]));
  694. if (ret < 0) {
  695. fprintf(stderr, "set_dn_oid: %s\n",
  696. gnutls_strerror(ret));
  697. exit(1);
  698. }
  699. }
  700. }
  701. }
  702. void get_key_purpose_set(int type, void *crt)
  703. {
  704. int ret, i;
  705. if (batch) {
  706. if (!cfg.key_purpose_oids)
  707. return;
  708. for (i = 0; cfg.key_purpose_oids[i] != NULL; i++) {
  709. if (type == TYPE_CRT)
  710. ret =
  711. gnutls_x509_crt_set_key_purpose_oid
  712. (crt, cfg.key_purpose_oids[i], 0);
  713. else
  714. ret =
  715. gnutls_x509_crq_set_key_purpose_oid
  716. (crt, cfg.key_purpose_oids[i], 0);
  717. if (ret < 0) {
  718. fprintf(stderr,
  719. "set_key_purpose_oid (%s): %s\n",
  720. cfg.key_purpose_oids[i],
  721. gnutls_strerror(ret));
  722. exit(1);
  723. }
  724. }
  725. }
  726. }
  727. void get_ocsp_issuer_set(gnutls_x509_crt_t crt)
  728. {
  729. int ret, i;
  730. gnutls_datum_t uri;
  731. if (batch) {
  732. if (!cfg.ocsp_uris)
  733. return;
  734. for (i = 0; cfg.ocsp_uris[i] != NULL; i++) {
  735. uri.data = cfg.ocsp_uris[i];
  736. uri.size = strlen(cfg.ocsp_uris[i]);
  737. ret =
  738. gnutls_x509_crt_set_authority_info_access(crt,
  739. GNUTLS_IA_OCSP_URI,
  740. &uri);
  741. if (ret < 0) {
  742. fprintf(stderr, "set OCSP URI (%s): %s\n",
  743. cfg.ocsp_uris[i],
  744. gnutls_strerror(ret));
  745. exit(1);
  746. }
  747. }
  748. }
  749. }
  750. void get_ca_issuers_set(gnutls_x509_crt_t crt)
  751. {
  752. int ret, i;
  753. gnutls_datum_t uri;
  754. if (batch) {
  755. if (!cfg.ca_issuers_uris)
  756. return;
  757. for (i = 0; cfg.ca_issuers_uris[i] != NULL; i++) {
  758. uri.data = cfg.ca_issuers_uris[i];
  759. uri.size = strlen(cfg.ca_issuers_uris[i]);
  760. ret =
  761. gnutls_x509_crt_set_authority_info_access(crt,
  762. GNUTLS_IA_CAISSUERS_URI,
  763. &uri);
  764. if (ret < 0) {
  765. fprintf(stderr,
  766. "set CA ISSUERS URI (%s): %s\n",
  767. cfg.ca_issuers_uris[i],
  768. gnutls_strerror(ret));
  769. exit(1);
  770. }
  771. }
  772. }
  773. }
  774. void get_pkcs9_email_crt_set(gnutls_x509_crt_t crt)
  775. {
  776. int ret;
  777. if (batch) {
  778. if (!cfg.pkcs9_email)
  779. return;
  780. ret =
  781. gnutls_x509_crt_set_dn_by_oid(crt,
  782. GNUTLS_OID_PKCS9_EMAIL,
  783. 0, cfg.pkcs9_email,
  784. strlen(cfg.pkcs9_email));
  785. if (ret < 0) {
  786. fprintf(stderr, "set_dn: %s\n",
  787. gnutls_strerror(ret));
  788. exit(1);
  789. }
  790. } else {
  791. read_crt_set(crt, "E-mail: ", GNUTLS_OID_PKCS9_EMAIL);
  792. }
  793. }
  794. void get_serial(unsigned char* serial, size_t * size)
  795. {
  796. struct timespec ts;
  797. char dserial[12];
  798. uint32_t default_serial[2];
  799. /* default format:
  800. * | 4 b | 4 b | 4b
  801. * | secs | nsecs | rnd |
  802. */
  803. gettime(&ts);
  804. if (*size < 12) {
  805. fprintf(stderr, "error in get_serial()!\n");
  806. exit(1);
  807. }
  808. if (batch && cfg.serial < 0) {
  809. serial[0] = (ts.tv_sec >> 24) & 0xff;
  810. serial[1] = (ts.tv_sec >> 16) & 0xff;
  811. serial[2] = (ts.tv_sec >> 8) & 0xff;
  812. serial[3] = (ts.tv_sec) & 0xff;
  813. serial[4] = (ts.tv_nsec >> 24) & 0xff;
  814. serial[5] = (ts.tv_nsec >> 16) & 0xff;
  815. serial[6] = (ts.tv_nsec >> 8) & 0xff;
  816. serial[7] = (ts.tv_nsec) & 0xff;
  817. serial[0] &= 0x7F;
  818. gnutls_rnd(GNUTLS_RND_NONCE, &serial[8], 4);
  819. *size = 12;
  820. return;
  821. }
  822. if (batch) {
  823. default_serial[0] = cfg.serial >> 32;
  824. default_serial[1] = cfg.serial;
  825. } else {
  826. unsigned long default_serial_int = (ts.tv_sec << 32) | ts.tv_nsec;
  827. default_serial_int = read_int_with_default
  828. ("Enter the certificate's serial number in decimal (default: %lu): ",
  829. (unsigned long)default_serial_int);
  830. default_serial[0] = default_serial_int >> 32;
  831. default_serial[1] = default_serial_int;
  832. }
  833. serial[0] = (default_serial[0] >> 24) & 0xff;
  834. serial[1] = (default_serial[0] >> 16) & 0xff;
  835. serial[2] = (default_serial[0] >> 8) & 0xff;
  836. serial[3] = (default_serial[0]) & 0xff;
  837. serial[4] = (default_serial[1] >> 24) & 0xff;
  838. serial[5] = (default_serial[1] >> 16) & 0xff;
  839. serial[6] = (default_serial[1] >> 8) & 0xff;
  840. serial[7] = (default_serial[1]) & 0xff;
  841. serial[0] &= 0x7F;
  842. *size = 8;
  843. return;
  844. }
  845. static
  846. time_t get_date(const char* date)
  847. {
  848. time_t t;
  849. struct timespec r;
  850. if (date==NULL || parse_datetime(&r, date, NULL) == 0) {
  851. fprintf(stderr, "Cannot parse date: %s\n", date);
  852. exit(1);
  853. }
  854. return r.tv_sec;
  855. }
  856. time_t get_activation_date()
  857. {
  858. if (batch && cfg.activation_date != NULL) {
  859. return get_date(cfg.activation_date);
  860. }
  861. return time(NULL);
  862. }
  863. static
  864. time_t days_to_secs(int days)
  865. {
  866. time_t secs = days;
  867. time_t now = time(NULL);
  868. if (secs != (time_t)-1) {
  869. if (INT_MULTIPLY_OVERFLOW(secs, 24*60*60)) {
  870. secs = -1;
  871. } else {
  872. secs *= 24*60*60;
  873. }
  874. }
  875. if (secs != (time_t)-1) {
  876. if (INT_ADD_OVERFLOW(secs, now)) {
  877. secs = -1;
  878. } else {
  879. secs += now;
  880. }
  881. }
  882. return secs;
  883. }
  884. time_t get_expiration_date()
  885. {
  886. if (batch) {
  887. if (cfg.expiration_date == NULL) {
  888. time_t secs, now;
  889. now = time(NULL);
  890. if (cfg.expiration_days == 0 || cfg.expiration_days < -2)
  891. secs = days_to_secs(365);
  892. else {
  893. secs = days_to_secs(cfg.expiration_days);
  894. }
  895. return secs;
  896. } else
  897. return get_date(cfg.expiration_date);
  898. } else {
  899. int days;
  900. do {
  901. days =
  902. read_int
  903. ("The certificate will expire in (days): ");
  904. }
  905. while (days == 0);
  906. return days_to_secs(days);
  907. }
  908. }
  909. int get_ca_status(void)
  910. {
  911. if (batch) {
  912. return cfg.ca;
  913. } else {
  914. return
  915. read_yesno
  916. ("Does the certificate belong to an authority? (y/N): ",
  917. 0);
  918. }
  919. }
  920. int get_crq_extensions_status(void)
  921. {
  922. if (batch) {
  923. return cfg.crq_extensions;
  924. } else {
  925. return
  926. read_yesno
  927. ("Do you want to honour the extensions from the request? (y/N): ",
  928. 0);
  929. }
  930. }
  931. int get_crl_number(void)
  932. {
  933. if (batch) {
  934. return cfg.crl_number;
  935. } else {
  936. return read_int_with_default("CRL Number: ", 1);
  937. }
  938. }
  939. int get_path_len(void)
  940. {
  941. if (batch) {
  942. return cfg.path_len;
  943. } else {
  944. return read_int_with_default
  945. ("Path length constraint (decimal, %d for no constraint): ",
  946. -1);
  947. }
  948. }
  949. const char *get_pkcs12_key_name(void)
  950. {
  951. const char *name;
  952. if (batch) {
  953. if (!cfg.pkcs12_key_name)
  954. return "Anonymous";
  955. return cfg.pkcs12_key_name;
  956. } else {
  957. do {
  958. name = read_str("Enter a name for the key: ");
  959. }
  960. while (name == NULL);
  961. }
  962. return name;
  963. }
  964. int get_tls_client_status(void)
  965. {
  966. if (batch) {
  967. return cfg.tls_www_client;
  968. } else {
  969. return
  970. read_yesno
  971. ("Is this a TLS web client certificate? (y/N): ", 0);
  972. }
  973. }
  974. int get_tls_server_status(void)
  975. {
  976. if (batch) {
  977. return cfg.tls_www_server;
  978. } else {
  979. return
  980. read_yesno
  981. ("Is this a TLS web server certificate? (y/N): ", 0);
  982. }
  983. }
  984. /* convert a printable IP to binary */
  985. static int string_to_ip(unsigned char *ip, const char *str)
  986. {
  987. int len = strlen(str);
  988. int ret;
  989. #if HAVE_IPV6
  990. if (strchr(str, ':') != NULL || len > 16) { /* IPv6 */
  991. ret = inet_pton(AF_INET6, str, ip);
  992. if (ret <= 0) {
  993. fprintf(stderr, "Error in IPv6 address %s\n", str);
  994. exit(1);
  995. }
  996. /* To be done */
  997. return 16;
  998. } else
  999. #endif
  1000. { /* IPv4 */
  1001. ret = inet_pton(AF_INET, str, ip);
  1002. if (ret <= 0) {
  1003. fprintf(stderr, "Error in IPv4 address %s\n", str);
  1004. exit(1);
  1005. }
  1006. return 4;
  1007. }
  1008. }
  1009. void get_ip_addr_set(int type, void *crt)
  1010. {
  1011. int ret = 0, i;
  1012. unsigned char ip[16];
  1013. int len;
  1014. if (batch) {
  1015. if (!cfg.ip_addr)
  1016. return;
  1017. for (i = 0; cfg.ip_addr[i] != NULL; i++) {
  1018. len = string_to_ip(ip, cfg.ip_addr[i]);
  1019. if (len <= 0) {
  1020. fprintf(stderr,
  1021. "Error parsing address: %s\n",
  1022. cfg.ip_addr[i]);
  1023. exit(1);
  1024. }
  1025. if (type == TYPE_CRT)
  1026. ret =
  1027. gnutls_x509_crt_set_subject_alt_name
  1028. (crt, GNUTLS_SAN_IPADDRESS, ip, len,
  1029. GNUTLS_FSAN_APPEND);
  1030. else
  1031. ret =
  1032. gnutls_x509_crq_set_subject_alt_name
  1033. (crt, GNUTLS_SAN_IPADDRESS, ip, len,
  1034. GNUTLS_FSAN_APPEND);
  1035. if (ret < 0)
  1036. break;
  1037. }
  1038. } else {
  1039. const char *p;
  1040. p = read_str
  1041. ("Enter the IP address of the subject of the certificate: ");
  1042. if (!p)
  1043. return;
  1044. len = string_to_ip(ip, p);
  1045. if (len <= 0) {
  1046. fprintf(stderr, "Error parsing address: %s\n", p);
  1047. exit(1);
  1048. }
  1049. if (type == TYPE_CRT)
  1050. ret =
  1051. gnutls_x509_crt_set_subject_alt_name(crt,
  1052. GNUTLS_SAN_IPADDRESS,
  1053. ip, len,
  1054. GNUTLS_FSAN_APPEND);
  1055. else
  1056. ret =
  1057. gnutls_x509_crq_set_subject_alt_name(crt,
  1058. GNUTLS_SAN_IPADDRESS,
  1059. ip, len,
  1060. GNUTLS_FSAN_APPEND);
  1061. }
  1062. if (ret < 0) {
  1063. fprintf(stderr, "set_subject_alt_name: %s\n",
  1064. gnutls_strerror(ret));
  1065. exit(1);
  1066. }
  1067. }
  1068. void get_email_set(int type, void *crt)
  1069. {
  1070. int ret = 0, i;
  1071. if (batch) {
  1072. if (!cfg.email)
  1073. return;
  1074. for (i = 0; cfg.email[i] != NULL; i++) {
  1075. if (type == TYPE_CRT)
  1076. ret =
  1077. gnutls_x509_crt_set_subject_alt_name
  1078. (crt, GNUTLS_SAN_RFC822NAME,
  1079. cfg.email[i], strlen(cfg.email[i]),
  1080. GNUTLS_FSAN_APPEND);
  1081. else
  1082. ret =
  1083. gnutls_x509_crq_set_subject_alt_name
  1084. (crt, GNUTLS_SAN_RFC822NAME,
  1085. cfg.email[i], strlen(cfg.email[i]),
  1086. GNUTLS_FSAN_APPEND);
  1087. if (ret < 0)
  1088. break;
  1089. }
  1090. } else {
  1091. const char *p;
  1092. p = read_str
  1093. ("Enter the e-mail of the subject of the certificate: ");
  1094. if (!p)
  1095. return;
  1096. if (type == TYPE_CRT)
  1097. ret =
  1098. gnutls_x509_crt_set_subject_alt_name(crt,
  1099. GNUTLS_SAN_RFC822NAME,
  1100. p,
  1101. strlen(p),
  1102. GNUTLS_FSAN_APPEND);
  1103. else
  1104. ret =
  1105. gnutls_x509_crq_set_subject_alt_name(crt,
  1106. GNUTLS_SAN_RFC822NAME,
  1107. p,
  1108. strlen(p),
  1109. GNUTLS_FSAN_APPEND);
  1110. }
  1111. if (ret < 0) {
  1112. fprintf(stderr, "set_subject_alt_name: %s\n",
  1113. gnutls_strerror(ret));
  1114. exit(1);
  1115. }
  1116. }
  1117. void get_dc_set(int type, void *crt)
  1118. {
  1119. int ret = 0, i;
  1120. if (batch) {
  1121. if (!cfg.dc)
  1122. return;
  1123. for (i = 0; cfg.dc[i] != NULL; i++) {
  1124. if (type == TYPE_CRT)
  1125. ret =
  1126. gnutls_x509_crt_set_dn_by_oid(crt,
  1127. GNUTLS_OID_LDAP_DC,
  1128. 0,
  1129. cfg.
  1130. dc[i],
  1131. strlen
  1132. (cfg.
  1133. dc[i]));
  1134. else
  1135. ret =
  1136. gnutls_x509_crq_set_dn_by_oid(crt,
  1137. GNUTLS_OID_LDAP_DC,
  1138. 0,
  1139. cfg.
  1140. dc[i],
  1141. strlen
  1142. (cfg.
  1143. dc[i]));
  1144. if (ret < 0)
  1145. break;
  1146. }
  1147. } else {
  1148. const char *p;
  1149. do {
  1150. p = read_str
  1151. ("Enter the subject's domain component (DC): ");
  1152. if (!p)
  1153. return;
  1154. if (type == TYPE_CRT)
  1155. ret =
  1156. gnutls_x509_crt_set_dn_by_oid(crt,
  1157. GNUTLS_OID_LDAP_DC,
  1158. 0, p,
  1159. strlen
  1160. (p));
  1161. else
  1162. ret =
  1163. gnutls_x509_crq_set_dn_by_oid(crt,
  1164. GNUTLS_OID_LDAP_DC,
  1165. 0, p,
  1166. strlen
  1167. (p));
  1168. }
  1169. while (p != NULL);
  1170. }
  1171. if (ret < 0) {
  1172. fprintf(stderr, "set_dn_by_oid: %s\n",
  1173. gnutls_strerror(ret));
  1174. exit(1);
  1175. }
  1176. }
  1177. void get_dns_name_set(int type, void *crt)
  1178. {
  1179. int ret = 0, i;
  1180. if (batch) {
  1181. if (!cfg.dns_name)
  1182. return;
  1183. for (i = 0; cfg.dns_name[i] != NULL; i++) {
  1184. if (type == TYPE_CRT)
  1185. ret =
  1186. gnutls_x509_crt_set_subject_alt_name
  1187. (crt, GNUTLS_SAN_DNSNAME,
  1188. cfg.dns_name[i],
  1189. strlen(cfg.dns_name[i]),
  1190. GNUTLS_FSAN_APPEND);
  1191. else
  1192. ret =
  1193. gnutls_x509_crq_set_subject_alt_name
  1194. (crt, GNUTLS_SAN_DNSNAME,
  1195. cfg.dns_name[i],
  1196. strlen(cfg.dns_name[i]),
  1197. GNUTLS_FSAN_APPEND);
  1198. if (ret < 0)
  1199. break;
  1200. }
  1201. } else {
  1202. const char *p;
  1203. do {
  1204. p = read_str
  1205. ("Enter a dnsName of the subject of the certificate: ");
  1206. if (!p)
  1207. return;
  1208. if (type == TYPE_CRT)
  1209. ret = gnutls_x509_crt_set_subject_alt_name
  1210. (crt, GNUTLS_SAN_DNSNAME, p, strlen(p),
  1211. GNUTLS_FSAN_APPEND);
  1212. else
  1213. ret = gnutls_x509_crq_set_subject_alt_name
  1214. (crt, GNUTLS_SAN_DNSNAME, p, strlen(p),
  1215. GNUTLS_FSAN_APPEND);
  1216. }
  1217. while (p);
  1218. }
  1219. if (ret < 0) {
  1220. fprintf(stderr, "set_subject_alt_name: %s\n",
  1221. gnutls_strerror(ret));
  1222. exit(1);
  1223. }
  1224. }
  1225. void get_policy_set(gnutls_x509_crt_t crt)
  1226. {
  1227. int ret = 0, i;
  1228. gnutls_x509_policy_st policy;
  1229. if (batch) {
  1230. if (!cfg.policy_oid)
  1231. return;
  1232. for (i = 0; cfg.policy_oid[i] != NULL; i++) {
  1233. memset(&policy, 0, sizeof(policy));
  1234. policy.oid = cfg.policy_oid[i];
  1235. if (cfg.policy_txt[i] != NULL) {
  1236. policy.qualifier[policy.qualifiers].type =
  1237. GNUTLS_X509_QUALIFIER_NOTICE;
  1238. policy.qualifier[policy.qualifiers].data =
  1239. cfg.policy_txt[i];
  1240. policy.qualifier[policy.qualifiers].size =
  1241. strlen(cfg.policy_txt[i]);
  1242. policy.qualifiers++;
  1243. }
  1244. if (cfg.policy_url[i] != NULL) {
  1245. policy.qualifier[policy.qualifiers].type =
  1246. GNUTLS_X509_QUALIFIER_URI;
  1247. policy.qualifier[policy.qualifiers].data =
  1248. cfg.policy_url[i];
  1249. policy.qualifier[policy.qualifiers].size =
  1250. strlen(cfg.policy_url[i]);
  1251. policy.qualifiers++;
  1252. }
  1253. ret = gnutls_x509_crt_set_policy(crt, &policy, 0);
  1254. if (ret < 0)
  1255. break;
  1256. }
  1257. }
  1258. if (ret < 0) {
  1259. fprintf(stderr, "set_policy: %s\n", gnutls_strerror(ret));
  1260. exit(1);
  1261. }
  1262. }
  1263. void get_uri_set(int type, void *crt)
  1264. {
  1265. int ret = 0, i;
  1266. if (batch) {
  1267. if (!cfg.uri)
  1268. return;
  1269. for (i = 0; cfg.uri[i] != NULL; i++) {
  1270. if (type == TYPE_CRT)
  1271. ret =
  1272. gnutls_x509_crt_set_subject_alt_name
  1273. (crt, GNUTLS_SAN_URI, cfg.uri[i],
  1274. strlen(cfg.uri[i]),
  1275. GNUTLS_FSAN_APPEND);
  1276. else
  1277. ret =
  1278. gnutls_x509_crq_set_subject_alt_name
  1279. (crt, GNUTLS_SAN_URI, cfg.uri[i],
  1280. strlen(cfg.uri[i]),
  1281. GNUTLS_FSAN_APPEND);
  1282. if (ret < 0)
  1283. break;
  1284. }
  1285. } else {
  1286. const char *p;
  1287. do {
  1288. p = read_str
  1289. ("Enter a URI of the subject of the certificate: ");
  1290. if (!p)
  1291. return;
  1292. if (type == TYPE_CRT)
  1293. ret = gnutls_x509_crt_set_subject_alt_name
  1294. (crt, GNUTLS_SAN_URI, p, strlen(p),
  1295. GNUTLS_FSAN_APPEND);
  1296. else
  1297. ret = gnutls_x509_crq_set_subject_alt_name
  1298. (crt, GNUTLS_SAN_URI, p, strlen(p),
  1299. GNUTLS_FSAN_APPEND);
  1300. }
  1301. while (p);
  1302. }
  1303. if (ret < 0) {
  1304. fprintf(stderr, "set_subject_alt_name: %s\n",
  1305. gnutls_strerror(ret));
  1306. exit(1);
  1307. }
  1308. }
  1309. int get_sign_status(int server)
  1310. {
  1311. const char *msg;
  1312. if (batch) {
  1313. return cfg.signing_key;
  1314. } else {
  1315. if (server)
  1316. msg =
  1317. "Will the certificate be used for signing (DHE and RSA-EXPORT ciphersuites)? (Y/n): ";
  1318. else
  1319. msg =
  1320. "Will the certificate be used for signing (required for TLS)? (Y/n): ";
  1321. return read_yesno(msg, 1);
  1322. }
  1323. }
  1324. int get_encrypt_status(int server)
  1325. {
  1326. const char *msg;
  1327. if (batch) {
  1328. return cfg.encryption_key;
  1329. } else {
  1330. if (server)
  1331. msg =
  1332. "Will the certificate be used for encryption (RSA ciphersuites)? (Y/n): ";
  1333. else
  1334. msg =
  1335. "Will the certificate be used for encryption (not required for TLS)? (Y/n): ";
  1336. return read_yesno(msg, 1);
  1337. }
  1338. }
  1339. int get_cert_sign_status(void)
  1340. {
  1341. if (batch) {
  1342. return cfg.cert_sign_key;
  1343. } else {
  1344. return
  1345. read_yesno
  1346. ("Will the certificate be used to sign other certificates? (y/N): ",
  1347. 0);
  1348. }
  1349. }
  1350. int get_crl_sign_status(void)
  1351. {
  1352. if (batch) {
  1353. return cfg.crl_sign_key;
  1354. } else {
  1355. return
  1356. read_yesno
  1357. ("Will the certificate be used to sign CRLs? (y/N): ",
  1358. 0);
  1359. }
  1360. }
  1361. int get_code_sign_status(void)
  1362. {
  1363. if (batch) {
  1364. return cfg.code_sign_key;
  1365. } else {
  1366. return
  1367. read_yesno
  1368. ("Will the certificate be used to sign code? (y/N): ",
  1369. 0);
  1370. }
  1371. }
  1372. int get_ocsp_sign_status(void)
  1373. {
  1374. if (batch) {
  1375. return cfg.ocsp_sign_key;
  1376. } else {
  1377. return
  1378. read_yesno
  1379. ("Will the certificate be used to sign OCSP requests? (y/N): ",
  1380. 0);
  1381. }
  1382. }
  1383. int get_time_stamp_status(void)
  1384. {
  1385. if (batch) {
  1386. return cfg.time_stamping_key;
  1387. } else {
  1388. return
  1389. read_yesno
  1390. ("Will the certificate be used for time stamping? (y/N): ",
  1391. 0);
  1392. }
  1393. }
  1394. int get_ipsec_ike_status(void)
  1395. {
  1396. if (batch) {
  1397. return cfg.ipsec_ike_key;
  1398. } else {
  1399. return
  1400. read_yesno
  1401. ("Will the certificate be used for IPsec IKE operations? (y/N): ",
  1402. 0);
  1403. }
  1404. }
  1405. int get_crl_next_update(void)
  1406. {
  1407. int days;
  1408. if (batch) {
  1409. if (cfg.crl_next_update <= 0)
  1410. return 365;
  1411. else
  1412. return cfg.crl_next_update;
  1413. } else {
  1414. do {
  1415. days =
  1416. read_int
  1417. ("The next CRL will be issued in (days): ");
  1418. }
  1419. while (days == 0);
  1420. return days;
  1421. }
  1422. }
  1423. const char *get_proxy_policy(char **policy, size_t * policylen)
  1424. {
  1425. const char *ret;
  1426. if (batch) {
  1427. ret = cfg.proxy_policy_language;
  1428. if (!ret)
  1429. ret = "1.3.6.1.5.5.7.21.1";
  1430. } else {
  1431. do {
  1432. ret =
  1433. read_str
  1434. ("Enter the OID of the proxy policy language: ");
  1435. }
  1436. while (ret == NULL);
  1437. }
  1438. *policy = NULL;
  1439. *policylen = 0;
  1440. if (strcmp(ret, "1.3.6.1.5.5.7.21.1") != 0 &&
  1441. strcmp(ret, "1.3.6.1.5.5.7.21.2") != 0) {
  1442. fprintf(stderr,
  1443. "Reading non-standard proxy policy not supported.\n");
  1444. }
  1445. return ret;
  1446. }
  1447. /* CRQ stuff.
  1448. */
  1449. void get_country_crq_set(gnutls_x509_crq_t crq)
  1450. {
  1451. int ret;
  1452. if (batch) {
  1453. if (!cfg.country)
  1454. return;
  1455. ret =
  1456. gnutls_x509_crq_set_dn_by_oid(crq,
  1457. GNUTLS_OID_X520_COUNTRY_NAME,
  1458. 0, cfg.country,
  1459. strlen(cfg.country));
  1460. if (ret < 0) {
  1461. fprintf(stderr, "set_dn: %s\n",
  1462. gnutls_strerror(ret));
  1463. exit(1);
  1464. }
  1465. } else {
  1466. read_crq_set(crq, "Country name (2 chars): ",
  1467. GNUTLS_OID_X520_COUNTRY_NAME);
  1468. }
  1469. }
  1470. void get_organization_crq_set(gnutls_x509_crq_t crq)
  1471. {
  1472. int ret;
  1473. if (batch) {
  1474. if (!cfg.organization)
  1475. return;
  1476. ret =
  1477. gnutls_x509_crq_set_dn_by_oid(crq,
  1478. GNUTLS_OID_X520_ORGANIZATION_NAME,
  1479. 0, cfg.organization,
  1480. strlen(cfg.
  1481. organization));
  1482. if (ret < 0) {
  1483. fprintf(stderr, "set_dn: %s\n",
  1484. gnutls_strerror(ret));
  1485. exit(1);
  1486. }
  1487. } else {
  1488. read_crq_set(crq, "Organization name: ",
  1489. GNUTLS_OID_X520_ORGANIZATION_NAME);
  1490. }
  1491. }
  1492. void get_unit_crq_set(gnutls_x509_crq_t crq)
  1493. {
  1494. int ret;
  1495. if (batch) {
  1496. if (!cfg.unit)
  1497. return;
  1498. ret =
  1499. gnutls_x509_crq_set_dn_by_oid(crq,
  1500. GNUTLS_OID_X520_ORGANIZATIONAL_UNIT_NAME,
  1501. 0, cfg.unit,
  1502. strlen(cfg.unit));
  1503. if (ret < 0) {
  1504. fprintf(stderr, "set_dn: %s\n",
  1505. gnutls_strerror(ret));
  1506. exit(1);
  1507. }
  1508. } else {
  1509. read_crq_set(crq, "Organizational unit name: ",
  1510. GNUTLS_OID_X520_ORGANIZATIONAL_UNIT_NAME);
  1511. }
  1512. }
  1513. void get_state_crq_set(gnutls_x509_crq_t crq)
  1514. {
  1515. int ret;
  1516. if (batch) {
  1517. if (!cfg.state)
  1518. return;
  1519. ret =
  1520. gnutls_x509_crq_set_dn_by_oid(crq,
  1521. GNUTLS_OID_X520_STATE_OR_PROVINCE_NAME,
  1522. 0, cfg.state,
  1523. strlen(cfg.state));
  1524. if (ret < 0) {
  1525. fprintf(stderr, "set_dn: %s\n",
  1526. gnutls_strerror(ret));
  1527. exit(1);
  1528. }
  1529. } else {
  1530. read_crq_set(crq, "State or province name: ",
  1531. GNUTLS_OID_X520_STATE_OR_PROVINCE_NAME);
  1532. }
  1533. }
  1534. void get_locality_crq_set(gnutls_x509_crq_t crq)
  1535. {
  1536. int ret;
  1537. if (batch) {
  1538. if (!cfg.locality)
  1539. return;
  1540. ret =
  1541. gnutls_x509_crq_set_dn_by_oid(crq,
  1542. GNUTLS_OID_X520_LOCALITY_NAME,
  1543. 0, cfg.locality,
  1544. strlen(cfg.locality));
  1545. if (ret < 0) {
  1546. fprintf(stderr, "set_dn: %s\n",
  1547. gnutls_strerror(ret));
  1548. exit(1);
  1549. }
  1550. } else {
  1551. read_crq_set(crq, "Locality name: ",
  1552. GNUTLS_OID_X520_LOCALITY_NAME);
  1553. }
  1554. }
  1555. void get_dn_crq_set(gnutls_x509_crq_t crq)
  1556. {
  1557. int ret;
  1558. const char *err;
  1559. if (batch) {
  1560. if (!cfg.dn)
  1561. return;
  1562. ret = gnutls_x509_crq_set_dn(crq, cfg.dn, &err);
  1563. if (ret < 0) {
  1564. fprintf(stderr, "set_dn: %s at: %s\n",
  1565. gnutls_strerror(ret), err);
  1566. exit(1);
  1567. }
  1568. }
  1569. }
  1570. void get_cn_crq_set(gnutls_x509_crq_t crq)
  1571. {
  1572. int ret;
  1573. if (batch) {
  1574. if (!cfg.cn)
  1575. return;
  1576. ret =
  1577. gnutls_x509_crq_set_dn_by_oid(crq,
  1578. GNUTLS_OID_X520_COMMON_NAME,
  1579. 0, cfg.cn,
  1580. strlen(cfg.cn));
  1581. if (ret < 0) {
  1582. fprintf(stderr, "set_dn: %s\n",
  1583. gnutls_strerror(ret));
  1584. exit(1);
  1585. }
  1586. } else {
  1587. read_crq_set(crq, "Common name: ",
  1588. GNUTLS_OID_X520_COMMON_NAME);
  1589. }
  1590. }
  1591. void get_uid_crq_set(gnutls_x509_crq_t crq)
  1592. {
  1593. int ret;
  1594. if (batch) {
  1595. if (!cfg.uid)
  1596. return;
  1597. ret =
  1598. gnutls_x509_crq_set_dn_by_oid(crq, GNUTLS_OID_LDAP_UID,
  1599. 0, cfg.uid,
  1600. strlen(cfg.uid));
  1601. if (ret < 0) {
  1602. fprintf(stderr, "set_dn: %s\n",
  1603. gnutls_strerror(ret));
  1604. exit(1);
  1605. }
  1606. } else {
  1607. read_crq_set(crq, "UID: ", GNUTLS_OID_LDAP_UID);
  1608. }
  1609. }
  1610. void get_oid_crq_set(gnutls_x509_crq_t crq)
  1611. {
  1612. int ret, i;
  1613. if (batch) {
  1614. if (!cfg.dn_oid)
  1615. return;
  1616. for (i = 0; cfg.dn_oid[i] != NULL; i += 2) {
  1617. if (cfg.dn_oid[i + 1] == NULL) {
  1618. fprintf(stderr,
  1619. "dn_oid: %s does not have an argument.\n",
  1620. cfg.dn_oid[i]);
  1621. exit(1);
  1622. }
  1623. ret =
  1624. gnutls_x509_crq_set_dn_by_oid(crq,
  1625. cfg.dn_oid[i], 0,
  1626. cfg.dn_oid[i +
  1627. 1],
  1628. strlen(cfg.
  1629. dn_oid[i +
  1630. 1]));
  1631. if (ret < 0) {
  1632. fprintf(stderr, "set_dn_oid: %s\n",
  1633. gnutls_strerror(ret));
  1634. exit(1);
  1635. }
  1636. }
  1637. }
  1638. }