x509.c 41 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201
  1. /* apps/x509.c */
  2. /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
  3. * All rights reserved.
  4. *
  5. * This package is an SSL implementation written
  6. * by Eric Young (eay@cryptsoft.com).
  7. * The implementation was written so as to conform with Netscapes SSL.
  8. *
  9. * This library is free for commercial and non-commercial use as long as
  10. * the following conditions are aheared to. The following conditions
  11. * apply to all code found in this distribution, be it the RC4, RSA,
  12. * lhash, DES, etc., code; not just the SSL code. The SSL documentation
  13. * included with this distribution is covered by the same copyright terms
  14. * except that the holder is Tim Hudson (tjh@cryptsoft.com).
  15. *
  16. * Copyright remains Eric Young's, and as such any Copyright notices in
  17. * the code are not to be removed.
  18. * If this package is used in a product, Eric Young should be given attribution
  19. * as the author of the parts of the library used.
  20. * This can be in the form of a textual message at program startup or
  21. * in documentation (online or textual) provided with the package.
  22. *
  23. * Redistribution and use in source and binary forms, with or without
  24. * modification, are permitted provided that the following conditions
  25. * are met:
  26. * 1. Redistributions of source code must retain the copyright
  27. * notice, this list of conditions and the following disclaimer.
  28. * 2. Redistributions in binary form must reproduce the above copyright
  29. * notice, this list of conditions and the following disclaimer in the
  30. * documentation and/or other materials provided with the distribution.
  31. * 3. All advertising materials mentioning features or use of this software
  32. * must display the following acknowledgement:
  33. * "This product includes cryptographic software written by
  34. * Eric Young (eay@cryptsoft.com)"
  35. * The word 'cryptographic' can be left out if the rouines from the library
  36. * being used are not cryptographic related :-).
  37. * 4. If you include any Windows specific code (or a derivative thereof) from
  38. * the apps directory (application code) you must include an acknowledgement:
  39. * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
  40. *
  41. * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
  42. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  43. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  44. * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
  45. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  46. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  47. * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  48. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  49. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  50. * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  51. * SUCH DAMAGE.
  52. *
  53. * The licence and distribution terms for any publically available version or
  54. * derivative of this code cannot be changed. i.e. this code cannot simply be
  55. * copied and put under another distribution licence
  56. * [including the GNU Public Licence.]
  57. */
  58. #include <assert.h>
  59. #include <stdio.h>
  60. #include <stdlib.h>
  61. #include <string.h>
  62. #ifdef OPENSSL_NO_STDIO
  63. # define APPS_WIN16
  64. #endif
  65. #include "apps.h"
  66. #include <openssl/bio.h>
  67. #include <openssl/asn1.h>
  68. #include <openssl/err.h>
  69. #include <openssl/bn.h>
  70. #include <openssl/evp.h>
  71. #include <openssl/x509.h>
  72. #include <openssl/x509v3.h>
  73. #include <openssl/objects.h>
  74. #include <openssl/pem.h>
  75. #ifndef OPENSSL_NO_RSA
  76. # include <openssl/rsa.h>
  77. #endif
  78. #ifndef OPENSSL_NO_DSA
  79. # include <openssl/dsa.h>
  80. #endif
  81. #undef PROG
  82. #define PROG x509_main
  83. #undef POSTFIX
  84. #define POSTFIX ".srl"
  85. #define DEF_DAYS 30
  86. static const char *x509_usage[] = {
  87. "usage: x509 args\n",
  88. " -inform arg - input format - default PEM (one of DER, NET or PEM)\n",
  89. " -outform arg - output format - default PEM (one of DER, NET or PEM)\n",
  90. " -keyform arg - private key format - default PEM\n",
  91. " -CAform arg - CA format - default PEM\n",
  92. " -CAkeyform arg - CA key format - default PEM\n",
  93. " -in arg - input file - default stdin\n",
  94. " -out arg - output file - default stdout\n",
  95. " -passin arg - private key password source\n",
  96. " -serial - print serial number value\n",
  97. " -subject_hash - print subject hash value\n",
  98. #ifndef OPENSSL_NO_MD5
  99. " -subject_hash_old - print old-style (MD5) subject hash value\n",
  100. #endif
  101. " -issuer_hash - print issuer hash value\n",
  102. #ifndef OPENSSL_NO_MD5
  103. " -issuer_hash_old - print old-style (MD5) issuer hash value\n",
  104. #endif
  105. " -hash - synonym for -subject_hash\n",
  106. " -subject - print subject DN\n",
  107. " -issuer - print issuer DN\n",
  108. " -email - print email address(es)\n",
  109. " -startdate - notBefore field\n",
  110. " -enddate - notAfter field\n",
  111. " -purpose - print out certificate purposes\n",
  112. " -dates - both Before and After dates\n",
  113. " -modulus - print the RSA key modulus\n",
  114. " -pubkey - output the public key\n",
  115. " -fingerprint - print the certificate fingerprint\n",
  116. " -alias - output certificate alias\n",
  117. " -noout - no certificate output\n",
  118. " -ocspid - print OCSP hash values for the subject name and public key\n",
  119. " -ocsp_uri - print OCSP Responder URL(s)\n",
  120. " -trustout - output a \"trusted\" certificate\n",
  121. " -clrtrust - clear all trusted purposes\n",
  122. " -clrreject - clear all rejected purposes\n",
  123. " -addtrust arg - trust certificate for a given purpose\n",
  124. " -addreject arg - reject certificate for a given purpose\n",
  125. " -setalias arg - set certificate alias\n",
  126. " -days arg - How long till expiry of a signed certificate - def 30 days\n",
  127. " -checkend arg - check whether the cert expires in the next arg seconds\n",
  128. " exit 1 if so, 0 if not\n",
  129. " -signkey arg - self sign cert with arg\n",
  130. " -x509toreq - output a certification request object\n",
  131. " -req - input is a certificate request, sign and output.\n",
  132. " -CA arg - set the CA certificate, must be PEM format.\n",
  133. " -CAkey arg - set the CA key, must be PEM format\n",
  134. " missing, it is assumed to be in the CA file.\n",
  135. " -CAcreateserial - create serial number file if it does not exist\n",
  136. " -CAserial arg - serial file\n",
  137. " -set_serial - serial number to use\n",
  138. " -text - print the certificate in text form\n",
  139. " -C - print out C code forms\n",
  140. " -md2/-md5/-sha1/-mdc2 - digest to use\n",
  141. " -extfile - configuration file with X509V3 extensions to add\n",
  142. " -extensions - section from config file with X509V3 extensions to add\n",
  143. " -clrext - delete extensions before signing and input certificate\n",
  144. " -nameopt arg - various certificate name options\n",
  145. #ifndef OPENSSL_NO_ENGINE
  146. " -engine e - use engine e, possibly a hardware device.\n",
  147. #endif
  148. " -certopt arg - various certificate text options\n",
  149. NULL
  150. };
  151. static int MS_CALLBACK callb(int ok, X509_STORE_CTX *ctx);
  152. static int sign(X509 *x, EVP_PKEY *pkey, int days, int clrext,
  153. const EVP_MD *digest, CONF *conf, char *section);
  154. static int x509_certify(X509_STORE *ctx, char *CAfile, const EVP_MD *digest,
  155. X509 *x, X509 *xca, EVP_PKEY *pkey, char *serial,
  156. int create, int days, int clrext, CONF *conf,
  157. char *section, ASN1_INTEGER *sno);
  158. static int purpose_print(BIO *bio, X509 *cert, X509_PURPOSE *pt);
  159. static int reqfile = 0;
  160. int MAIN(int, char **);
  161. int MAIN(int argc, char **argv)
  162. {
  163. ENGINE *e = NULL;
  164. int ret = 1;
  165. X509_REQ *req = NULL;
  166. X509 *x = NULL, *xca = NULL;
  167. ASN1_OBJECT *objtmp;
  168. EVP_PKEY *Upkey = NULL, *CApkey = NULL;
  169. ASN1_INTEGER *sno = NULL;
  170. int i, num, badops = 0;
  171. BIO *out = NULL;
  172. BIO *STDout = NULL;
  173. STACK_OF(ASN1_OBJECT) *trust = NULL, *reject = NULL;
  174. int informat, outformat, keyformat, CAformat, CAkeyformat;
  175. char *infile = NULL, *outfile = NULL, *keyfile = NULL, *CAfile = NULL;
  176. char *CAkeyfile = NULL, *CAserial = NULL;
  177. char *alias = NULL;
  178. int text = 0, serial = 0, subject = 0, issuer = 0, startdate =
  179. 0, enddate = 0;
  180. int next_serial = 0;
  181. int subject_hash = 0, issuer_hash = 0, ocspid = 0;
  182. #ifndef OPENSSL_NO_MD5
  183. int subject_hash_old = 0, issuer_hash_old = 0;
  184. #endif
  185. int noout = 0, sign_flag = 0, CA_flag = 0, CA_createserial = 0, email = 0;
  186. int ocsp_uri = 0;
  187. int trustout = 0, clrtrust = 0, clrreject = 0, aliasout = 0, clrext = 0;
  188. int C = 0;
  189. int x509req = 0, days = DEF_DAYS, modulus = 0, pubkey = 0;
  190. int pprint = 0;
  191. const char **pp;
  192. X509_STORE *ctx = NULL;
  193. X509_REQ *rq = NULL;
  194. int fingerprint = 0;
  195. char buf[256];
  196. const EVP_MD *md_alg, *digest = NULL;
  197. CONF *extconf = NULL;
  198. char *extsect = NULL, *extfile = NULL, *passin = NULL, *passargin = NULL;
  199. int need_rand = 0;
  200. int checkend = 0, checkoffset = 0;
  201. unsigned long nmflag = 0, certflag = 0;
  202. #ifndef OPENSSL_NO_ENGINE
  203. char *engine = NULL;
  204. #endif
  205. reqfile = 0;
  206. apps_startup();
  207. if (bio_err == NULL)
  208. bio_err = BIO_new_fp(stderr, BIO_NOCLOSE);
  209. if (!load_config(bio_err, NULL))
  210. goto end;
  211. STDout = BIO_new_fp(stdout, BIO_NOCLOSE);
  212. #ifdef OPENSSL_SYS_VMS
  213. {
  214. BIO *tmpbio = BIO_new(BIO_f_linebuffer());
  215. STDout = BIO_push(tmpbio, STDout);
  216. }
  217. #endif
  218. informat = FORMAT_PEM;
  219. outformat = FORMAT_PEM;
  220. keyformat = FORMAT_PEM;
  221. CAformat = FORMAT_PEM;
  222. CAkeyformat = FORMAT_PEM;
  223. ctx = X509_STORE_new();
  224. if (ctx == NULL)
  225. goto end;
  226. X509_STORE_set_verify_cb(ctx, callb);
  227. argc--;
  228. argv++;
  229. num = 0;
  230. while (argc >= 1) {
  231. if (strcmp(*argv, "-inform") == 0) {
  232. if (--argc < 1)
  233. goto bad;
  234. informat = str2fmt(*(++argv));
  235. } else if (strcmp(*argv, "-outform") == 0) {
  236. if (--argc < 1)
  237. goto bad;
  238. outformat = str2fmt(*(++argv));
  239. } else if (strcmp(*argv, "-keyform") == 0) {
  240. if (--argc < 1)
  241. goto bad;
  242. keyformat = str2fmt(*(++argv));
  243. } else if (strcmp(*argv, "-req") == 0) {
  244. reqfile = 1;
  245. need_rand = 1;
  246. } else if (strcmp(*argv, "-CAform") == 0) {
  247. if (--argc < 1)
  248. goto bad;
  249. CAformat = str2fmt(*(++argv));
  250. } else if (strcmp(*argv, "-CAkeyform") == 0) {
  251. if (--argc < 1)
  252. goto bad;
  253. CAkeyformat = str2fmt(*(++argv));
  254. } else if (strcmp(*argv, "-days") == 0) {
  255. if (--argc < 1)
  256. goto bad;
  257. days = atoi(*(++argv));
  258. if (days == 0) {
  259. BIO_printf(STDout, "bad number of days\n");
  260. goto bad;
  261. }
  262. } else if (strcmp(*argv, "-passin") == 0) {
  263. if (--argc < 1)
  264. goto bad;
  265. passargin = *(++argv);
  266. } else if (strcmp(*argv, "-extfile") == 0) {
  267. if (--argc < 1)
  268. goto bad;
  269. extfile = *(++argv);
  270. } else if (strcmp(*argv, "-extensions") == 0) {
  271. if (--argc < 1)
  272. goto bad;
  273. extsect = *(++argv);
  274. } else if (strcmp(*argv, "-in") == 0) {
  275. if (--argc < 1)
  276. goto bad;
  277. infile = *(++argv);
  278. } else if (strcmp(*argv, "-out") == 0) {
  279. if (--argc < 1)
  280. goto bad;
  281. outfile = *(++argv);
  282. } else if (strcmp(*argv, "-signkey") == 0) {
  283. if (--argc < 1)
  284. goto bad;
  285. keyfile = *(++argv);
  286. sign_flag = ++num;
  287. need_rand = 1;
  288. } else if (strcmp(*argv, "-CA") == 0) {
  289. if (--argc < 1)
  290. goto bad;
  291. CAfile = *(++argv);
  292. CA_flag = ++num;
  293. need_rand = 1;
  294. } else if (strcmp(*argv, "-CAkey") == 0) {
  295. if (--argc < 1)
  296. goto bad;
  297. CAkeyfile = *(++argv);
  298. } else if (strcmp(*argv, "-CAserial") == 0) {
  299. if (--argc < 1)
  300. goto bad;
  301. CAserial = *(++argv);
  302. } else if (strcmp(*argv, "-set_serial") == 0) {
  303. if (--argc < 1)
  304. goto bad;
  305. if (!(sno = s2i_ASN1_INTEGER(NULL, *(++argv))))
  306. goto bad;
  307. } else if (strcmp(*argv, "-addtrust") == 0) {
  308. if (--argc < 1)
  309. goto bad;
  310. if (!(objtmp = OBJ_txt2obj(*(++argv), 0))) {
  311. BIO_printf(bio_err, "Invalid trust object value %s\n", *argv);
  312. goto bad;
  313. }
  314. if (!trust)
  315. trust = sk_ASN1_OBJECT_new_null();
  316. sk_ASN1_OBJECT_push(trust, objtmp);
  317. trustout = 1;
  318. } else if (strcmp(*argv, "-addreject") == 0) {
  319. if (--argc < 1)
  320. goto bad;
  321. if (!(objtmp = OBJ_txt2obj(*(++argv), 0))) {
  322. BIO_printf(bio_err,
  323. "Invalid reject object value %s\n", *argv);
  324. goto bad;
  325. }
  326. if (!reject)
  327. reject = sk_ASN1_OBJECT_new_null();
  328. sk_ASN1_OBJECT_push(reject, objtmp);
  329. trustout = 1;
  330. } else if (strcmp(*argv, "-setalias") == 0) {
  331. if (--argc < 1)
  332. goto bad;
  333. alias = *(++argv);
  334. trustout = 1;
  335. } else if (strcmp(*argv, "-certopt") == 0) {
  336. if (--argc < 1)
  337. goto bad;
  338. if (!set_cert_ex(&certflag, *(++argv)))
  339. goto bad;
  340. } else if (strcmp(*argv, "-nameopt") == 0) {
  341. if (--argc < 1)
  342. goto bad;
  343. if (!set_name_ex(&nmflag, *(++argv)))
  344. goto bad;
  345. }
  346. #ifndef OPENSSL_NO_ENGINE
  347. else if (strcmp(*argv, "-engine") == 0) {
  348. if (--argc < 1)
  349. goto bad;
  350. engine = *(++argv);
  351. }
  352. #endif
  353. else if (strcmp(*argv, "-C") == 0)
  354. C = ++num;
  355. else if (strcmp(*argv, "-email") == 0)
  356. email = ++num;
  357. else if (strcmp(*argv, "-ocsp_uri") == 0)
  358. ocsp_uri = ++num;
  359. else if (strcmp(*argv, "-serial") == 0)
  360. serial = ++num;
  361. else if (strcmp(*argv, "-next_serial") == 0)
  362. next_serial = ++num;
  363. else if (strcmp(*argv, "-modulus") == 0)
  364. modulus = ++num;
  365. else if (strcmp(*argv, "-pubkey") == 0)
  366. pubkey = ++num;
  367. else if (strcmp(*argv, "-x509toreq") == 0)
  368. x509req = ++num;
  369. else if (strcmp(*argv, "-text") == 0)
  370. text = ++num;
  371. else if (strcmp(*argv, "-hash") == 0
  372. || strcmp(*argv, "-subject_hash") == 0)
  373. subject_hash = ++num;
  374. #ifndef OPENSSL_NO_MD5
  375. else if (strcmp(*argv, "-subject_hash_old") == 0)
  376. subject_hash_old = ++num;
  377. #endif
  378. else if (strcmp(*argv, "-issuer_hash") == 0)
  379. issuer_hash = ++num;
  380. #ifndef OPENSSL_NO_MD5
  381. else if (strcmp(*argv, "-issuer_hash_old") == 0)
  382. issuer_hash_old = ++num;
  383. #endif
  384. else if (strcmp(*argv, "-subject") == 0)
  385. subject = ++num;
  386. else if (strcmp(*argv, "-issuer") == 0)
  387. issuer = ++num;
  388. else if (strcmp(*argv, "-fingerprint") == 0)
  389. fingerprint = ++num;
  390. else if (strcmp(*argv, "-dates") == 0) {
  391. startdate = ++num;
  392. enddate = ++num;
  393. } else if (strcmp(*argv, "-purpose") == 0)
  394. pprint = ++num;
  395. else if (strcmp(*argv, "-startdate") == 0)
  396. startdate = ++num;
  397. else if (strcmp(*argv, "-enddate") == 0)
  398. enddate = ++num;
  399. else if (strcmp(*argv, "-checkend") == 0) {
  400. if (--argc < 1)
  401. goto bad;
  402. checkoffset = atoi(*(++argv));
  403. checkend = 1;
  404. } else if (strcmp(*argv, "-noout") == 0)
  405. noout = ++num;
  406. else if (strcmp(*argv, "-trustout") == 0)
  407. trustout = 1;
  408. else if (strcmp(*argv, "-clrtrust") == 0)
  409. clrtrust = ++num;
  410. else if (strcmp(*argv, "-clrreject") == 0)
  411. clrreject = ++num;
  412. else if (strcmp(*argv, "-alias") == 0)
  413. aliasout = ++num;
  414. else if (strcmp(*argv, "-CAcreateserial") == 0)
  415. CA_createserial = ++num;
  416. else if (strcmp(*argv, "-clrext") == 0)
  417. clrext = 1;
  418. #if 1 /* stay backwards-compatible with 0.9.5; this
  419. * should go away soon */
  420. else if (strcmp(*argv, "-crlext") == 0) {
  421. BIO_printf(bio_err, "use -clrext instead of -crlext\n");
  422. clrext = 1;
  423. }
  424. #endif
  425. else if (strcmp(*argv, "-ocspid") == 0)
  426. ocspid = ++num;
  427. else if ((md_alg = EVP_get_digestbyname(*argv + 1))) {
  428. /* ok */
  429. digest = md_alg;
  430. } else {
  431. BIO_printf(bio_err, "unknown option %s\n", *argv);
  432. badops = 1;
  433. break;
  434. }
  435. argc--;
  436. argv++;
  437. }
  438. if (badops) {
  439. bad:
  440. for (pp = x509_usage; (*pp != NULL); pp++)
  441. BIO_printf(bio_err, "%s", *pp);
  442. goto end;
  443. }
  444. #ifndef OPENSSL_NO_ENGINE
  445. e = setup_engine(bio_err, engine, 0);
  446. #endif
  447. if (need_rand)
  448. app_RAND_load_file(NULL, bio_err, 0);
  449. ERR_load_crypto_strings();
  450. if (!app_passwd(bio_err, passargin, NULL, &passin, NULL)) {
  451. BIO_printf(bio_err, "Error getting password\n");
  452. goto end;
  453. }
  454. if (!X509_STORE_set_default_paths(ctx)) {
  455. ERR_print_errors(bio_err);
  456. goto end;
  457. }
  458. if ((CAkeyfile == NULL) && (CA_flag) && (CAformat == FORMAT_PEM)) {
  459. CAkeyfile = CAfile;
  460. } else if ((CA_flag) && (CAkeyfile == NULL)) {
  461. BIO_printf(bio_err,
  462. "need to specify a CAkey if using the CA command\n");
  463. goto end;
  464. }
  465. if (extfile) {
  466. long errorline = -1;
  467. X509V3_CTX ctx2;
  468. extconf = NCONF_new(NULL);
  469. if (!NCONF_load(extconf, extfile, &errorline)) {
  470. if (errorline <= 0)
  471. BIO_printf(bio_err,
  472. "error loading the config file '%s'\n", extfile);
  473. else
  474. BIO_printf(bio_err,
  475. "error on line %ld of config file '%s'\n",
  476. errorline, extfile);
  477. goto end;
  478. }
  479. if (!extsect) {
  480. extsect = NCONF_get_string(extconf, "default", "extensions");
  481. if (!extsect) {
  482. ERR_clear_error();
  483. extsect = "default";
  484. }
  485. }
  486. X509V3_set_ctx_test(&ctx2);
  487. X509V3_set_nconf(&ctx2, extconf);
  488. if (!X509V3_EXT_add_nconf(extconf, &ctx2, extsect, NULL)) {
  489. BIO_printf(bio_err,
  490. "Error Loading extension section %s\n", extsect);
  491. ERR_print_errors(bio_err);
  492. goto end;
  493. }
  494. }
  495. if (reqfile) {
  496. EVP_PKEY *pkey;
  497. BIO *in;
  498. if (!sign_flag && !CA_flag) {
  499. BIO_printf(bio_err, "We need a private key to sign with\n");
  500. goto end;
  501. }
  502. in = BIO_new(BIO_s_file());
  503. if (in == NULL) {
  504. ERR_print_errors(bio_err);
  505. goto end;
  506. }
  507. if (infile == NULL)
  508. BIO_set_fp(in, stdin, BIO_NOCLOSE | BIO_FP_TEXT);
  509. else {
  510. if (BIO_read_filename(in, infile) <= 0) {
  511. perror(infile);
  512. BIO_free(in);
  513. goto end;
  514. }
  515. }
  516. req = PEM_read_bio_X509_REQ(in, NULL, NULL, NULL);
  517. BIO_free(in);
  518. if (req == NULL) {
  519. ERR_print_errors(bio_err);
  520. goto end;
  521. }
  522. if ((req->req_info == NULL) ||
  523. (req->req_info->pubkey == NULL) ||
  524. (req->req_info->pubkey->public_key == NULL) ||
  525. (req->req_info->pubkey->public_key->data == NULL)) {
  526. BIO_printf(bio_err,
  527. "The certificate request appears to corrupted\n");
  528. BIO_printf(bio_err, "It does not contain a public key\n");
  529. goto end;
  530. }
  531. if ((pkey = X509_REQ_get_pubkey(req)) == NULL) {
  532. BIO_printf(bio_err, "error unpacking public key\n");
  533. goto end;
  534. }
  535. i = X509_REQ_verify(req, pkey);
  536. EVP_PKEY_free(pkey);
  537. if (i < 0) {
  538. BIO_printf(bio_err, "Signature verification error\n");
  539. ERR_print_errors(bio_err);
  540. goto end;
  541. }
  542. if (i == 0) {
  543. BIO_printf(bio_err,
  544. "Signature did not match the certificate request\n");
  545. goto end;
  546. } else
  547. BIO_printf(bio_err, "Signature ok\n");
  548. print_name(bio_err, "subject=", X509_REQ_get_subject_name(req),
  549. nmflag);
  550. if ((x = X509_new()) == NULL)
  551. goto end;
  552. if (sno == NULL) {
  553. sno = ASN1_INTEGER_new();
  554. if (!sno || !rand_serial(NULL, sno))
  555. goto end;
  556. if (!X509_set_serialNumber(x, sno))
  557. goto end;
  558. ASN1_INTEGER_free(sno);
  559. sno = NULL;
  560. } else if (!X509_set_serialNumber(x, sno))
  561. goto end;
  562. if (!X509_set_issuer_name(x, req->req_info->subject))
  563. goto end;
  564. if (!X509_set_subject_name(x, req->req_info->subject))
  565. goto end;
  566. X509_gmtime_adj(X509_get_notBefore(x), 0);
  567. X509_time_adj_ex(X509_get_notAfter(x), days, 0, NULL);
  568. pkey = X509_REQ_get_pubkey(req);
  569. X509_set_pubkey(x, pkey);
  570. EVP_PKEY_free(pkey);
  571. } else
  572. x = load_cert(bio_err, infile, informat, NULL, e, "Certificate");
  573. if (x == NULL)
  574. goto end;
  575. if (CA_flag) {
  576. xca = load_cert(bio_err, CAfile, CAformat, NULL, e, "CA Certificate");
  577. if (xca == NULL)
  578. goto end;
  579. }
  580. if (!noout || text || next_serial) {
  581. OBJ_create("2.99999.3", "SET.ex3", "SET x509v3 extension 3");
  582. out = BIO_new(BIO_s_file());
  583. if (out == NULL) {
  584. ERR_print_errors(bio_err);
  585. goto end;
  586. }
  587. if (outfile == NULL) {
  588. BIO_set_fp(out, stdout, BIO_NOCLOSE);
  589. #ifdef OPENSSL_SYS_VMS
  590. {
  591. BIO *tmpbio = BIO_new(BIO_f_linebuffer());
  592. out = BIO_push(tmpbio, out);
  593. }
  594. #endif
  595. } else {
  596. if (BIO_write_filename(out, outfile) <= 0) {
  597. perror(outfile);
  598. goto end;
  599. }
  600. }
  601. }
  602. if (alias)
  603. X509_alias_set1(x, (unsigned char *)alias, -1);
  604. if (clrtrust)
  605. X509_trust_clear(x);
  606. if (clrreject)
  607. X509_reject_clear(x);
  608. if (trust) {
  609. for (i = 0; i < sk_ASN1_OBJECT_num(trust); i++) {
  610. objtmp = sk_ASN1_OBJECT_value(trust, i);
  611. X509_add1_trust_object(x, objtmp);
  612. }
  613. }
  614. if (reject) {
  615. for (i = 0; i < sk_ASN1_OBJECT_num(reject); i++) {
  616. objtmp = sk_ASN1_OBJECT_value(reject, i);
  617. X509_add1_reject_object(x, objtmp);
  618. }
  619. }
  620. if (num) {
  621. for (i = 1; i <= num; i++) {
  622. if (issuer == i) {
  623. print_name(STDout, "issuer= ",
  624. X509_get_issuer_name(x), nmflag);
  625. } else if (subject == i) {
  626. print_name(STDout, "subject= ",
  627. X509_get_subject_name(x), nmflag);
  628. } else if (serial == i) {
  629. BIO_printf(STDout, "serial=");
  630. i2a_ASN1_INTEGER(STDout, X509_get_serialNumber(x));
  631. BIO_printf(STDout, "\n");
  632. } else if (next_serial == i) {
  633. BIGNUM *bnser;
  634. ASN1_INTEGER *ser;
  635. ser = X509_get_serialNumber(x);
  636. bnser = ASN1_INTEGER_to_BN(ser, NULL);
  637. if (!bnser)
  638. goto end;
  639. if (!BN_add_word(bnser, 1))
  640. goto end;
  641. ser = BN_to_ASN1_INTEGER(bnser, NULL);
  642. if (!ser)
  643. goto end;
  644. BN_free(bnser);
  645. i2a_ASN1_INTEGER(out, ser);
  646. ASN1_INTEGER_free(ser);
  647. BIO_puts(out, "\n");
  648. } else if ((email == i) || (ocsp_uri == i)) {
  649. int j;
  650. STACK_OF(OPENSSL_STRING) *emlst;
  651. if (email == i)
  652. emlst = X509_get1_email(x);
  653. else
  654. emlst = X509_get1_ocsp(x);
  655. for (j = 0; j < sk_OPENSSL_STRING_num(emlst); j++)
  656. BIO_printf(STDout, "%s\n",
  657. sk_OPENSSL_STRING_value(emlst, j));
  658. X509_email_free(emlst);
  659. } else if (aliasout == i) {
  660. unsigned char *alstr;
  661. alstr = X509_alias_get0(x, NULL);
  662. if (alstr)
  663. BIO_printf(STDout, "%s\n", alstr);
  664. else
  665. BIO_puts(STDout, "<No Alias>\n");
  666. } else if (subject_hash == i) {
  667. BIO_printf(STDout, "%08lx\n", X509_subject_name_hash(x));
  668. }
  669. #ifndef OPENSSL_NO_MD5
  670. else if (subject_hash_old == i) {
  671. BIO_printf(STDout, "%08lx\n", X509_subject_name_hash_old(x));
  672. }
  673. #endif
  674. else if (issuer_hash == i) {
  675. BIO_printf(STDout, "%08lx\n", X509_issuer_name_hash(x));
  676. }
  677. #ifndef OPENSSL_NO_MD5
  678. else if (issuer_hash_old == i) {
  679. BIO_printf(STDout, "%08lx\n", X509_issuer_name_hash_old(x));
  680. }
  681. #endif
  682. else if (pprint == i) {
  683. X509_PURPOSE *ptmp;
  684. int j;
  685. BIO_printf(STDout, "Certificate purposes:\n");
  686. for (j = 0; j < X509_PURPOSE_get_count(); j++) {
  687. ptmp = X509_PURPOSE_get0(j);
  688. purpose_print(STDout, x, ptmp);
  689. }
  690. } else if (modulus == i) {
  691. EVP_PKEY *pkey;
  692. pkey = X509_get_pubkey(x);
  693. if (pkey == NULL) {
  694. BIO_printf(bio_err, "Modulus=unavailable\n");
  695. ERR_print_errors(bio_err);
  696. goto end;
  697. }
  698. BIO_printf(STDout, "Modulus=");
  699. #ifndef OPENSSL_NO_RSA
  700. if (pkey->type == EVP_PKEY_RSA)
  701. BN_print(STDout, pkey->pkey.rsa->n);
  702. else
  703. #endif
  704. #ifndef OPENSSL_NO_DSA
  705. if (pkey->type == EVP_PKEY_DSA)
  706. BN_print(STDout, pkey->pkey.dsa->pub_key);
  707. else
  708. #endif
  709. BIO_printf(STDout, "Wrong Algorithm type");
  710. BIO_printf(STDout, "\n");
  711. EVP_PKEY_free(pkey);
  712. } else if (pubkey == i) {
  713. EVP_PKEY *pkey;
  714. pkey = X509_get_pubkey(x);
  715. if (pkey == NULL) {
  716. BIO_printf(bio_err, "Error getting public key\n");
  717. ERR_print_errors(bio_err);
  718. goto end;
  719. }
  720. PEM_write_bio_PUBKEY(STDout, pkey);
  721. EVP_PKEY_free(pkey);
  722. } else if (C == i) {
  723. unsigned char *d;
  724. char *m;
  725. int y, z;
  726. X509_NAME_oneline(X509_get_subject_name(x), buf, sizeof buf);
  727. BIO_printf(STDout, "/* subject:%s */\n", buf);
  728. m = X509_NAME_oneline(X509_get_issuer_name(x), buf,
  729. sizeof buf);
  730. BIO_printf(STDout, "/* issuer :%s */\n", buf);
  731. z = i2d_X509(x, NULL);
  732. m = OPENSSL_malloc(z);
  733. d = (unsigned char *)m;
  734. z = i2d_X509_NAME(X509_get_subject_name(x), &d);
  735. BIO_printf(STDout, "unsigned char XXX_subject_name[%d]={\n",
  736. z);
  737. d = (unsigned char *)m;
  738. for (y = 0; y < z; y++) {
  739. BIO_printf(STDout, "0x%02X,", d[y]);
  740. if ((y & 0x0f) == 0x0f)
  741. BIO_printf(STDout, "\n");
  742. }
  743. if (y % 16 != 0)
  744. BIO_printf(STDout, "\n");
  745. BIO_printf(STDout, "};\n");
  746. z = i2d_X509_PUBKEY(X509_get_X509_PUBKEY(x), &d);
  747. BIO_printf(STDout, "unsigned char XXX_public_key[%d]={\n", z);
  748. d = (unsigned char *)m;
  749. for (y = 0; y < z; y++) {
  750. BIO_printf(STDout, "0x%02X,", d[y]);
  751. if ((y & 0x0f) == 0x0f)
  752. BIO_printf(STDout, "\n");
  753. }
  754. if (y % 16 != 0)
  755. BIO_printf(STDout, "\n");
  756. BIO_printf(STDout, "};\n");
  757. z = i2d_X509(x, &d);
  758. BIO_printf(STDout, "unsigned char XXX_certificate[%d]={\n",
  759. z);
  760. d = (unsigned char *)m;
  761. for (y = 0; y < z; y++) {
  762. BIO_printf(STDout, "0x%02X,", d[y]);
  763. if ((y & 0x0f) == 0x0f)
  764. BIO_printf(STDout, "\n");
  765. }
  766. if (y % 16 != 0)
  767. BIO_printf(STDout, "\n");
  768. BIO_printf(STDout, "};\n");
  769. OPENSSL_free(m);
  770. } else if (text == i) {
  771. X509_print_ex(out, x, nmflag, certflag);
  772. } else if (startdate == i) {
  773. BIO_puts(STDout, "notBefore=");
  774. ASN1_TIME_print(STDout, X509_get_notBefore(x));
  775. BIO_puts(STDout, "\n");
  776. } else if (enddate == i) {
  777. BIO_puts(STDout, "notAfter=");
  778. ASN1_TIME_print(STDout, X509_get_notAfter(x));
  779. BIO_puts(STDout, "\n");
  780. } else if (fingerprint == i) {
  781. int j;
  782. unsigned int n;
  783. unsigned char md[EVP_MAX_MD_SIZE];
  784. const EVP_MD *fdig = digest;
  785. if (!fdig)
  786. fdig = EVP_sha1();
  787. if (!X509_digest(x, fdig, md, &n)) {
  788. BIO_printf(bio_err, "out of memory\n");
  789. goto end;
  790. }
  791. BIO_printf(STDout, "%s Fingerprint=",
  792. OBJ_nid2sn(EVP_MD_type(fdig)));
  793. for (j = 0; j < (int)n; j++) {
  794. BIO_printf(STDout, "%02X%c", md[j], (j + 1 == (int)n)
  795. ? '\n' : ':');
  796. }
  797. }
  798. /* should be in the library */
  799. else if ((sign_flag == i) && (x509req == 0)) {
  800. BIO_printf(bio_err, "Getting Private key\n");
  801. if (Upkey == NULL) {
  802. Upkey = load_key(bio_err,
  803. keyfile, keyformat, 0,
  804. passin, e, "Private key");
  805. if (Upkey == NULL)
  806. goto end;
  807. }
  808. assert(need_rand);
  809. if (!sign(x, Upkey, days, clrext, digest, extconf, extsect))
  810. goto end;
  811. } else if (CA_flag == i) {
  812. BIO_printf(bio_err, "Getting CA Private Key\n");
  813. if (CAkeyfile != NULL) {
  814. CApkey = load_key(bio_err,
  815. CAkeyfile, CAkeyformat,
  816. 0, passin, e, "CA Private Key");
  817. if (CApkey == NULL)
  818. goto end;
  819. }
  820. assert(need_rand);
  821. if (!x509_certify(ctx, CAfile, digest, x, xca,
  822. CApkey, CAserial, CA_createserial, days,
  823. clrext, extconf, extsect, sno))
  824. goto end;
  825. } else if (x509req == i) {
  826. EVP_PKEY *pk;
  827. BIO_printf(bio_err, "Getting request Private Key\n");
  828. if (keyfile == NULL) {
  829. BIO_printf(bio_err, "no request key file specified\n");
  830. goto end;
  831. } else {
  832. pk = load_key(bio_err,
  833. keyfile, keyformat, 0,
  834. passin, e, "request key");
  835. if (pk == NULL)
  836. goto end;
  837. }
  838. BIO_printf(bio_err, "Generating certificate request\n");
  839. rq = X509_to_X509_REQ(x, pk, digest);
  840. EVP_PKEY_free(pk);
  841. if (rq == NULL) {
  842. ERR_print_errors(bio_err);
  843. goto end;
  844. }
  845. if (!noout) {
  846. X509_REQ_print(out, rq);
  847. PEM_write_bio_X509_REQ(out, rq);
  848. }
  849. noout = 1;
  850. } else if (ocspid == i) {
  851. X509_ocspid_print(out, x);
  852. }
  853. }
  854. }
  855. if (checkend) {
  856. time_t tcheck = time(NULL) + checkoffset;
  857. if (X509_cmp_time(X509_get_notAfter(x), &tcheck) < 0) {
  858. BIO_printf(out, "Certificate will expire\n");
  859. ret = 1;
  860. } else {
  861. BIO_printf(out, "Certificate will not expire\n");
  862. ret = 0;
  863. }
  864. goto end;
  865. }
  866. if (noout) {
  867. ret = 0;
  868. goto end;
  869. }
  870. if (outformat == FORMAT_ASN1)
  871. i = i2d_X509_bio(out, x);
  872. else if (outformat == FORMAT_PEM) {
  873. if (trustout)
  874. i = PEM_write_bio_X509_AUX(out, x);
  875. else
  876. i = PEM_write_bio_X509(out, x);
  877. } else if (outformat == FORMAT_NETSCAPE) {
  878. NETSCAPE_X509 nx;
  879. ASN1_OCTET_STRING hdr;
  880. hdr.data = (unsigned char *)NETSCAPE_CERT_HDR;
  881. hdr.length = strlen(NETSCAPE_CERT_HDR);
  882. nx.header = &hdr;
  883. nx.cert = x;
  884. i = ASN1_item_i2d_bio(ASN1_ITEM_rptr(NETSCAPE_X509), out, &nx);
  885. } else {
  886. BIO_printf(bio_err, "bad output format specified for outfile\n");
  887. goto end;
  888. }
  889. if (!i) {
  890. BIO_printf(bio_err, "unable to write certificate\n");
  891. ERR_print_errors(bio_err);
  892. goto end;
  893. }
  894. ret = 0;
  895. end:
  896. if (need_rand)
  897. app_RAND_write_file(NULL, bio_err);
  898. OBJ_cleanup();
  899. NCONF_free(extconf);
  900. BIO_free_all(out);
  901. BIO_free_all(STDout);
  902. X509_STORE_free(ctx);
  903. X509_REQ_free(req);
  904. X509_free(x);
  905. X509_free(xca);
  906. EVP_PKEY_free(Upkey);
  907. EVP_PKEY_free(CApkey);
  908. X509_REQ_free(rq);
  909. ASN1_INTEGER_free(sno);
  910. sk_ASN1_OBJECT_pop_free(trust, ASN1_OBJECT_free);
  911. sk_ASN1_OBJECT_pop_free(reject, ASN1_OBJECT_free);
  912. if (passin)
  913. OPENSSL_free(passin);
  914. apps_shutdown();
  915. OPENSSL_EXIT(ret);
  916. }
  917. static ASN1_INTEGER *x509_load_serial(char *CAfile, char *serialfile,
  918. int create)
  919. {
  920. char *buf = NULL, *p;
  921. ASN1_INTEGER *bs = NULL;
  922. BIGNUM *serial = NULL;
  923. size_t len;
  924. len = ((serialfile == NULL)
  925. ? (strlen(CAfile) + strlen(POSTFIX) + 1)
  926. : (strlen(serialfile))) + 1;
  927. buf = OPENSSL_malloc(len);
  928. if (buf == NULL) {
  929. BIO_printf(bio_err, "out of mem\n");
  930. goto end;
  931. }
  932. if (serialfile == NULL) {
  933. BUF_strlcpy(buf, CAfile, len);
  934. for (p = buf; *p; p++)
  935. if (*p == '.') {
  936. *p = '\0';
  937. break;
  938. }
  939. BUF_strlcat(buf, POSTFIX, len);
  940. } else
  941. BUF_strlcpy(buf, serialfile, len);
  942. serial = load_serial(buf, create, NULL);
  943. if (serial == NULL)
  944. goto end;
  945. if (!BN_add_word(serial, 1)) {
  946. BIO_printf(bio_err, "add_word failure\n");
  947. goto end;
  948. }
  949. if (!save_serial(buf, NULL, serial, &bs))
  950. goto end;
  951. end:
  952. if (buf)
  953. OPENSSL_free(buf);
  954. BN_free(serial);
  955. return bs;
  956. }
  957. static int x509_certify(X509_STORE *ctx, char *CAfile, const EVP_MD *digest,
  958. X509 *x, X509 *xca, EVP_PKEY *pkey, char *serialfile,
  959. int create, int days, int clrext, CONF *conf,
  960. char *section, ASN1_INTEGER *sno)
  961. {
  962. int ret = 0;
  963. ASN1_INTEGER *bs = NULL;
  964. X509_STORE_CTX xsc;
  965. EVP_PKEY *upkey;
  966. upkey = X509_get_pubkey(xca);
  967. EVP_PKEY_copy_parameters(upkey, pkey);
  968. EVP_PKEY_free(upkey);
  969. if (!X509_STORE_CTX_init(&xsc, ctx, x, NULL)) {
  970. BIO_printf(bio_err, "Error initialising X509 store\n");
  971. goto end;
  972. }
  973. if (sno)
  974. bs = sno;
  975. else if (!(bs = x509_load_serial(CAfile, serialfile, create)))
  976. goto end;
  977. /* if (!X509_STORE_add_cert(ctx,x)) goto end;*/
  978. /*
  979. * NOTE: this certificate can/should be self signed, unless it was a
  980. * certificate request in which case it is not.
  981. */
  982. X509_STORE_CTX_set_cert(&xsc, x);
  983. X509_STORE_CTX_set_flags(&xsc, X509_V_FLAG_CHECK_SS_SIGNATURE);
  984. if (!reqfile && X509_verify_cert(&xsc) <= 0)
  985. goto end;
  986. if (!X509_check_private_key(xca, pkey)) {
  987. BIO_printf(bio_err,
  988. "CA certificate and CA private key do not match\n");
  989. goto end;
  990. }
  991. if (!X509_set_issuer_name(x, X509_get_subject_name(xca)))
  992. goto end;
  993. if (!X509_set_serialNumber(x, bs))
  994. goto end;
  995. if (X509_gmtime_adj(X509_get_notBefore(x), 0L) == NULL)
  996. goto end;
  997. /* hardwired expired */
  998. if (X509_time_adj_ex(X509_get_notAfter(x), days, 0, NULL) == NULL)
  999. goto end;
  1000. if (clrext) {
  1001. while (X509_get_ext_count(x) > 0)
  1002. X509_delete_ext(x, 0);
  1003. }
  1004. if (conf) {
  1005. X509V3_CTX ctx2;
  1006. X509_set_version(x, 2); /* version 3 certificate */
  1007. X509V3_set_ctx(&ctx2, xca, x, NULL, NULL, 0);
  1008. X509V3_set_nconf(&ctx2, conf);
  1009. if (!X509V3_EXT_add_nconf(conf, &ctx2, section, x))
  1010. goto end;
  1011. }
  1012. if (!X509_sign(x, pkey, digest))
  1013. goto end;
  1014. ret = 1;
  1015. end:
  1016. X509_STORE_CTX_cleanup(&xsc);
  1017. if (!ret)
  1018. ERR_print_errors(bio_err);
  1019. if (!sno)
  1020. ASN1_INTEGER_free(bs);
  1021. return ret;
  1022. }
  1023. static int MS_CALLBACK callb(int ok, X509_STORE_CTX *ctx)
  1024. {
  1025. int err;
  1026. X509 *err_cert;
  1027. /*
  1028. * it is ok to use a self signed certificate This case will catch both
  1029. * the initial ok == 0 and the final ok == 1 calls to this function
  1030. */
  1031. err = X509_STORE_CTX_get_error(ctx);
  1032. if (err == X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT)
  1033. return 1;
  1034. /*
  1035. * BAD we should have gotten an error. Normally if everything worked
  1036. * X509_STORE_CTX_get_error(ctx) will still be set to
  1037. * DEPTH_ZERO_SELF_....
  1038. */
  1039. if (ok) {
  1040. BIO_printf(bio_err,
  1041. "error with certificate to be certified - should be self signed\n");
  1042. return 0;
  1043. } else {
  1044. err_cert = X509_STORE_CTX_get_current_cert(ctx);
  1045. print_name(bio_err, NULL, X509_get_subject_name(err_cert), 0);
  1046. BIO_printf(bio_err,
  1047. "error with certificate - error %d at depth %d\n%s\n", err,
  1048. X509_STORE_CTX_get_error_depth(ctx),
  1049. X509_verify_cert_error_string(err));
  1050. return 1;
  1051. }
  1052. }
  1053. /* self sign */
  1054. static int sign(X509 *x, EVP_PKEY *pkey, int days, int clrext,
  1055. const EVP_MD *digest, CONF *conf, char *section)
  1056. {
  1057. EVP_PKEY *pktmp;
  1058. pktmp = X509_get_pubkey(x);
  1059. EVP_PKEY_copy_parameters(pktmp, pkey);
  1060. EVP_PKEY_save_parameters(pktmp, 1);
  1061. EVP_PKEY_free(pktmp);
  1062. if (!X509_set_issuer_name(x, X509_get_subject_name(x)))
  1063. goto err;
  1064. if (X509_gmtime_adj(X509_get_notBefore(x), 0) == NULL)
  1065. goto err;
  1066. /* Lets just make it 12:00am GMT, Jan 1 1970 */
  1067. /* memcpy(x->cert_info->validity->notBefore,"700101120000Z",13); */
  1068. /* 28 days to be certified */
  1069. if (X509_gmtime_adj(X509_get_notAfter(x), (long)60 * 60 * 24 * days) ==
  1070. NULL)
  1071. goto err;
  1072. if (!X509_set_pubkey(x, pkey))
  1073. goto err;
  1074. if (clrext) {
  1075. while (X509_get_ext_count(x) > 0)
  1076. X509_delete_ext(x, 0);
  1077. }
  1078. if (conf) {
  1079. X509V3_CTX ctx;
  1080. X509_set_version(x, 2); /* version 3 certificate */
  1081. X509V3_set_ctx(&ctx, x, x, NULL, NULL, 0);
  1082. X509V3_set_nconf(&ctx, conf);
  1083. if (!X509V3_EXT_add_nconf(conf, &ctx, section, x))
  1084. goto err;
  1085. }
  1086. if (!X509_sign(x, pkey, digest))
  1087. goto err;
  1088. return 1;
  1089. err:
  1090. ERR_print_errors(bio_err);
  1091. return 0;
  1092. }
  1093. static int purpose_print(BIO *bio, X509 *cert, X509_PURPOSE *pt)
  1094. {
  1095. int id, i, idret;
  1096. char *pname;
  1097. id = X509_PURPOSE_get_id(pt);
  1098. pname = X509_PURPOSE_get0_name(pt);
  1099. for (i = 0; i < 2; i++) {
  1100. idret = X509_check_purpose(cert, id, i);
  1101. BIO_printf(bio, "%s%s : ", pname, i ? " CA" : "");
  1102. if (idret == 1)
  1103. BIO_printf(bio, "Yes\n");
  1104. else if (idret == 0)
  1105. BIO_printf(bio, "No\n");
  1106. else
  1107. BIO_printf(bio, "Yes (WARNING code=%d)\n", idret);
  1108. }
  1109. return 1;
  1110. }