apps.c 60 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690
  1. /* apps/apps.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. /* ====================================================================
  59. * Copyright (c) 1998-2001 The OpenSSL Project. All rights reserved.
  60. *
  61. * Redistribution and use in source and binary forms, with or without
  62. * modification, are permitted provided that the following conditions
  63. * are met:
  64. *
  65. * 1. Redistributions of source code must retain the above copyright
  66. * notice, this list of conditions and the following disclaimer.
  67. *
  68. * 2. Redistributions in binary form must reproduce the above copyright
  69. * notice, this list of conditions and the following disclaimer in
  70. * the documentation and/or other materials provided with the
  71. * distribution.
  72. *
  73. * 3. All advertising materials mentioning features or use of this
  74. * software must display the following acknowledgment:
  75. * "This product includes software developed by the OpenSSL Project
  76. * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
  77. *
  78. * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
  79. * endorse or promote products derived from this software without
  80. * prior written permission. For written permission, please contact
  81. * openssl-core@openssl.org.
  82. *
  83. * 5. Products derived from this software may not be called "OpenSSL"
  84. * nor may "OpenSSL" appear in their names without prior written
  85. * permission of the OpenSSL Project.
  86. *
  87. * 6. Redistributions of any form whatsoever must retain the following
  88. * acknowledgment:
  89. * "This product includes software developed by the OpenSSL Project
  90. * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
  91. *
  92. * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
  93. * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  94. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  95. * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
  96. * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  97. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  98. * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  99. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  100. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  101. * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  102. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
  103. * OF THE POSSIBILITY OF SUCH DAMAGE.
  104. * ====================================================================
  105. *
  106. * This product includes cryptographic software written by Eric Young
  107. * (eay@cryptsoft.com). This product includes software written by Tim
  108. * Hudson (tjh@cryptsoft.com).
  109. *
  110. */
  111. #define _POSIX_C_SOURCE 2 /* On VMS, you need to define this to get
  112. the declaration of fileno(). The value
  113. 2 is to make sure no function defined
  114. in POSIX-2 is left undefined. */
  115. #include <stdio.h>
  116. #include <stdlib.h>
  117. #include <string.h>
  118. #include <sys/types.h>
  119. #include <ctype.h>
  120. #include <errno.h>
  121. #include <openssl/err.h>
  122. #include <openssl/x509.h>
  123. #include <openssl/x509v3.h>
  124. #include <openssl/pem.h>
  125. #include <openssl/pkcs12.h>
  126. #include <openssl/ui.h>
  127. #include <openssl/safestack.h>
  128. #ifndef OPENSSL_NO_ENGINE
  129. #include <openssl/engine.h>
  130. #endif
  131. #ifndef OPENSSL_NO_RSA
  132. #include <openssl/rsa.h>
  133. #endif
  134. #include <openssl/bn.h>
  135. #define NON_MAIN
  136. #include "apps.h"
  137. #undef NON_MAIN
  138. #ifdef _WIN32
  139. static int WIN32_rename(const char *from, const char *to);
  140. #define rename(from,to) WIN32_rename((from),(to))
  141. #endif
  142. typedef struct {
  143. const char *name;
  144. unsigned long flag;
  145. unsigned long mask;
  146. } NAME_EX_TBL;
  147. static UI_METHOD *ui_method = NULL;
  148. static int set_table_opts(unsigned long *flags, const char *arg, const NAME_EX_TBL *in_tbl);
  149. static int set_multi_opts(unsigned long *flags, const char *arg, const NAME_EX_TBL *in_tbl);
  150. #if !defined(OPENSSL_NO_RC4) && !defined(OPENSSL_NO_RSA)
  151. /* Looks like this stuff is worth moving into separate function */
  152. static EVP_PKEY *
  153. load_netscape_key(BIO *err, BIO *key, const char *file,
  154. const char *key_descrip, int format);
  155. #endif
  156. int app_init(long mesgwin);
  157. #ifdef undef /* never finished - probably never will be :-) */
  158. int args_from_file(char *file, int *argc, char **argv[])
  159. {
  160. FILE *fp;
  161. int num,i;
  162. unsigned int len;
  163. static char *buf=NULL;
  164. static char **arg=NULL;
  165. char *p;
  166. fp=fopen(file,"r");
  167. if (fp == NULL)
  168. return(0);
  169. if (fseek(fp,0,SEEK_END)==0)
  170. len=ftell(fp), rewind(fp);
  171. else len=-1;
  172. if (len<=0)
  173. {
  174. fclose(fp);
  175. return(0);
  176. }
  177. *argc=0;
  178. *argv=NULL;
  179. if (buf != NULL) OPENSSL_free(buf);
  180. buf=(char *)OPENSSL_malloc(len+1);
  181. if (buf == NULL) return(0);
  182. len=fread(buf,1,len,fp);
  183. if (len <= 1) return(0);
  184. buf[len]='\0';
  185. i=0;
  186. for (p=buf; *p; p++)
  187. if (*p == '\n') i++;
  188. if (arg != NULL) OPENSSL_free(arg);
  189. arg=(char **)OPENSSL_malloc(sizeof(char *)*(i*2));
  190. *argv=arg;
  191. num=0;
  192. p=buf;
  193. for (;;)
  194. {
  195. if (!*p) break;
  196. if (*p == '#') /* comment line */
  197. {
  198. while (*p && (*p != '\n')) p++;
  199. continue;
  200. }
  201. /* else we have a line */
  202. *(arg++)=p;
  203. num++;
  204. while (*p && ((*p != ' ') && (*p != '\t') && (*p != '\n')))
  205. p++;
  206. if (!*p) break;
  207. if (*p == '\n')
  208. {
  209. *(p++)='\0';
  210. continue;
  211. }
  212. /* else it is a tab or space */
  213. p++;
  214. while (*p && ((*p == ' ') || (*p == '\t') || (*p == '\n')))
  215. p++;
  216. if (!*p) break;
  217. if (*p == '\n')
  218. {
  219. p++;
  220. continue;
  221. }
  222. *(arg++)=p++;
  223. num++;
  224. while (*p && (*p != '\n')) p++;
  225. if (!*p) break;
  226. /* else *p == '\n' */
  227. *(p++)='\0';
  228. }
  229. *argc=num;
  230. return(1);
  231. }
  232. #endif
  233. int str2fmt(char *s)
  234. {
  235. if ((*s == 'D') || (*s == 'd'))
  236. return(FORMAT_ASN1);
  237. else if ((*s == 'T') || (*s == 't'))
  238. return(FORMAT_TEXT);
  239. else if ((*s == 'P') || (*s == 'p'))
  240. {
  241. if (s[1] == 'V' || s[1] == 'v')
  242. return FORMAT_PVK;
  243. else
  244. return(FORMAT_PEM);
  245. }
  246. else if ((*s == 'N') || (*s == 'n'))
  247. return(FORMAT_NETSCAPE);
  248. else if ((*s == 'S') || (*s == 's'))
  249. return(FORMAT_SMIME);
  250. else if ((*s == 'M') || (*s == 'm'))
  251. return(FORMAT_MSBLOB);
  252. else if ((*s == '1')
  253. || (strcmp(s,"PKCS12") == 0) || (strcmp(s,"pkcs12") == 0)
  254. || (strcmp(s,"P12") == 0) || (strcmp(s,"p12") == 0))
  255. return(FORMAT_PKCS12);
  256. else if ((*s == 'E') || (*s == 'e'))
  257. return(FORMAT_ENGINE);
  258. else
  259. return(FORMAT_UNDEF);
  260. }
  261. #if defined(OPENSSL_SYS_MSDOS) || defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_WIN16) || defined(OPENSSL_SYS_NETWARE)
  262. void program_name(char *in, char *out, int size)
  263. {
  264. int i,n;
  265. char *p=NULL;
  266. n=strlen(in);
  267. /* find the last '/', '\' or ':' */
  268. for (i=n-1; i>0; i--)
  269. {
  270. if ((in[i] == '/') || (in[i] == '\\') || (in[i] == ':'))
  271. {
  272. p= &(in[i+1]);
  273. break;
  274. }
  275. }
  276. if (p == NULL)
  277. p=in;
  278. n=strlen(p);
  279. #if defined(OPENSSL_SYS_NETWARE)
  280. /* strip off trailing .nlm if present. */
  281. if ((n > 4) && (p[n-4] == '.') &&
  282. ((p[n-3] == 'n') || (p[n-3] == 'N')) &&
  283. ((p[n-2] == 'l') || (p[n-2] == 'L')) &&
  284. ((p[n-1] == 'm') || (p[n-1] == 'M')))
  285. n-=4;
  286. #else
  287. /* strip off trailing .exe if present. */
  288. if ((n > 4) && (p[n-4] == '.') &&
  289. ((p[n-3] == 'e') || (p[n-3] == 'E')) &&
  290. ((p[n-2] == 'x') || (p[n-2] == 'X')) &&
  291. ((p[n-1] == 'e') || (p[n-1] == 'E')))
  292. n-=4;
  293. #endif
  294. if (n > size-1)
  295. n=size-1;
  296. for (i=0; i<n; i++)
  297. {
  298. if ((p[i] >= 'A') && (p[i] <= 'Z'))
  299. out[i]=p[i]-'A'+'a';
  300. else
  301. out[i]=p[i];
  302. }
  303. out[n]='\0';
  304. }
  305. #else
  306. #ifdef OPENSSL_SYS_VMS
  307. void program_name(char *in, char *out, int size)
  308. {
  309. char *p=in, *q;
  310. char *chars=":]>";
  311. while(*chars != '\0')
  312. {
  313. q=strrchr(p,*chars);
  314. if (q > p)
  315. p = q + 1;
  316. chars++;
  317. }
  318. q=strrchr(p,'.');
  319. if (q == NULL)
  320. q = p + strlen(p);
  321. strncpy(out,p,size-1);
  322. if (q-p >= size)
  323. {
  324. out[size-1]='\0';
  325. }
  326. else
  327. {
  328. out[q-p]='\0';
  329. }
  330. }
  331. #else
  332. void program_name(char *in, char *out, int size)
  333. {
  334. char *p;
  335. p=strrchr(in,'/');
  336. if (p != NULL)
  337. p++;
  338. else
  339. p=in;
  340. BUF_strlcpy(out,p,size);
  341. }
  342. #endif
  343. #endif
  344. int chopup_args(ARGS *arg, char *buf, int *argc, char **argv[])
  345. {
  346. int num,len,i;
  347. char *p;
  348. *argc=0;
  349. *argv=NULL;
  350. len=strlen(buf);
  351. i=0;
  352. if (arg->count == 0)
  353. {
  354. arg->count=20;
  355. arg->data=(char **)OPENSSL_malloc(sizeof(char *)*arg->count);
  356. }
  357. for (i=0; i<arg->count; i++)
  358. arg->data[i]=NULL;
  359. num=0;
  360. p=buf;
  361. for (;;)
  362. {
  363. /* first scan over white space */
  364. if (!*p) break;
  365. while (*p && ((*p == ' ') || (*p == '\t') || (*p == '\n')))
  366. p++;
  367. if (!*p) break;
  368. /* The start of something good :-) */
  369. if (num >= arg->count)
  370. {
  371. char **tmp_p;
  372. int tlen = arg->count + 20;
  373. tmp_p = (char **)OPENSSL_realloc(arg->data,
  374. sizeof(char *)*tlen);
  375. if (tmp_p == NULL)
  376. return 0;
  377. arg->data = tmp_p;
  378. arg->count = tlen;
  379. /* initialize newly allocated data */
  380. for (i = num; i < arg->count; i++)
  381. arg->data[i] = NULL;
  382. }
  383. arg->data[num++]=p;
  384. /* now look for the end of this */
  385. if ((*p == '\'') || (*p == '\"')) /* scan for closing quote */
  386. {
  387. i= *(p++);
  388. arg->data[num-1]++; /* jump over quote */
  389. while (*p && (*p != i))
  390. p++;
  391. *p='\0';
  392. }
  393. else
  394. {
  395. while (*p && ((*p != ' ') &&
  396. (*p != '\t') && (*p != '\n')))
  397. p++;
  398. if (*p == '\0')
  399. p--;
  400. else
  401. *p='\0';
  402. }
  403. p++;
  404. }
  405. *argc=num;
  406. *argv=arg->data;
  407. return(1);
  408. }
  409. #ifndef APP_INIT
  410. int app_init(long mesgwin)
  411. {
  412. return(1);
  413. }
  414. #endif
  415. int dump_cert_text (BIO *out, X509 *x)
  416. {
  417. char *p;
  418. p=X509_NAME_oneline(X509_get_subject_name(x),NULL,0);
  419. BIO_puts(out,"subject=");
  420. BIO_puts(out,p);
  421. OPENSSL_free(p);
  422. p=X509_NAME_oneline(X509_get_issuer_name(x),NULL,0);
  423. BIO_puts(out,"\nissuer=");
  424. BIO_puts(out,p);
  425. BIO_puts(out,"\n");
  426. OPENSSL_free(p);
  427. return 0;
  428. }
  429. static int ui_open(UI *ui)
  430. {
  431. return UI_method_get_opener(UI_OpenSSL())(ui);
  432. }
  433. static int ui_read(UI *ui, UI_STRING *uis)
  434. {
  435. if (UI_get_input_flags(uis) & UI_INPUT_FLAG_DEFAULT_PWD
  436. && UI_get0_user_data(ui))
  437. {
  438. switch(UI_get_string_type(uis))
  439. {
  440. case UIT_PROMPT:
  441. case UIT_VERIFY:
  442. {
  443. const char *password =
  444. ((PW_CB_DATA *)UI_get0_user_data(ui))->password;
  445. if (password && password[0] != '\0')
  446. {
  447. UI_set_result(ui, uis, password);
  448. return 1;
  449. }
  450. }
  451. default:
  452. break;
  453. }
  454. }
  455. return UI_method_get_reader(UI_OpenSSL())(ui, uis);
  456. }
  457. static int ui_write(UI *ui, UI_STRING *uis)
  458. {
  459. if (UI_get_input_flags(uis) & UI_INPUT_FLAG_DEFAULT_PWD
  460. && UI_get0_user_data(ui))
  461. {
  462. switch(UI_get_string_type(uis))
  463. {
  464. case UIT_PROMPT:
  465. case UIT_VERIFY:
  466. {
  467. const char *password =
  468. ((PW_CB_DATA *)UI_get0_user_data(ui))->password;
  469. if (password && password[0] != '\0')
  470. return 1;
  471. }
  472. default:
  473. break;
  474. }
  475. }
  476. return UI_method_get_writer(UI_OpenSSL())(ui, uis);
  477. }
  478. static int ui_close(UI *ui)
  479. {
  480. return UI_method_get_closer(UI_OpenSSL())(ui);
  481. }
  482. int setup_ui_method(void)
  483. {
  484. ui_method = UI_create_method("OpenSSL application user interface");
  485. UI_method_set_opener(ui_method, ui_open);
  486. UI_method_set_reader(ui_method, ui_read);
  487. UI_method_set_writer(ui_method, ui_write);
  488. UI_method_set_closer(ui_method, ui_close);
  489. return 0;
  490. }
  491. void destroy_ui_method(void)
  492. {
  493. if(ui_method)
  494. {
  495. UI_destroy_method(ui_method);
  496. ui_method = NULL;
  497. }
  498. }
  499. int password_callback(char *buf, int bufsiz, int verify,
  500. PW_CB_DATA *cb_tmp)
  501. {
  502. UI *ui = NULL;
  503. int res = 0;
  504. const char *prompt_info = NULL;
  505. const char *password = NULL;
  506. PW_CB_DATA *cb_data = (PW_CB_DATA *)cb_tmp;
  507. if (cb_data)
  508. {
  509. if (cb_data->password)
  510. password = cb_data->password;
  511. if (cb_data->prompt_info)
  512. prompt_info = cb_data->prompt_info;
  513. }
  514. if (password)
  515. {
  516. res = strlen(password);
  517. if (res > bufsiz)
  518. res = bufsiz;
  519. memcpy(buf, password, res);
  520. return res;
  521. }
  522. ui = UI_new_method(ui_method);
  523. if (ui)
  524. {
  525. int ok = 0;
  526. char *buff = NULL;
  527. int ui_flags = 0;
  528. char *prompt = NULL;
  529. prompt = UI_construct_prompt(ui, "pass phrase",
  530. prompt_info);
  531. ui_flags |= UI_INPUT_FLAG_DEFAULT_PWD;
  532. UI_ctrl(ui, UI_CTRL_PRINT_ERRORS, 1, 0, 0);
  533. if (ok >= 0)
  534. ok = UI_add_input_string(ui,prompt,ui_flags,buf,
  535. PW_MIN_LENGTH,BUFSIZ-1);
  536. if (ok >= 0 && verify)
  537. {
  538. buff = (char *)OPENSSL_malloc(bufsiz);
  539. ok = UI_add_verify_string(ui,prompt,ui_flags,buff,
  540. PW_MIN_LENGTH,BUFSIZ-1, buf);
  541. }
  542. if (ok >= 0)
  543. do
  544. {
  545. ok = UI_process(ui);
  546. }
  547. while (ok < 0 && UI_ctrl(ui, UI_CTRL_IS_REDOABLE, 0, 0, 0));
  548. if (buff)
  549. {
  550. OPENSSL_cleanse(buff,(unsigned int)bufsiz);
  551. OPENSSL_free(buff);
  552. }
  553. if (ok >= 0)
  554. res = strlen(buf);
  555. if (ok == -1)
  556. {
  557. BIO_printf(bio_err, "User interface error\n");
  558. ERR_print_errors(bio_err);
  559. OPENSSL_cleanse(buf,(unsigned int)bufsiz);
  560. res = 0;
  561. }
  562. if (ok == -2)
  563. {
  564. BIO_printf(bio_err,"aborted!\n");
  565. OPENSSL_cleanse(buf,(unsigned int)bufsiz);
  566. res = 0;
  567. }
  568. UI_free(ui);
  569. OPENSSL_free(prompt);
  570. }
  571. return res;
  572. }
  573. static char *app_get_pass(BIO *err, char *arg, int keepbio);
  574. int app_passwd(BIO *err, char *arg1, char *arg2, char **pass1, char **pass2)
  575. {
  576. int same;
  577. if(!arg2 || !arg1 || strcmp(arg1, arg2)) same = 0;
  578. else same = 1;
  579. if(arg1) {
  580. *pass1 = app_get_pass(err, arg1, same);
  581. if(!*pass1) return 0;
  582. } else if(pass1) *pass1 = NULL;
  583. if(arg2) {
  584. *pass2 = app_get_pass(err, arg2, same ? 2 : 0);
  585. if(!*pass2) return 0;
  586. } else if(pass2) *pass2 = NULL;
  587. return 1;
  588. }
  589. static char *app_get_pass(BIO *err, char *arg, int keepbio)
  590. {
  591. char *tmp, tpass[APP_PASS_LEN];
  592. static BIO *pwdbio = NULL;
  593. int i;
  594. if(!strncmp(arg, "pass:", 5)) return BUF_strdup(arg + 5);
  595. if(!strncmp(arg, "env:", 4)) {
  596. tmp = getenv(arg + 4);
  597. if(!tmp) {
  598. BIO_printf(err, "Can't read environment variable %s\n", arg + 4);
  599. return NULL;
  600. }
  601. return BUF_strdup(tmp);
  602. }
  603. if(!keepbio || !pwdbio) {
  604. if(!strncmp(arg, "file:", 5)) {
  605. pwdbio = BIO_new_file(arg + 5, "r");
  606. if(!pwdbio) {
  607. BIO_printf(err, "Can't open file %s\n", arg + 5);
  608. return NULL;
  609. }
  610. #if !defined(_WIN32)
  611. /*
  612. * Under _WIN32, which covers even Win64 and CE, file
  613. * descriptors referenced by BIO_s_fd are not inherited
  614. * by child process and therefore below is not an option.
  615. * It could have been an option if bss_fd.c was operating
  616. * on real Windows descriptors, such as those obtained
  617. * with CreateFile.
  618. */
  619. } else if(!strncmp(arg, "fd:", 3)) {
  620. BIO *btmp;
  621. i = atoi(arg + 3);
  622. if(i >= 0) pwdbio = BIO_new_fd(i, BIO_NOCLOSE);
  623. if((i < 0) || !pwdbio) {
  624. BIO_printf(err, "Can't access file descriptor %s\n", arg + 3);
  625. return NULL;
  626. }
  627. /* Can't do BIO_gets on an fd BIO so add a buffering BIO */
  628. btmp = BIO_new(BIO_f_buffer());
  629. pwdbio = BIO_push(btmp, pwdbio);
  630. #endif
  631. } else if(!strcmp(arg, "stdin")) {
  632. pwdbio = BIO_new_fp(stdin, BIO_NOCLOSE);
  633. if(!pwdbio) {
  634. BIO_printf(err, "Can't open BIO for stdin\n");
  635. return NULL;
  636. }
  637. } else {
  638. BIO_printf(err, "Invalid password argument \"%s\"\n", arg);
  639. return NULL;
  640. }
  641. }
  642. i = BIO_gets(pwdbio, tpass, APP_PASS_LEN);
  643. if(keepbio != 1) {
  644. BIO_free_all(pwdbio);
  645. pwdbio = NULL;
  646. }
  647. if(i <= 0) {
  648. BIO_printf(err, "Error reading password from BIO\n");
  649. return NULL;
  650. }
  651. tmp = strchr(tpass, '\n');
  652. if(tmp) *tmp = 0;
  653. return BUF_strdup(tpass);
  654. }
  655. int add_oid_section(BIO *err, CONF *conf)
  656. {
  657. char *p;
  658. STACK_OF(CONF_VALUE) *sktmp;
  659. CONF_VALUE *cnf;
  660. int i;
  661. if(!(p=NCONF_get_string(conf,NULL,"oid_section")))
  662. {
  663. ERR_clear_error();
  664. return 1;
  665. }
  666. if(!(sktmp = NCONF_get_section(conf, p))) {
  667. BIO_printf(err, "problem loading oid section %s\n", p);
  668. return 0;
  669. }
  670. for(i = 0; i < sk_CONF_VALUE_num(sktmp); i++) {
  671. cnf = sk_CONF_VALUE_value(sktmp, i);
  672. if(OBJ_create(cnf->value, cnf->name, cnf->name) == NID_undef) {
  673. BIO_printf(err, "problem creating object %s=%s\n",
  674. cnf->name, cnf->value);
  675. return 0;
  676. }
  677. }
  678. return 1;
  679. }
  680. static int load_pkcs12(BIO *err, BIO *in, const char *desc,
  681. pem_password_cb *pem_cb, void *cb_data,
  682. EVP_PKEY **pkey, X509 **cert, STACK_OF(X509) **ca)
  683. {
  684. const char *pass;
  685. char tpass[PEM_BUFSIZE];
  686. int len, ret = 0;
  687. PKCS12 *p12;
  688. p12 = d2i_PKCS12_bio(in, NULL);
  689. if (p12 == NULL)
  690. {
  691. BIO_printf(err, "Error loading PKCS12 file for %s\n", desc);
  692. goto die;
  693. }
  694. /* See if an empty password will do */
  695. if (PKCS12_verify_mac(p12, "", 0) || PKCS12_verify_mac(p12, NULL, 0))
  696. pass = "";
  697. else
  698. {
  699. if (!pem_cb)
  700. pem_cb = (pem_password_cb *)password_callback;
  701. len = pem_cb(tpass, PEM_BUFSIZE, 0, cb_data);
  702. if (len < 0)
  703. {
  704. BIO_printf(err, "Passpharse callback error for %s\n",
  705. desc);
  706. goto die;
  707. }
  708. if (len < PEM_BUFSIZE)
  709. tpass[len] = 0;
  710. if (!PKCS12_verify_mac(p12, tpass, len))
  711. {
  712. BIO_printf(err,
  713. "Mac verify error (wrong password?) in PKCS12 file for %s\n", desc);
  714. goto die;
  715. }
  716. pass = tpass;
  717. }
  718. ret = PKCS12_parse(p12, pass, pkey, cert, ca);
  719. die:
  720. if (p12)
  721. PKCS12_free(p12);
  722. return ret;
  723. }
  724. X509 *load_cert(BIO *err, const char *file, int format,
  725. const char *pass, ENGINE *e, const char *cert_descrip)
  726. {
  727. X509 *x=NULL;
  728. BIO *cert;
  729. if ((cert=BIO_new(BIO_s_file())) == NULL)
  730. {
  731. ERR_print_errors(err);
  732. goto end;
  733. }
  734. if (file == NULL)
  735. {
  736. #ifdef _IONBF
  737. setvbuf(stdin, NULL, _IONBF, 0);
  738. #endif
  739. BIO_set_fp(cert,stdin,BIO_NOCLOSE);
  740. }
  741. else
  742. {
  743. if (BIO_read_filename(cert,file) <= 0)
  744. {
  745. BIO_printf(err, "Error opening %s %s\n",
  746. cert_descrip, file);
  747. ERR_print_errors(err);
  748. goto end;
  749. }
  750. }
  751. if (format == FORMAT_ASN1)
  752. x=d2i_X509_bio(cert,NULL);
  753. else if (format == FORMAT_NETSCAPE)
  754. {
  755. NETSCAPE_X509 *nx;
  756. nx=ASN1_item_d2i_bio(ASN1_ITEM_rptr(NETSCAPE_X509),cert,NULL);
  757. if (nx == NULL)
  758. goto end;
  759. if ((strncmp(NETSCAPE_CERT_HDR,(char *)nx->header->data,
  760. nx->header->length) != 0))
  761. {
  762. NETSCAPE_X509_free(nx);
  763. BIO_printf(err,"Error reading header on certificate\n");
  764. goto end;
  765. }
  766. x=nx->cert;
  767. nx->cert = NULL;
  768. NETSCAPE_X509_free(nx);
  769. }
  770. else if (format == FORMAT_PEM)
  771. x=PEM_read_bio_X509_AUX(cert,NULL,
  772. (pem_password_cb *)password_callback, NULL);
  773. else if (format == FORMAT_PKCS12)
  774. {
  775. if (!load_pkcs12(err, cert,cert_descrip, NULL, NULL,
  776. NULL, &x, NULL))
  777. goto end;
  778. }
  779. else {
  780. BIO_printf(err,"bad input format specified for %s\n",
  781. cert_descrip);
  782. goto end;
  783. }
  784. end:
  785. if (x == NULL)
  786. {
  787. BIO_printf(err,"unable to load certificate\n");
  788. ERR_print_errors(err);
  789. }
  790. if (cert != NULL) BIO_free(cert);
  791. return(x);
  792. }
  793. EVP_PKEY *load_key(BIO *err, const char *file, int format, int maybe_stdin,
  794. const char *pass, ENGINE *e, const char *key_descrip)
  795. {
  796. BIO *key=NULL;
  797. EVP_PKEY *pkey=NULL;
  798. PW_CB_DATA cb_data;
  799. cb_data.password = pass;
  800. cb_data.prompt_info = file;
  801. if (file == NULL && (!maybe_stdin || format == FORMAT_ENGINE))
  802. {
  803. BIO_printf(err,"no keyfile specified\n");
  804. goto end;
  805. }
  806. #ifndef OPENSSL_NO_ENGINE
  807. if (format == FORMAT_ENGINE)
  808. {
  809. if (!e)
  810. BIO_printf(bio_err,"no engine specified\n");
  811. else
  812. pkey = ENGINE_load_private_key(e, file,
  813. ui_method, &cb_data);
  814. goto end;
  815. }
  816. #endif
  817. key=BIO_new(BIO_s_file());
  818. if (key == NULL)
  819. {
  820. ERR_print_errors(err);
  821. goto end;
  822. }
  823. if (file == NULL && maybe_stdin)
  824. {
  825. #ifdef _IONBF
  826. setvbuf(stdin, NULL, _IONBF, 0);
  827. #endif
  828. BIO_set_fp(key,stdin,BIO_NOCLOSE);
  829. }
  830. else
  831. if (BIO_read_filename(key,file) <= 0)
  832. {
  833. BIO_printf(err, "Error opening %s %s\n",
  834. key_descrip, file);
  835. ERR_print_errors(err);
  836. goto end;
  837. }
  838. if (format == FORMAT_ASN1)
  839. {
  840. pkey=d2i_PrivateKey_bio(key, NULL);
  841. }
  842. else if (format == FORMAT_PEM)
  843. {
  844. pkey=PEM_read_bio_PrivateKey(key,NULL,
  845. (pem_password_cb *)password_callback, &cb_data);
  846. }
  847. #if !defined(OPENSSL_NO_RC4) && !defined(OPENSSL_NO_RSA)
  848. else if (format == FORMAT_NETSCAPE || format == FORMAT_IISSGC)
  849. pkey = load_netscape_key(err, key, file, key_descrip, format);
  850. #endif
  851. else if (format == FORMAT_PKCS12)
  852. {
  853. if (!load_pkcs12(err, key, key_descrip,
  854. (pem_password_cb *)password_callback, &cb_data,
  855. &pkey, NULL, NULL))
  856. goto end;
  857. }
  858. else if (format == FORMAT_MSBLOB)
  859. pkey = b2i_PrivateKey_bio(key);
  860. else if (format == FORMAT_PVK)
  861. pkey = b2i_PVK_bio(key, (pem_password_cb *)password_callback,
  862. &cb_data);
  863. else
  864. {
  865. BIO_printf(err,"bad input format specified for key file\n");
  866. goto end;
  867. }
  868. end:
  869. if (key != NULL) BIO_free(key);
  870. if (pkey == NULL)
  871. BIO_printf(err,"unable to load %s\n", key_descrip);
  872. return(pkey);
  873. }
  874. EVP_PKEY *load_pubkey(BIO *err, const char *file, int format, int maybe_stdin,
  875. const char *pass, ENGINE *e, const char *key_descrip)
  876. {
  877. BIO *key=NULL;
  878. EVP_PKEY *pkey=NULL;
  879. PW_CB_DATA cb_data;
  880. cb_data.password = pass;
  881. cb_data.prompt_info = file;
  882. if (file == NULL && (!maybe_stdin || format == FORMAT_ENGINE))
  883. {
  884. BIO_printf(err,"no keyfile specified\n");
  885. goto end;
  886. }
  887. #ifndef OPENSSL_NO_ENGINE
  888. if (format == FORMAT_ENGINE)
  889. {
  890. if (!e)
  891. BIO_printf(bio_err,"no engine specified\n");
  892. else
  893. pkey = ENGINE_load_public_key(e, file,
  894. ui_method, &cb_data);
  895. goto end;
  896. }
  897. #endif
  898. key=BIO_new(BIO_s_file());
  899. if (key == NULL)
  900. {
  901. ERR_print_errors(err);
  902. goto end;
  903. }
  904. if (file == NULL && maybe_stdin)
  905. {
  906. #ifdef _IONBF
  907. setvbuf(stdin, NULL, _IONBF, 0);
  908. #endif
  909. BIO_set_fp(key,stdin,BIO_NOCLOSE);
  910. }
  911. else
  912. if (BIO_read_filename(key,file) <= 0)
  913. {
  914. BIO_printf(err, "Error opening %s %s\n",
  915. key_descrip, file);
  916. ERR_print_errors(err);
  917. goto end;
  918. }
  919. if (format == FORMAT_ASN1)
  920. {
  921. pkey=d2i_PUBKEY_bio(key, NULL);
  922. }
  923. else if (format == FORMAT_ASN1RSA)
  924. {
  925. RSA *rsa;
  926. rsa = d2i_RSAPublicKey_bio(key, NULL);
  927. if (rsa)
  928. {
  929. pkey = EVP_PKEY_new();
  930. if (pkey)
  931. EVP_PKEY_set1_RSA(pkey, rsa);
  932. RSA_free(rsa);
  933. }
  934. else
  935. pkey = NULL;
  936. }
  937. else if (format == FORMAT_PEMRSA)
  938. {
  939. RSA *rsa;
  940. rsa = PEM_read_bio_RSAPublicKey(key, NULL,
  941. (pem_password_cb *)password_callback, &cb_data);
  942. if (rsa)
  943. {
  944. pkey = EVP_PKEY_new();
  945. if (pkey)
  946. EVP_PKEY_set1_RSA(pkey, rsa);
  947. RSA_free(rsa);
  948. }
  949. else
  950. pkey = NULL;
  951. }
  952. else if (format == FORMAT_PEM)
  953. {
  954. pkey=PEM_read_bio_PUBKEY(key,NULL,
  955. (pem_password_cb *)password_callback, &cb_data);
  956. }
  957. #if !defined(OPENSSL_NO_RC4) && !defined(OPENSSL_NO_RSA)
  958. else if (format == FORMAT_NETSCAPE || format == FORMAT_IISSGC)
  959. pkey = load_netscape_key(err, key, file, key_descrip, format);
  960. #endif
  961. else if (format == FORMAT_MSBLOB)
  962. pkey = b2i_PublicKey_bio(key);
  963. else
  964. {
  965. BIO_printf(err,"bad input format specified for key file\n");
  966. goto end;
  967. }
  968. end:
  969. if (key != NULL) BIO_free(key);
  970. if (pkey == NULL)
  971. BIO_printf(err,"unable to load %s\n", key_descrip);
  972. return(pkey);
  973. }
  974. #if !defined(OPENSSL_NO_RC4) && !defined(OPENSSL_NO_RSA)
  975. static EVP_PKEY *
  976. load_netscape_key(BIO *err, BIO *key, const char *file,
  977. const char *key_descrip, int format)
  978. {
  979. EVP_PKEY *pkey;
  980. BUF_MEM *buf;
  981. RSA *rsa;
  982. const unsigned char *p;
  983. int size, i;
  984. buf=BUF_MEM_new();
  985. pkey = EVP_PKEY_new();
  986. size = 0;
  987. if (buf == NULL || pkey == NULL)
  988. goto error;
  989. for (;;)
  990. {
  991. if (!BUF_MEM_grow_clean(buf,size+1024*10))
  992. goto error;
  993. i = BIO_read(key, &(buf->data[size]), 1024*10);
  994. size += i;
  995. if (i == 0)
  996. break;
  997. if (i < 0)
  998. {
  999. BIO_printf(err, "Error reading %s %s",
  1000. key_descrip, file);
  1001. goto error;
  1002. }
  1003. }
  1004. p=(unsigned char *)buf->data;
  1005. rsa = d2i_RSA_NET(NULL,&p,(long)size,NULL,
  1006. (format == FORMAT_IISSGC ? 1 : 0));
  1007. if (rsa == NULL)
  1008. goto error;
  1009. BUF_MEM_free(buf);
  1010. EVP_PKEY_set1_RSA(pkey, rsa);
  1011. return pkey;
  1012. error:
  1013. BUF_MEM_free(buf);
  1014. EVP_PKEY_free(pkey);
  1015. return NULL;
  1016. }
  1017. #endif /* ndef OPENSSL_NO_RC4 */
  1018. STACK_OF(X509) *load_certs(BIO *err, const char *file, int format,
  1019. const char *pass, ENGINE *e, const char *cert_descrip)
  1020. {
  1021. BIO *certs;
  1022. int i;
  1023. STACK_OF(X509) *othercerts = NULL;
  1024. STACK_OF(X509_INFO) *allcerts = NULL;
  1025. X509_INFO *xi;
  1026. PW_CB_DATA cb_data;
  1027. cb_data.password = pass;
  1028. cb_data.prompt_info = file;
  1029. if((certs = BIO_new(BIO_s_file())) == NULL)
  1030. {
  1031. ERR_print_errors(err);
  1032. goto end;
  1033. }
  1034. if (file == NULL)
  1035. BIO_set_fp(certs,stdin,BIO_NOCLOSE);
  1036. else
  1037. {
  1038. if (BIO_read_filename(certs,file) <= 0)
  1039. {
  1040. BIO_printf(err, "Error opening %s %s\n",
  1041. cert_descrip, file);
  1042. ERR_print_errors(err);
  1043. goto end;
  1044. }
  1045. }
  1046. if (format == FORMAT_PEM)
  1047. {
  1048. othercerts = sk_X509_new_null();
  1049. if(!othercerts)
  1050. {
  1051. sk_X509_free(othercerts);
  1052. othercerts = NULL;
  1053. goto end;
  1054. }
  1055. allcerts = PEM_X509_INFO_read_bio(certs, NULL,
  1056. (pem_password_cb *)password_callback, &cb_data);
  1057. for(i = 0; i < sk_X509_INFO_num(allcerts); i++)
  1058. {
  1059. xi = sk_X509_INFO_value (allcerts, i);
  1060. if (xi->x509)
  1061. {
  1062. sk_X509_push(othercerts, xi->x509);
  1063. xi->x509 = NULL;
  1064. }
  1065. }
  1066. goto end;
  1067. }
  1068. else {
  1069. BIO_printf(err,"bad input format specified for %s\n",
  1070. cert_descrip);
  1071. goto end;
  1072. }
  1073. end:
  1074. if (othercerts == NULL)
  1075. {
  1076. BIO_printf(err,"unable to load certificates\n");
  1077. ERR_print_errors(err);
  1078. }
  1079. if (allcerts) sk_X509_INFO_pop_free(allcerts, X509_INFO_free);
  1080. if (certs != NULL) BIO_free(certs);
  1081. return(othercerts);
  1082. }
  1083. #define X509V3_EXT_UNKNOWN_MASK (0xfL << 16)
  1084. /* Return error for unknown extensions */
  1085. #define X509V3_EXT_DEFAULT 0
  1086. /* Print error for unknown extensions */
  1087. #define X509V3_EXT_ERROR_UNKNOWN (1L << 16)
  1088. /* ASN1 parse unknown extensions */
  1089. #define X509V3_EXT_PARSE_UNKNOWN (2L << 16)
  1090. /* BIO_dump unknown extensions */
  1091. #define X509V3_EXT_DUMP_UNKNOWN (3L << 16)
  1092. #define X509_FLAG_CA (X509_FLAG_NO_ISSUER | X509_FLAG_NO_PUBKEY | \
  1093. X509_FLAG_NO_HEADER | X509_FLAG_NO_VERSION)
  1094. int set_cert_ex(unsigned long *flags, const char *arg)
  1095. {
  1096. static const NAME_EX_TBL cert_tbl[] = {
  1097. { "compatible", X509_FLAG_COMPAT, 0xffffffffl},
  1098. { "ca_default", X509_FLAG_CA, 0xffffffffl},
  1099. { "no_header", X509_FLAG_NO_HEADER, 0},
  1100. { "no_version", X509_FLAG_NO_VERSION, 0},
  1101. { "no_serial", X509_FLAG_NO_SERIAL, 0},
  1102. { "no_signame", X509_FLAG_NO_SIGNAME, 0},
  1103. { "no_validity", X509_FLAG_NO_VALIDITY, 0},
  1104. { "no_subject", X509_FLAG_NO_SUBJECT, 0},
  1105. { "no_issuer", X509_FLAG_NO_ISSUER, 0},
  1106. { "no_pubkey", X509_FLAG_NO_PUBKEY, 0},
  1107. { "no_extensions", X509_FLAG_NO_EXTENSIONS, 0},
  1108. { "no_sigdump", X509_FLAG_NO_SIGDUMP, 0},
  1109. { "no_aux", X509_FLAG_NO_AUX, 0},
  1110. { "no_attributes", X509_FLAG_NO_ATTRIBUTES, 0},
  1111. { "ext_default", X509V3_EXT_DEFAULT, X509V3_EXT_UNKNOWN_MASK},
  1112. { "ext_error", X509V3_EXT_ERROR_UNKNOWN, X509V3_EXT_UNKNOWN_MASK},
  1113. { "ext_parse", X509V3_EXT_PARSE_UNKNOWN, X509V3_EXT_UNKNOWN_MASK},
  1114. { "ext_dump", X509V3_EXT_DUMP_UNKNOWN, X509V3_EXT_UNKNOWN_MASK},
  1115. { NULL, 0, 0}
  1116. };
  1117. return set_multi_opts(flags, arg, cert_tbl);
  1118. }
  1119. int set_name_ex(unsigned long *flags, const char *arg)
  1120. {
  1121. static const NAME_EX_TBL ex_tbl[] = {
  1122. { "esc_2253", ASN1_STRFLGS_ESC_2253, 0},
  1123. { "esc_ctrl", ASN1_STRFLGS_ESC_CTRL, 0},
  1124. { "esc_msb", ASN1_STRFLGS_ESC_MSB, 0},
  1125. { "use_quote", ASN1_STRFLGS_ESC_QUOTE, 0},
  1126. { "utf8", ASN1_STRFLGS_UTF8_CONVERT, 0},
  1127. { "ignore_type", ASN1_STRFLGS_IGNORE_TYPE, 0},
  1128. { "show_type", ASN1_STRFLGS_SHOW_TYPE, 0},
  1129. { "dump_all", ASN1_STRFLGS_DUMP_ALL, 0},
  1130. { "dump_nostr", ASN1_STRFLGS_DUMP_UNKNOWN, 0},
  1131. { "dump_der", ASN1_STRFLGS_DUMP_DER, 0},
  1132. { "compat", XN_FLAG_COMPAT, 0xffffffffL},
  1133. { "sep_comma_plus", XN_FLAG_SEP_COMMA_PLUS, XN_FLAG_SEP_MASK},
  1134. { "sep_comma_plus_space", XN_FLAG_SEP_CPLUS_SPC, XN_FLAG_SEP_MASK},
  1135. { "sep_semi_plus_space", XN_FLAG_SEP_SPLUS_SPC, XN_FLAG_SEP_MASK},
  1136. { "sep_multiline", XN_FLAG_SEP_MULTILINE, XN_FLAG_SEP_MASK},
  1137. { "dn_rev", XN_FLAG_DN_REV, 0},
  1138. { "nofname", XN_FLAG_FN_NONE, XN_FLAG_FN_MASK},
  1139. { "sname", XN_FLAG_FN_SN, XN_FLAG_FN_MASK},
  1140. { "lname", XN_FLAG_FN_LN, XN_FLAG_FN_MASK},
  1141. { "align", XN_FLAG_FN_ALIGN, 0},
  1142. { "oid", XN_FLAG_FN_OID, XN_FLAG_FN_MASK},
  1143. { "space_eq", XN_FLAG_SPC_EQ, 0},
  1144. { "dump_unknown", XN_FLAG_DUMP_UNKNOWN_FIELDS, 0},
  1145. { "RFC2253", XN_FLAG_RFC2253, 0xffffffffL},
  1146. { "oneline", XN_FLAG_ONELINE, 0xffffffffL},
  1147. { "multiline", XN_FLAG_MULTILINE, 0xffffffffL},
  1148. { "ca_default", XN_FLAG_MULTILINE, 0xffffffffL},
  1149. { NULL, 0, 0}
  1150. };
  1151. return set_multi_opts(flags, arg, ex_tbl);
  1152. }
  1153. int set_ext_copy(int *copy_type, const char *arg)
  1154. {
  1155. if (!strcasecmp(arg, "none"))
  1156. *copy_type = EXT_COPY_NONE;
  1157. else if (!strcasecmp(arg, "copy"))
  1158. *copy_type = EXT_COPY_ADD;
  1159. else if (!strcasecmp(arg, "copyall"))
  1160. *copy_type = EXT_COPY_ALL;
  1161. else
  1162. return 0;
  1163. return 1;
  1164. }
  1165. int copy_extensions(X509 *x, X509_REQ *req, int copy_type)
  1166. {
  1167. STACK_OF(X509_EXTENSION) *exts = NULL;
  1168. X509_EXTENSION *ext, *tmpext;
  1169. ASN1_OBJECT *obj;
  1170. int i, idx, ret = 0;
  1171. if (!x || !req || (copy_type == EXT_COPY_NONE))
  1172. return 1;
  1173. exts = X509_REQ_get_extensions(req);
  1174. for(i = 0; i < sk_X509_EXTENSION_num(exts); i++) {
  1175. ext = sk_X509_EXTENSION_value(exts, i);
  1176. obj = X509_EXTENSION_get_object(ext);
  1177. idx = X509_get_ext_by_OBJ(x, obj, -1);
  1178. /* Does extension exist? */
  1179. if (idx != -1) {
  1180. /* If normal copy don't override existing extension */
  1181. if (copy_type == EXT_COPY_ADD)
  1182. continue;
  1183. /* Delete all extensions of same type */
  1184. do {
  1185. tmpext = X509_get_ext(x, idx);
  1186. X509_delete_ext(x, idx);
  1187. X509_EXTENSION_free(tmpext);
  1188. idx = X509_get_ext_by_OBJ(x, obj, -1);
  1189. } while (idx != -1);
  1190. }
  1191. if (!X509_add_ext(x, ext, -1))
  1192. goto end;
  1193. }
  1194. ret = 1;
  1195. end:
  1196. sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free);
  1197. return ret;
  1198. }
  1199. static int set_multi_opts(unsigned long *flags, const char *arg, const NAME_EX_TBL *in_tbl)
  1200. {
  1201. STACK_OF(CONF_VALUE) *vals;
  1202. CONF_VALUE *val;
  1203. int i, ret = 1;
  1204. if(!arg) return 0;
  1205. vals = X509V3_parse_list(arg);
  1206. for (i = 0; i < sk_CONF_VALUE_num(vals); i++) {
  1207. val = sk_CONF_VALUE_value(vals, i);
  1208. if (!set_table_opts(flags, val->name, in_tbl))
  1209. ret = 0;
  1210. }
  1211. sk_CONF_VALUE_pop_free(vals, X509V3_conf_free);
  1212. return ret;
  1213. }
  1214. static int set_table_opts(unsigned long *flags, const char *arg, const NAME_EX_TBL *in_tbl)
  1215. {
  1216. char c;
  1217. const NAME_EX_TBL *ptbl;
  1218. c = arg[0];
  1219. if(c == '-') {
  1220. c = 0;
  1221. arg++;
  1222. } else if (c == '+') {
  1223. c = 1;
  1224. arg++;
  1225. } else c = 1;
  1226. for(ptbl = in_tbl; ptbl->name; ptbl++) {
  1227. if(!strcasecmp(arg, ptbl->name)) {
  1228. *flags &= ~ptbl->mask;
  1229. if(c) *flags |= ptbl->flag;
  1230. else *flags &= ~ptbl->flag;
  1231. return 1;
  1232. }
  1233. }
  1234. return 0;
  1235. }
  1236. void print_name(BIO *out, const char *title, X509_NAME *nm, unsigned long lflags)
  1237. {
  1238. char *buf;
  1239. char mline = 0;
  1240. int indent = 0;
  1241. if(title) BIO_puts(out, title);
  1242. if((lflags & XN_FLAG_SEP_MASK) == XN_FLAG_SEP_MULTILINE) {
  1243. mline = 1;
  1244. indent = 4;
  1245. }
  1246. if(lflags == XN_FLAG_COMPAT) {
  1247. buf = X509_NAME_oneline(nm, 0, 0);
  1248. BIO_puts(out, buf);
  1249. BIO_puts(out, "\n");
  1250. OPENSSL_free(buf);
  1251. } else {
  1252. if(mline) BIO_puts(out, "\n");
  1253. X509_NAME_print_ex(out, nm, indent, lflags);
  1254. BIO_puts(out, "\n");
  1255. }
  1256. }
  1257. X509_STORE *setup_verify(BIO *bp, char *CAfile, char *CApath)
  1258. {
  1259. X509_STORE *store;
  1260. X509_LOOKUP *lookup;
  1261. if(!(store = X509_STORE_new())) goto end;
  1262. lookup=X509_STORE_add_lookup(store,X509_LOOKUP_file());
  1263. if (lookup == NULL) goto end;
  1264. if (CAfile) {
  1265. if(!X509_LOOKUP_load_file(lookup,CAfile,X509_FILETYPE_PEM)) {
  1266. BIO_printf(bp, "Error loading file %s\n", CAfile);
  1267. goto end;
  1268. }
  1269. } else X509_LOOKUP_load_file(lookup,NULL,X509_FILETYPE_DEFAULT);
  1270. lookup=X509_STORE_add_lookup(store,X509_LOOKUP_hash_dir());
  1271. if (lookup == NULL) goto end;
  1272. if (CApath) {
  1273. if(!X509_LOOKUP_add_dir(lookup,CApath,X509_FILETYPE_PEM)) {
  1274. BIO_printf(bp, "Error loading directory %s\n", CApath);
  1275. goto end;
  1276. }
  1277. } else X509_LOOKUP_add_dir(lookup,NULL,X509_FILETYPE_DEFAULT);
  1278. ERR_clear_error();
  1279. return store;
  1280. end:
  1281. X509_STORE_free(store);
  1282. return NULL;
  1283. }
  1284. #ifndef OPENSSL_NO_ENGINE
  1285. /* Try to load an engine in a shareable library */
  1286. static ENGINE *try_load_engine(BIO *err, const char *engine, int debug)
  1287. {
  1288. ENGINE *e = ENGINE_by_id("dynamic");
  1289. if (e)
  1290. {
  1291. if (!ENGINE_ctrl_cmd_string(e, "SO_PATH", engine, 0)
  1292. || !ENGINE_ctrl_cmd_string(e, "LOAD", NULL, 0))
  1293. {
  1294. ENGINE_free(e);
  1295. e = NULL;
  1296. }
  1297. }
  1298. return e;
  1299. }
  1300. ENGINE *setup_engine(BIO *err, const char *engine, int debug)
  1301. {
  1302. ENGINE *e = NULL;
  1303. if (engine)
  1304. {
  1305. if(strcmp(engine, "auto") == 0)
  1306. {
  1307. BIO_printf(err,"enabling auto ENGINE support\n");
  1308. ENGINE_register_all_complete();
  1309. return NULL;
  1310. }
  1311. if((e = ENGINE_by_id(engine)) == NULL
  1312. && (e = try_load_engine(err, engine, debug)) == NULL)
  1313. {
  1314. BIO_printf(err,"invalid engine \"%s\"\n", engine);
  1315. ERR_print_errors(err);
  1316. return NULL;
  1317. }
  1318. if (debug)
  1319. {
  1320. ENGINE_ctrl(e, ENGINE_CTRL_SET_LOGSTREAM,
  1321. 0, err, 0);
  1322. }
  1323. ENGINE_ctrl_cmd(e, "SET_USER_INTERFACE", 0, ui_method, 0, 1);
  1324. if(!ENGINE_set_default(e, ENGINE_METHOD_ALL))
  1325. {
  1326. BIO_printf(err,"can't use that engine\n");
  1327. ERR_print_errors(err);
  1328. ENGINE_free(e);
  1329. return NULL;
  1330. }
  1331. BIO_printf(err,"engine \"%s\" set.\n", ENGINE_get_id(e));
  1332. /* Free our "structural" reference. */
  1333. ENGINE_free(e);
  1334. }
  1335. return e;
  1336. }
  1337. #endif
  1338. int load_config(BIO *err, CONF *cnf)
  1339. {
  1340. static int load_config_called = 0;
  1341. if (load_config_called)
  1342. return 1;
  1343. load_config_called = 1;
  1344. if (!cnf)
  1345. cnf = config;
  1346. if (!cnf)
  1347. return 1;
  1348. OPENSSL_load_builtin_modules();
  1349. if (CONF_modules_load(cnf, NULL, 0) <= 0)
  1350. {
  1351. BIO_printf(err, "Error configuring OpenSSL\n");
  1352. ERR_print_errors(err);
  1353. return 0;
  1354. }
  1355. return 1;
  1356. }
  1357. char *make_config_name()
  1358. {
  1359. const char *t=X509_get_default_cert_area();
  1360. size_t len;
  1361. char *p;
  1362. len=strlen(t)+strlen(OPENSSL_CONF)+2;
  1363. p=OPENSSL_malloc(len);
  1364. BUF_strlcpy(p,t,len);
  1365. #ifndef OPENSSL_SYS_VMS
  1366. BUF_strlcat(p,"/",len);
  1367. #endif
  1368. BUF_strlcat(p,OPENSSL_CONF,len);
  1369. return p;
  1370. }
  1371. static unsigned long index_serial_hash(const char **a)
  1372. {
  1373. const char *n;
  1374. n=a[DB_serial];
  1375. while (*n == '0') n++;
  1376. return(lh_strhash(n));
  1377. }
  1378. static int index_serial_cmp(const char **a, const char **b)
  1379. {
  1380. const char *aa,*bb;
  1381. for (aa=a[DB_serial]; *aa == '0'; aa++);
  1382. for (bb=b[DB_serial]; *bb == '0'; bb++);
  1383. return(strcmp(aa,bb));
  1384. }
  1385. static int index_name_qual(char **a)
  1386. { return(a[0][0] == 'V'); }
  1387. static unsigned long index_name_hash(const char **a)
  1388. { return(lh_strhash(a[DB_name])); }
  1389. int index_name_cmp(const char **a, const char **b)
  1390. { return(strcmp(a[DB_name],
  1391. b[DB_name])); }
  1392. static IMPLEMENT_LHASH_HASH_FN(index_serial_hash,const char **)
  1393. static IMPLEMENT_LHASH_COMP_FN(index_serial_cmp,const char **)
  1394. static IMPLEMENT_LHASH_HASH_FN(index_name_hash,const char **)
  1395. static IMPLEMENT_LHASH_COMP_FN(index_name_cmp,const char **)
  1396. #undef BSIZE
  1397. #define BSIZE 256
  1398. BIGNUM *load_serial(char *serialfile, int create, ASN1_INTEGER **retai)
  1399. {
  1400. BIO *in=NULL;
  1401. BIGNUM *ret=NULL;
  1402. MS_STATIC char buf[1024];
  1403. ASN1_INTEGER *ai=NULL;
  1404. ai=ASN1_INTEGER_new();
  1405. if (ai == NULL) goto err;
  1406. if ((in=BIO_new(BIO_s_file())) == NULL)
  1407. {
  1408. ERR_print_errors(bio_err);
  1409. goto err;
  1410. }
  1411. if (BIO_read_filename(in,serialfile) <= 0)
  1412. {
  1413. if (!create)
  1414. {
  1415. perror(serialfile);
  1416. goto err;
  1417. }
  1418. else
  1419. {
  1420. ret=BN_new();
  1421. if (ret == NULL || !rand_serial(ret, ai))
  1422. BIO_printf(bio_err, "Out of memory\n");
  1423. }
  1424. }
  1425. else
  1426. {
  1427. if (!a2i_ASN1_INTEGER(in,ai,buf,1024))
  1428. {
  1429. BIO_printf(bio_err,"unable to load number from %s\n",
  1430. serialfile);
  1431. goto err;
  1432. }
  1433. ret=ASN1_INTEGER_to_BN(ai,NULL);
  1434. if (ret == NULL)
  1435. {
  1436. BIO_printf(bio_err,"error converting number from bin to BIGNUM\n");
  1437. goto err;
  1438. }
  1439. }
  1440. if (ret && retai)
  1441. {
  1442. *retai = ai;
  1443. ai = NULL;
  1444. }
  1445. err:
  1446. if (in != NULL) BIO_free(in);
  1447. if (ai != NULL) ASN1_INTEGER_free(ai);
  1448. return(ret);
  1449. }
  1450. int save_serial(char *serialfile, char *suffix, BIGNUM *serial, ASN1_INTEGER **retai)
  1451. {
  1452. char buf[1][BSIZE];
  1453. BIO *out = NULL;
  1454. int ret=0;
  1455. ASN1_INTEGER *ai=NULL;
  1456. int j;
  1457. if (suffix == NULL)
  1458. j = strlen(serialfile);
  1459. else
  1460. j = strlen(serialfile) + strlen(suffix) + 1;
  1461. if (j >= BSIZE)
  1462. {
  1463. BIO_printf(bio_err,"file name too long\n");
  1464. goto err;
  1465. }
  1466. if (suffix == NULL)
  1467. BUF_strlcpy(buf[0], serialfile, BSIZE);
  1468. else
  1469. {
  1470. #ifndef OPENSSL_SYS_VMS
  1471. j = BIO_snprintf(buf[0], sizeof buf[0], "%s.%s", serialfile, suffix);
  1472. #else
  1473. j = BIO_snprintf(buf[0], sizeof buf[0], "%s-%s", serialfile, suffix);
  1474. #endif
  1475. }
  1476. #ifdef RL_DEBUG
  1477. BIO_printf(bio_err, "DEBUG: writing \"%s\"\n", buf[0]);
  1478. #endif
  1479. out=BIO_new(BIO_s_file());
  1480. if (out == NULL)
  1481. {
  1482. ERR_print_errors(bio_err);
  1483. goto err;
  1484. }
  1485. if (BIO_write_filename(out,buf[0]) <= 0)
  1486. {
  1487. perror(serialfile);
  1488. goto err;
  1489. }
  1490. if ((ai=BN_to_ASN1_INTEGER(serial,NULL)) == NULL)
  1491. {
  1492. BIO_printf(bio_err,"error converting serial to ASN.1 format\n");
  1493. goto err;
  1494. }
  1495. i2a_ASN1_INTEGER(out,ai);
  1496. BIO_puts(out,"\n");
  1497. ret=1;
  1498. if (retai)
  1499. {
  1500. *retai = ai;
  1501. ai = NULL;
  1502. }
  1503. err:
  1504. if (out != NULL) BIO_free_all(out);
  1505. if (ai != NULL) ASN1_INTEGER_free(ai);
  1506. return(ret);
  1507. }
  1508. int rotate_serial(char *serialfile, char *new_suffix, char *old_suffix)
  1509. {
  1510. char buf[5][BSIZE];
  1511. int i,j;
  1512. i = strlen(serialfile) + strlen(old_suffix);
  1513. j = strlen(serialfile) + strlen(new_suffix);
  1514. if (i > j) j = i;
  1515. if (j + 1 >= BSIZE)
  1516. {
  1517. BIO_printf(bio_err,"file name too long\n");
  1518. goto err;
  1519. }
  1520. #ifndef OPENSSL_SYS_VMS
  1521. j = BIO_snprintf(buf[0], sizeof buf[0], "%s.%s",
  1522. serialfile, new_suffix);
  1523. #else
  1524. j = BIO_snprintf(buf[0], sizeof buf[0], "%s-%s",
  1525. serialfile, new_suffix);
  1526. #endif
  1527. #ifndef OPENSSL_SYS_VMS
  1528. j = BIO_snprintf(buf[1], sizeof buf[1], "%s.%s",
  1529. serialfile, old_suffix);
  1530. #else
  1531. j = BIO_snprintf(buf[1], sizeof buf[1], "%s-%s",
  1532. serialfile, old_suffix);
  1533. #endif
  1534. #ifdef RL_DEBUG
  1535. BIO_printf(bio_err, "DEBUG: renaming \"%s\" to \"%s\"\n",
  1536. serialfile, buf[1]);
  1537. #endif
  1538. if (rename(serialfile,buf[1]) < 0 && errno != ENOENT
  1539. #ifdef ENOTDIR
  1540. && errno != ENOTDIR
  1541. #endif
  1542. ) {
  1543. BIO_printf(bio_err,
  1544. "unable to rename %s to %s\n",
  1545. serialfile, buf[1]);
  1546. perror("reason");
  1547. goto err;
  1548. }
  1549. #ifdef RL_DEBUG
  1550. BIO_printf(bio_err, "DEBUG: renaming \"%s\" to \"%s\"\n",
  1551. buf[0],serialfile);
  1552. #endif
  1553. if (rename(buf[0],serialfile) < 0)
  1554. {
  1555. BIO_printf(bio_err,
  1556. "unable to rename %s to %s\n",
  1557. buf[0],serialfile);
  1558. perror("reason");
  1559. rename(buf[1],serialfile);
  1560. goto err;
  1561. }
  1562. return 1;
  1563. err:
  1564. return 0;
  1565. }
  1566. int rand_serial(BIGNUM *b, ASN1_INTEGER *ai)
  1567. {
  1568. BIGNUM *btmp;
  1569. int ret = 0;
  1570. if (b)
  1571. btmp = b;
  1572. else
  1573. btmp = BN_new();
  1574. if (!btmp)
  1575. return 0;
  1576. if (!BN_pseudo_rand(btmp, SERIAL_RAND_BITS, 0, 0))
  1577. goto error;
  1578. if (ai && !BN_to_ASN1_INTEGER(btmp, ai))
  1579. goto error;
  1580. ret = 1;
  1581. error:
  1582. if (!b)
  1583. BN_free(btmp);
  1584. return ret;
  1585. }
  1586. CA_DB *load_index(char *dbfile, DB_ATTR *db_attr)
  1587. {
  1588. CA_DB *retdb = NULL;
  1589. TXT_DB *tmpdb = NULL;
  1590. BIO *in = BIO_new(BIO_s_file());
  1591. CONF *dbattr_conf = NULL;
  1592. char buf[1][BSIZE];
  1593. long errorline= -1;
  1594. if (in == NULL)
  1595. {
  1596. ERR_print_errors(bio_err);
  1597. goto err;
  1598. }
  1599. if (BIO_read_filename(in,dbfile) <= 0)
  1600. {
  1601. perror(dbfile);
  1602. BIO_printf(bio_err,"unable to open '%s'\n",dbfile);
  1603. goto err;
  1604. }
  1605. if ((tmpdb = TXT_DB_read(in,DB_NUMBER)) == NULL)
  1606. goto err;
  1607. #ifndef OPENSSL_SYS_VMS
  1608. BIO_snprintf(buf[0], sizeof buf[0], "%s.attr", dbfile);
  1609. #else
  1610. BIO_snprintf(buf[0], sizeof buf[0], "%s-attr", dbfile);
  1611. #endif
  1612. dbattr_conf = NCONF_new(NULL);
  1613. if (NCONF_load(dbattr_conf,buf[0],&errorline) <= 0)
  1614. {
  1615. if (errorline > 0)
  1616. {
  1617. BIO_printf(bio_err,
  1618. "error on line %ld of db attribute file '%s'\n"
  1619. ,errorline,buf[0]);
  1620. goto err;
  1621. }
  1622. else
  1623. {
  1624. NCONF_free(dbattr_conf);
  1625. dbattr_conf = NULL;
  1626. }
  1627. }
  1628. if ((retdb = OPENSSL_malloc(sizeof(CA_DB))) == NULL)
  1629. {
  1630. fprintf(stderr, "Out of memory\n");
  1631. goto err;
  1632. }
  1633. retdb->db = tmpdb;
  1634. tmpdb = NULL;
  1635. if (db_attr)
  1636. retdb->attributes = *db_attr;
  1637. else
  1638. {
  1639. retdb->attributes.unique_subject = 1;
  1640. }
  1641. if (dbattr_conf)
  1642. {
  1643. char *p = NCONF_get_string(dbattr_conf,NULL,"unique_subject");
  1644. if (p)
  1645. {
  1646. #ifdef RL_DEBUG
  1647. BIO_printf(bio_err, "DEBUG[load_index]: unique_subject = \"%s\"\n", p);
  1648. #endif
  1649. retdb->attributes.unique_subject = parse_yesno(p,1);
  1650. }
  1651. }
  1652. err:
  1653. if (dbattr_conf) NCONF_free(dbattr_conf);
  1654. if (tmpdb) TXT_DB_free(tmpdb);
  1655. if (in) BIO_free_all(in);
  1656. return retdb;
  1657. }
  1658. int index_index(CA_DB *db)
  1659. {
  1660. if (!TXT_DB_create_index(db->db, DB_serial, NULL,
  1661. LHASH_HASH_FN(index_serial_hash),
  1662. LHASH_COMP_FN(index_serial_cmp)))
  1663. {
  1664. BIO_printf(bio_err,
  1665. "error creating serial number index:(%ld,%ld,%ld)\n",
  1666. db->db->error,db->db->arg1,db->db->arg2);
  1667. return 0;
  1668. }
  1669. if (db->attributes.unique_subject
  1670. && !TXT_DB_create_index(db->db, DB_name, index_name_qual,
  1671. LHASH_HASH_FN(index_name_hash),
  1672. LHASH_COMP_FN(index_name_cmp)))
  1673. {
  1674. BIO_printf(bio_err,"error creating name index:(%ld,%ld,%ld)\n",
  1675. db->db->error,db->db->arg1,db->db->arg2);
  1676. return 0;
  1677. }
  1678. return 1;
  1679. }
  1680. int save_index(const char *dbfile, const char *suffix, CA_DB *db)
  1681. {
  1682. char buf[3][BSIZE];
  1683. BIO *out = BIO_new(BIO_s_file());
  1684. int j;
  1685. if (out == NULL)
  1686. {
  1687. ERR_print_errors(bio_err);
  1688. goto err;
  1689. }
  1690. j = strlen(dbfile) + strlen(suffix);
  1691. if (j + 6 >= BSIZE)
  1692. {
  1693. BIO_printf(bio_err,"file name too long\n");
  1694. goto err;
  1695. }
  1696. #ifndef OPENSSL_SYS_VMS
  1697. j = BIO_snprintf(buf[2], sizeof buf[2], "%s.attr", dbfile);
  1698. #else
  1699. j = BIO_snprintf(buf[2], sizeof buf[2], "%s-attr", dbfile);
  1700. #endif
  1701. #ifndef OPENSSL_SYS_VMS
  1702. j = BIO_snprintf(buf[1], sizeof buf[1], "%s.attr.%s", dbfile, suffix);
  1703. #else
  1704. j = BIO_snprintf(buf[1], sizeof buf[1], "%s-attr-%s", dbfile, suffix);
  1705. #endif
  1706. #ifndef OPENSSL_SYS_VMS
  1707. j = BIO_snprintf(buf[0], sizeof buf[0], "%s.%s", dbfile, suffix);
  1708. #else
  1709. j = BIO_snprintf(buf[0], sizeof buf[0], "%s-%s", dbfile, suffix);
  1710. #endif
  1711. #ifdef RL_DEBUG
  1712. BIO_printf(bio_err, "DEBUG: writing \"%s\"\n", buf[0]);
  1713. #endif
  1714. if (BIO_write_filename(out,buf[0]) <= 0)
  1715. {
  1716. perror(dbfile);
  1717. BIO_printf(bio_err,"unable to open '%s'\n", dbfile);
  1718. goto err;
  1719. }
  1720. j=TXT_DB_write(out,db->db);
  1721. if (j <= 0) goto err;
  1722. BIO_free(out);
  1723. out = BIO_new(BIO_s_file());
  1724. #ifdef RL_DEBUG
  1725. BIO_printf(bio_err, "DEBUG: writing \"%s\"\n", buf[1]);
  1726. #endif
  1727. if (BIO_write_filename(out,buf[1]) <= 0)
  1728. {
  1729. perror(buf[2]);
  1730. BIO_printf(bio_err,"unable to open '%s'\n", buf[2]);
  1731. goto err;
  1732. }
  1733. BIO_printf(out,"unique_subject = %s\n",
  1734. db->attributes.unique_subject ? "yes" : "no");
  1735. BIO_free(out);
  1736. return 1;
  1737. err:
  1738. return 0;
  1739. }
  1740. int rotate_index(const char *dbfile, const char *new_suffix, const char *old_suffix)
  1741. {
  1742. char buf[5][BSIZE];
  1743. int i,j;
  1744. i = strlen(dbfile) + strlen(old_suffix);
  1745. j = strlen(dbfile) + strlen(new_suffix);
  1746. if (i > j) j = i;
  1747. if (j + 6 >= BSIZE)
  1748. {
  1749. BIO_printf(bio_err,"file name too long\n");
  1750. goto err;
  1751. }
  1752. #ifndef OPENSSL_SYS_VMS
  1753. j = BIO_snprintf(buf[4], sizeof buf[4], "%s.attr", dbfile);
  1754. #else
  1755. j = BIO_snprintf(buf[4], sizeof buf[4], "%s-attr", dbfile);
  1756. #endif
  1757. #ifndef OPENSSL_SYS_VMS
  1758. j = BIO_snprintf(buf[2], sizeof buf[2], "%s.attr.%s",
  1759. dbfile, new_suffix);
  1760. #else
  1761. j = BIO_snprintf(buf[2], sizeof buf[2], "%s-attr-%s",
  1762. dbfile, new_suffix);
  1763. #endif
  1764. #ifndef OPENSSL_SYS_VMS
  1765. j = BIO_snprintf(buf[0], sizeof buf[0], "%s.%s",
  1766. dbfile, new_suffix);
  1767. #else
  1768. j = BIO_snprintf(buf[0], sizeof buf[0], "%s-%s",
  1769. dbfile, new_suffix);
  1770. #endif
  1771. #ifndef OPENSSL_SYS_VMS
  1772. j = BIO_snprintf(buf[1], sizeof buf[1], "%s.%s",
  1773. dbfile, old_suffix);
  1774. #else
  1775. j = BIO_snprintf(buf[1], sizeof buf[1], "%s-%s",
  1776. dbfile, old_suffix);
  1777. #endif
  1778. #ifndef OPENSSL_SYS_VMS
  1779. j = BIO_snprintf(buf[3], sizeof buf[3], "%s.attr.%s",
  1780. dbfile, old_suffix);
  1781. #else
  1782. j = BIO_snprintf(buf[3], sizeof buf[3], "%s-attr-%s",
  1783. dbfile, old_suffix);
  1784. #endif
  1785. #ifdef RL_DEBUG
  1786. BIO_printf(bio_err, "DEBUG: renaming \"%s\" to \"%s\"\n",
  1787. dbfile, buf[1]);
  1788. #endif
  1789. if (rename(dbfile,buf[1]) < 0 && errno != ENOENT
  1790. #ifdef ENOTDIR
  1791. && errno != ENOTDIR
  1792. #endif
  1793. ) {
  1794. BIO_printf(bio_err,
  1795. "unable to rename %s to %s\n",
  1796. dbfile, buf[1]);
  1797. perror("reason");
  1798. goto err;
  1799. }
  1800. #ifdef RL_DEBUG
  1801. BIO_printf(bio_err, "DEBUG: renaming \"%s\" to \"%s\"\n",
  1802. buf[0],dbfile);
  1803. #endif
  1804. if (rename(buf[0],dbfile) < 0)
  1805. {
  1806. BIO_printf(bio_err,
  1807. "unable to rename %s to %s\n",
  1808. buf[0],dbfile);
  1809. perror("reason");
  1810. rename(buf[1],dbfile);
  1811. goto err;
  1812. }
  1813. #ifdef RL_DEBUG
  1814. BIO_printf(bio_err, "DEBUG: renaming \"%s\" to \"%s\"\n",
  1815. buf[4],buf[3]);
  1816. #endif
  1817. if (rename(buf[4],buf[3]) < 0 && errno != ENOENT
  1818. #ifdef ENOTDIR
  1819. && errno != ENOTDIR
  1820. #endif
  1821. ) {
  1822. BIO_printf(bio_err,
  1823. "unable to rename %s to %s\n",
  1824. buf[4], buf[3]);
  1825. perror("reason");
  1826. rename(dbfile,buf[0]);
  1827. rename(buf[1],dbfile);
  1828. goto err;
  1829. }
  1830. #ifdef RL_DEBUG
  1831. BIO_printf(bio_err, "DEBUG: renaming \"%s\" to \"%s\"\n",
  1832. buf[2],buf[4]);
  1833. #endif
  1834. if (rename(buf[2],buf[4]) < 0)
  1835. {
  1836. BIO_printf(bio_err,
  1837. "unable to rename %s to %s\n",
  1838. buf[2],buf[4]);
  1839. perror("reason");
  1840. rename(buf[3],buf[4]);
  1841. rename(dbfile,buf[0]);
  1842. rename(buf[1],dbfile);
  1843. goto err;
  1844. }
  1845. return 1;
  1846. err:
  1847. return 0;
  1848. }
  1849. void free_index(CA_DB *db)
  1850. {
  1851. if (db)
  1852. {
  1853. if (db->db) TXT_DB_free(db->db);
  1854. OPENSSL_free(db);
  1855. }
  1856. }
  1857. int parse_yesno(const char *str, int def)
  1858. {
  1859. int ret = def;
  1860. if (str)
  1861. {
  1862. switch (*str)
  1863. {
  1864. case 'f': /* false */
  1865. case 'F': /* FALSE */
  1866. case 'n': /* no */
  1867. case 'N': /* NO */
  1868. case '0': /* 0 */
  1869. ret = 0;
  1870. break;
  1871. case 't': /* true */
  1872. case 'T': /* TRUE */
  1873. case 'y': /* yes */
  1874. case 'Y': /* YES */
  1875. case '1': /* 1 */
  1876. ret = 0;
  1877. break;
  1878. default:
  1879. ret = def;
  1880. break;
  1881. }
  1882. }
  1883. return ret;
  1884. }
  1885. /*
  1886. * subject is expected to be in the format /type0=value0/type1=value1/type2=...
  1887. * where characters may be escaped by \
  1888. */
  1889. X509_NAME *parse_name(char *subject, long chtype, int multirdn)
  1890. {
  1891. size_t buflen = strlen(subject)+1; /* to copy the types and values into. due to escaping, the copy can only become shorter */
  1892. char *buf = OPENSSL_malloc(buflen);
  1893. size_t max_ne = buflen / 2 + 1; /* maximum number of name elements */
  1894. char **ne_types = OPENSSL_malloc(max_ne * sizeof (char *));
  1895. char **ne_values = OPENSSL_malloc(max_ne * sizeof (char *));
  1896. int *mval = OPENSSL_malloc (max_ne * sizeof (int));
  1897. char *sp = subject, *bp = buf;
  1898. int i, ne_num = 0;
  1899. X509_NAME *n = NULL;
  1900. int nid;
  1901. if (!buf || !ne_types || !ne_values)
  1902. {
  1903. BIO_printf(bio_err, "malloc error\n");
  1904. goto error;
  1905. }
  1906. if (*subject != '/')
  1907. {
  1908. BIO_printf(bio_err, "Subject does not start with '/'.\n");
  1909. goto error;
  1910. }
  1911. sp++; /* skip leading / */
  1912. /* no multivalued RDN by default */
  1913. mval[ne_num] = 0;
  1914. while (*sp)
  1915. {
  1916. /* collect type */
  1917. ne_types[ne_num] = bp;
  1918. while (*sp)
  1919. {
  1920. if (*sp == '\\') /* is there anything to escape in the type...? */
  1921. {
  1922. if (*++sp)
  1923. *bp++ = *sp++;
  1924. else
  1925. {
  1926. BIO_printf(bio_err, "escape character at end of string\n");
  1927. goto error;
  1928. }
  1929. }
  1930. else if (*sp == '=')
  1931. {
  1932. sp++;
  1933. *bp++ = '\0';
  1934. break;
  1935. }
  1936. else
  1937. *bp++ = *sp++;
  1938. }
  1939. if (!*sp)
  1940. {
  1941. BIO_printf(bio_err, "end of string encountered while processing type of subject name element #%d\n", ne_num);
  1942. goto error;
  1943. }
  1944. ne_values[ne_num] = bp;
  1945. while (*sp)
  1946. {
  1947. if (*sp == '\\')
  1948. {
  1949. if (*++sp)
  1950. *bp++ = *sp++;
  1951. else
  1952. {
  1953. BIO_printf(bio_err, "escape character at end of string\n");
  1954. goto error;
  1955. }
  1956. }
  1957. else if (*sp == '/')
  1958. {
  1959. sp++;
  1960. /* no multivalued RDN by default */
  1961. mval[ne_num+1] = 0;
  1962. break;
  1963. }
  1964. else if (*sp == '+' && multirdn)
  1965. {
  1966. /* a not escaped + signals a mutlivalued RDN */
  1967. sp++;
  1968. mval[ne_num+1] = -1;
  1969. break;
  1970. }
  1971. else
  1972. *bp++ = *sp++;
  1973. }
  1974. *bp++ = '\0';
  1975. ne_num++;
  1976. }
  1977. if (!(n = X509_NAME_new()))
  1978. goto error;
  1979. for (i = 0; i < ne_num; i++)
  1980. {
  1981. if ((nid=OBJ_txt2nid(ne_types[i])) == NID_undef)
  1982. {
  1983. BIO_printf(bio_err, "Subject Attribute %s has no known NID, skipped\n", ne_types[i]);
  1984. continue;
  1985. }
  1986. if (!*ne_values[i])
  1987. {
  1988. BIO_printf(bio_err, "No value provided for Subject Attribute %s, skipped\n", ne_types[i]);
  1989. continue;
  1990. }
  1991. if (!X509_NAME_add_entry_by_NID(n, nid, chtype, (unsigned char*)ne_values[i], -1,-1,mval[i]))
  1992. goto error;
  1993. }
  1994. OPENSSL_free(ne_values);
  1995. OPENSSL_free(ne_types);
  1996. OPENSSL_free(buf);
  1997. return n;
  1998. error:
  1999. X509_NAME_free(n);
  2000. if (ne_values)
  2001. OPENSSL_free(ne_values);
  2002. if (ne_types)
  2003. OPENSSL_free(ne_types);
  2004. if (buf)
  2005. OPENSSL_free(buf);
  2006. return NULL;
  2007. }
  2008. int args_verify(char ***pargs, int *pargc,
  2009. int *badarg, BIO *err, X509_VERIFY_PARAM **pm)
  2010. {
  2011. ASN1_OBJECT *otmp = NULL;
  2012. unsigned long flags = 0;
  2013. int i;
  2014. int purpose = 0;
  2015. char **oldargs = *pargs;
  2016. char *arg = **pargs, *argn = (*pargs)[1];
  2017. if (!strcmp(arg, "-policy"))
  2018. {
  2019. if (!argn)
  2020. *badarg = 1;
  2021. else
  2022. {
  2023. otmp = OBJ_txt2obj(argn, 0);
  2024. if (!otmp)
  2025. {
  2026. BIO_printf(err, "Invalid Policy \"%s\"\n",
  2027. argn);
  2028. *badarg = 1;
  2029. }
  2030. }
  2031. (*pargs)++;
  2032. }
  2033. else if (strcmp(arg,"-purpose") == 0)
  2034. {
  2035. X509_PURPOSE *xptmp;
  2036. if (!argn)
  2037. *badarg = 1;
  2038. else
  2039. {
  2040. i = X509_PURPOSE_get_by_sname(argn);
  2041. if(i < 0)
  2042. {
  2043. BIO_printf(err, "unrecognized purpose\n");
  2044. *badarg = 1;
  2045. }
  2046. else
  2047. {
  2048. xptmp = X509_PURPOSE_get0(i);
  2049. purpose = X509_PURPOSE_get_id(xptmp);
  2050. }
  2051. }
  2052. (*pargs)++;
  2053. }
  2054. else if (!strcmp(arg, "-ignore_critical"))
  2055. flags |= X509_V_FLAG_IGNORE_CRITICAL;
  2056. else if (!strcmp(arg, "-issuer_checks"))
  2057. flags |= X509_V_FLAG_CB_ISSUER_CHECK;
  2058. else if (!strcmp(arg, "-crl_check"))
  2059. flags |= X509_V_FLAG_CRL_CHECK;
  2060. else if (!strcmp(arg, "-crl_check_all"))
  2061. flags |= X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL;
  2062. else if (!strcmp(arg, "-policy_check"))
  2063. flags |= X509_V_FLAG_POLICY_CHECK;
  2064. else if (!strcmp(arg, "-explicit_policy"))
  2065. flags |= X509_V_FLAG_EXPLICIT_POLICY;
  2066. else if (!strcmp(arg, "-x509_strict"))
  2067. flags |= X509_V_FLAG_X509_STRICT;
  2068. else if (!strcmp(arg, "-policy_print"))
  2069. flags |= X509_V_FLAG_NOTIFY_POLICY;
  2070. else
  2071. return 0;
  2072. if (*badarg)
  2073. {
  2074. if (*pm)
  2075. X509_VERIFY_PARAM_free(*pm);
  2076. *pm = NULL;
  2077. goto end;
  2078. }
  2079. if (!*pm && !(*pm = X509_VERIFY_PARAM_new()))
  2080. {
  2081. *badarg = 1;
  2082. goto end;
  2083. }
  2084. if (otmp)
  2085. X509_VERIFY_PARAM_add0_policy(*pm, otmp);
  2086. if (flags)
  2087. X509_VERIFY_PARAM_set_flags(*pm, flags);
  2088. if (purpose)
  2089. X509_VERIFY_PARAM_set_purpose(*pm, purpose);
  2090. end:
  2091. (*pargs)++;
  2092. if (pargc)
  2093. *pargc -= *pargs - oldargs;
  2094. return 1;
  2095. }
  2096. /* Read whole contents of a BIO into an allocated memory buffer and
  2097. * return it.
  2098. */
  2099. int bio_to_mem(unsigned char **out, int maxlen, BIO *in)
  2100. {
  2101. BIO *mem;
  2102. int len, ret;
  2103. unsigned char tbuf[1024];
  2104. mem = BIO_new(BIO_s_mem());
  2105. if (!mem)
  2106. return -1;
  2107. for(;;)
  2108. {
  2109. if ((maxlen != -1) && maxlen < 1024)
  2110. len = maxlen;
  2111. else
  2112. len = 1024;
  2113. len = BIO_read(in, tbuf, len);
  2114. if (len <= 0)
  2115. break;
  2116. if (BIO_write(mem, tbuf, len) != len)
  2117. {
  2118. BIO_free(mem);
  2119. return -1;
  2120. }
  2121. maxlen -= len;
  2122. if (maxlen == 0)
  2123. break;
  2124. }
  2125. ret = BIO_get_mem_data(mem, (char **)out);
  2126. BIO_set_flags(mem, BIO_FLAGS_MEM_RDONLY);
  2127. BIO_free(mem);
  2128. return ret;
  2129. }
  2130. int pkey_ctrl_string(EVP_PKEY_CTX *ctx, char *value)
  2131. {
  2132. int rv;
  2133. char *stmp, *vtmp = NULL;
  2134. stmp = BUF_strdup(value);
  2135. if (!stmp)
  2136. return -1;
  2137. vtmp = strchr(stmp, ':');
  2138. if (vtmp)
  2139. {
  2140. *vtmp = 0;
  2141. vtmp++;
  2142. }
  2143. rv = EVP_PKEY_CTX_ctrl_str(ctx, stmp, vtmp);
  2144. OPENSSL_free(stmp);
  2145. return rv;
  2146. }
  2147. static void nodes_print(BIO *out, const char *name,
  2148. STACK_OF(X509_POLICY_NODE) *nodes)
  2149. {
  2150. X509_POLICY_NODE *node;
  2151. int i;
  2152. BIO_printf(out, "%s Policies:", name);
  2153. if (nodes)
  2154. {
  2155. BIO_puts(out, "\n");
  2156. for (i = 0; i < sk_X509_POLICY_NODE_num(nodes); i++)
  2157. {
  2158. node = sk_X509_POLICY_NODE_value(nodes, i);
  2159. X509_POLICY_NODE_print(out, node, 2);
  2160. }
  2161. }
  2162. else
  2163. BIO_puts(out, " <empty>\n");
  2164. }
  2165. void policies_print(BIO *out, X509_STORE_CTX *ctx)
  2166. {
  2167. X509_POLICY_TREE *tree;
  2168. int explicit_policy;
  2169. int free_out = 0;
  2170. if (out == NULL)
  2171. {
  2172. out = BIO_new_fp(stderr, BIO_NOCLOSE);
  2173. free_out = 1;
  2174. }
  2175. tree = X509_STORE_CTX_get0_policy_tree(ctx);
  2176. explicit_policy = X509_STORE_CTX_get_explicit_policy(ctx);
  2177. BIO_printf(out, "Require explicit Policy: %s\n",
  2178. explicit_policy ? "True" : "False");
  2179. nodes_print(out, "Authority", X509_policy_tree_get0_policies(tree));
  2180. nodes_print(out, "User", X509_policy_tree_get0_user_policies(tree));
  2181. if (free_out)
  2182. BIO_free(out);
  2183. }
  2184. /*
  2185. * Platform-specific sections
  2186. */
  2187. #if defined(_WIN32)
  2188. # ifdef fileno
  2189. # undef fileno
  2190. # define fileno(a) (int)_fileno(a)
  2191. # endif
  2192. # include <windows.h>
  2193. # include <tchar.h>
  2194. static int WIN32_rename(const char *from, const char *to)
  2195. {
  2196. TCHAR *tfrom=NULL,*tto;
  2197. DWORD err;
  2198. int ret=0;
  2199. if (sizeof(TCHAR) == 1)
  2200. {
  2201. tfrom = (TCHAR *)from;
  2202. tto = (TCHAR *)to;
  2203. }
  2204. else /* UNICODE path */
  2205. {
  2206. size_t i,flen=strlen(from)+1,tlen=strlen(to)+1;
  2207. tfrom = (TCHAR *)malloc(sizeof(TCHAR)*(flen+tlen));
  2208. if (tfrom==NULL) goto err;
  2209. tto=tfrom+flen;
  2210. #if !defined(_WIN32_WCE) || _WIN32_WCE>=101
  2211. if (!MultiByteToWideChar(CP_ACP,0,from,flen,(WCHAR *)tfrom,flen))
  2212. #endif
  2213. for (i=0;i<flen;i++) tfrom[i]=(TCHAR)from[i];
  2214. #if !defined(_WIN32_WCE) || _WIN32_WCE>=101
  2215. if (!MultiByteToWideChar(CP_ACP,0,to, tlen,(WCHAR *)tto, tlen))
  2216. #endif
  2217. for (i=0;i<tlen;i++) tto[i] =(TCHAR)to[i];
  2218. }
  2219. if (MoveFile(tfrom,tto)) goto ok;
  2220. err=GetLastError();
  2221. if (err==ERROR_ALREADY_EXISTS || err==ERROR_FILE_EXISTS)
  2222. {
  2223. if (DeleteFile(tto) && MoveFile(tfrom,tto))
  2224. goto ok;
  2225. err=GetLastError();
  2226. }
  2227. if (err==ERROR_FILE_NOT_FOUND || err==ERROR_PATH_NOT_FOUND)
  2228. errno = ENOENT;
  2229. else if (err==ERROR_ACCESS_DENIED)
  2230. errno = EACCES;
  2231. else
  2232. errno = EINVAL; /* we could map more codes... */
  2233. err:
  2234. ret=-1;
  2235. ok:
  2236. if (tfrom!=NULL && tfrom!=(TCHAR *)from) free(tfrom);
  2237. return ret;
  2238. }
  2239. #endif
  2240. /* app_tminterval section */
  2241. #if defined(_WIN32)
  2242. double app_tminterval(int stop,int usertime)
  2243. {
  2244. FILETIME now;
  2245. double ret=0;
  2246. static ULARGE_INTEGER tmstart;
  2247. static int warning=1;
  2248. #ifdef _WIN32_WINNT
  2249. static HANDLE proc=NULL;
  2250. if (proc==NULL)
  2251. {
  2252. if (GetVersion() < 0x80000000)
  2253. proc = OpenProcess(PROCESS_QUERY_INFORMATION,FALSE,
  2254. GetCurrentProcessId());
  2255. if (proc==NULL) proc = (HANDLE)-1;
  2256. }
  2257. if (usertime && proc!=(HANDLE)-1)
  2258. {
  2259. FILETIME junk;
  2260. GetProcessTimes(proc,&junk,&junk,&junk,&now);
  2261. }
  2262. else
  2263. #endif
  2264. {
  2265. SYSTEMTIME systime;
  2266. if (usertime && warning)
  2267. {
  2268. BIO_printf(bio_err,"To get meaningful results, run "
  2269. "this program on idle system.\n");
  2270. warning=0;
  2271. }
  2272. GetSystemTime(&systime);
  2273. SystemTimeToFileTime(&systime,&now);
  2274. }
  2275. if (stop==TM_START)
  2276. {
  2277. tmstart.u.LowPart = now.dwLowDateTime;
  2278. tmstart.u.HighPart = now.dwHighDateTime;
  2279. }
  2280. else {
  2281. ULARGE_INTEGER tmstop;
  2282. tmstop.u.LowPart = now.dwLowDateTime;
  2283. tmstop.u.HighPart = now.dwHighDateTime;
  2284. ret = (__int64)(tmstop.QuadPart - tmstart.QuadPart)*1e-7;
  2285. }
  2286. return (ret);
  2287. }
  2288. #elif defined(OPENSSL_SYSTEM_NETWARE)
  2289. #include <time.h>
  2290. double app_tminterval(int stop,int usertime)
  2291. {
  2292. double ret=0;
  2293. static clock_t tmstart;
  2294. static int warning=1;
  2295. if (usertime && warning)
  2296. {
  2297. BIO_printf(bio_err,"To get meaningful results, run "
  2298. "this program on idle system.\n");
  2299. warning=0;
  2300. }
  2301. if (stop==TM_START) tmstart = clock();
  2302. else ret = (clock()-tmstart)/(double)CLOCKS_PER_SEC;
  2303. return (ret);
  2304. }
  2305. #elif defined(OPENSSL_SYSTEM_VXWORKS)
  2306. #include <time.h>
  2307. double app_tminterval(int stop,int usertime)
  2308. {
  2309. double ret=0;
  2310. #ifdef CLOCK_REALTIME
  2311. static struct timespec tmstart;
  2312. struct timespec now;
  2313. #else
  2314. static unsigned long tmstart;
  2315. unsigned long now;
  2316. #endif
  2317. static int warning=1;
  2318. if (usertime && warning)
  2319. {
  2320. BIO_printf(bio_err,"To get meaningful results, run "
  2321. "this program on idle system.\n");
  2322. warning=0;
  2323. }
  2324. #ifdef CLOCK_REALTIME
  2325. clock_gettime(CLOCK_REALTIME,&now);
  2326. if (stop==TM_START) tmstart = now;
  2327. else ret = ( (now.tv_sec+now.tv_nsec*1e-9)
  2328. - (tmstart.tv_sec+tmstart.tv_nsec*1e-9) );
  2329. #else
  2330. now = tickGet();
  2331. if (stop==TM_START) tmstart = now;
  2332. else ret = (now - tmstart)/(double)sysClkRateGet();
  2333. #endif
  2334. return (ret);
  2335. }
  2336. #elif defined(OPENSSL_SYSTEM_VMS)
  2337. #include <time.h>
  2338. #include <times.h>
  2339. double app_tminterval(int stop,int usertime)
  2340. {
  2341. static clock_t tmstart;
  2342. double ret = 0;
  2343. clock_t now;
  2344. #ifdef __TMS
  2345. struct tms rus;
  2346. now = times(&rus);
  2347. if (usertime) now = rus.tms_utime;
  2348. #else
  2349. if (usertime)
  2350. now = clock(); /* sum of user and kernel times */
  2351. else {
  2352. struct timeval tv;
  2353. gettimeofday(&tv,NULL);
  2354. now = (clock_t)(
  2355. (unsigned long long)tv.tv_sec*CLK_TCK +
  2356. (unsigned long long)tv.tv_usec*(1000000/CLK_TCK)
  2357. );
  2358. }
  2359. #endif
  2360. if (stop==TM_START) tmstart = now;
  2361. else ret = (now - tmstart)/(double)(CLK_TCK);
  2362. return (ret);
  2363. }
  2364. #elif defined(_SC_CLK_TCK) /* by means of unistd.h */
  2365. #include <sys/times.h>
  2366. double app_tminterval(int stop,int usertime)
  2367. {
  2368. double ret = 0;
  2369. struct tms rus;
  2370. clock_t now = times(&rus);
  2371. static clock_t tmstart;
  2372. if (usertime) now = rus.tms_utime;
  2373. if (stop==TM_START) tmstart = now;
  2374. else ret = (now - tmstart)/(double)sysconf(_SC_CLK_TCK);
  2375. return (ret);
  2376. }
  2377. #else
  2378. #include <sys/time.h>
  2379. #include <sys/resource.h>
  2380. double app_tminterval(int stop,int usertime)
  2381. {
  2382. double ret = 0;
  2383. struct rusage rus;
  2384. struct timeval now;
  2385. static struct timeval tmstart;
  2386. if (usertime) getrusage(RUSAGE_SELF,&rus), now = rus.ru_time;
  2387. else gettimeofday(&now,NULL);
  2388. if (stop==TM_START) tmstart = now;
  2389. else ret = ( (now.tv_sec+now.tv_usec*1e-6)
  2390. - (tmstart.tv_sec+tmstart.tv_usec*1e-6) );
  2391. return ret;
  2392. }
  2393. #endif
  2394. /* app_isdir section */
  2395. #ifdef _WIN32
  2396. int app_isdir(const char *name)
  2397. {
  2398. HANDLE hList;
  2399. WIN32_FIND_DATA FileData;
  2400. #if defined(UNICODE) || defined(_UNICODE)
  2401. size_t i, len_0 = strlen(name)+1;
  2402. if (len_0 > sizeof(FileData.cFileName)/sizeof(FileData.cFileName[0]))
  2403. return -1;
  2404. #if !defined(_WIN32_WCE) || _WIN32_WCE>=101
  2405. if (!MultiByteToWideChar(CP_ACP,0,name,len_0,FileData.cFileName,len_0))
  2406. #endif
  2407. for (i=0;i<len_0;i++)
  2408. FileData.cFileName[i] = (WCHAR)name[i];
  2409. hList = FindFirstFile(FileData.cFileName,&FileData);
  2410. #else
  2411. hList = FindFirstFile(name,&FileData);
  2412. #endif
  2413. if (hList == INVALID_HANDLE_VALUE) return -1;
  2414. FindClose(hList);
  2415. return ((FileData.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY)!=0);
  2416. }
  2417. #else
  2418. #include <sys/stat.h>
  2419. #ifndef S_ISDIR
  2420. # if defined(_S_IFMT) && defined(_S_IFDIR)
  2421. # define S_ISDIR(a) (((a) & _S_IFMT) == _S_IFDIR)
  2422. # else
  2423. # define S_ISDIR(a) (((a) & S_IFMT) == S_IFDIR)
  2424. # endif
  2425. #endif
  2426. int app_isdir(const char *name)
  2427. {
  2428. #if defined(S_ISDIR)
  2429. struct stat st;
  2430. if (stat(name,&st)==0) return S_ISDIR(st.st_mode);
  2431. else return -1;
  2432. #else
  2433. return -1;
  2434. #endif
  2435. }
  2436. #endif
  2437. /* raw_read|write section */
  2438. #if defined(_WIN32) && defined(STD_INPUT_HANDLE)
  2439. int raw_read_stdin(void *buf,int siz)
  2440. {
  2441. DWORD n;
  2442. if (ReadFile(GetStdHandle(STD_INPUT_HANDLE),buf,siz,&n,NULL))
  2443. return (n);
  2444. else return (-1);
  2445. }
  2446. #else
  2447. int raw_read_stdin(void *buf,int siz)
  2448. { return read(fileno(stdin),buf,siz); }
  2449. #endif
  2450. #if defined(_WIN32) && defined(STD_OUTPUT_HANDLE)
  2451. int raw_write_stdout(const void *buf,int siz)
  2452. {
  2453. DWORD n;
  2454. if (WriteFile(GetStdHandle(STD_OUTPUT_HANDLE),buf,siz,&n,NULL))
  2455. return (n);
  2456. else return (-1);
  2457. }
  2458. #else
  2459. int raw_write_stdout(const void *buf,int siz)
  2460. { return write(fileno(stdout),buf,siz); }
  2461. #endif