x509.c 32 KB

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