csp.patch.cvs 45 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815
  1. Unreleased changes from upstream author CVS
  2. http://devel.it.su.se/cgi-bin/local/cvsweb.cgi/CSP/
  3. Index: CSP.pm
  4. --- CSP.pm.orig 2002-09-24 20:33:20 +0200
  5. +++ CSP.pm 2005-05-06 21:42:11 +0200
  6. @@ -8,6 +8,7 @@
  7. use IO::File;
  8. use Term::Prompt;
  9. use POSIX qw(strftime);
  10. +use Date::Calc qw(Day_of_Week Gmtime Add_Delta_Days Add_Delta_DHMS);
  11. @ISA = qw(Exporter AutoLoader);
  12. # Items to export into callers namespace by default. Note: do not export
  13. @@ -15,7 +16,7 @@
  14. # Do not simply export all your public functions/methods/constants.
  15. @EXPORT = qw();
  16. @EXPORT_OK = qw($_openssl);
  17. -$VERSION = '0.26';
  18. +$VERSION = '0.29';
  19. # Preloaded methods go here.
  20. @@ -49,7 +50,7 @@
  21. my $me = bless { dir=>$dir,name=>$name },$class;
  22. open ALIASES,"$dir/etc/aliases.txt";
  23. - while (<ALIASES>)
  24. + while (<ALIASES>)
  25. {
  26. chomp;
  27. next unless /\s*([^:]+)\s*:\s*([^:]+)\s*/;
  28. @@ -58,6 +59,8 @@
  29. }
  30. close ALIASES;
  31. + $me->{openssl} = CSP::OpenSSL->new($me);
  32. +
  33. $me;
  34. }
  35. @@ -158,7 +161,7 @@
  36. $self->mppFile($cf,$vars,$1),last SWITCH if /^%include\s+(.+)/;
  37. - $cf->print(&_rewrite($vars,$_));
  38. + print $cf &_rewrite($vars,$_);
  39. }
  40. }
  41. close IN;
  42. @@ -168,11 +171,11 @@
  43. {
  44. my $self = shift;
  45. my $cmd = shift;
  46. - my $vars = shift;
  47. + my $args = shift;
  48. my $cadir = "$self->{dir}/csp/$self->{name}";
  49. - $ENV{TMPDIR} = '/tmp' unless exists $ENV{TMPDIR};
  50. + $ENV{TMPDIR} ||= ("$self->{dir}/tmp" || '/tmp');
  51. my $cff = $self->tempFile("csp","conf");
  52. my $cf = IO::File->new();
  53. eval
  54. @@ -187,15 +190,30 @@
  55. \#\# by hand. Please see the CSP-documentation for details.
  56. \#\# $date
  57. +openssl_conf = openssl_init
  58. +
  59. +[openssl_init]
  60. +engines = engine_section
  61. +oid_section = oids
  62. +
  63. +[engine_section]
  64. +EOW
  65. +
  66. + $ENV{CSP_OPENSC} && $cf->print(<<EOW);
  67. +opensc = opensc_section
  68. +
  69. +[opensc_section]
  70. +dynamic_path = $ENV{CSP_OPENSC}/lib/opensc/engine_opensc.so
  71. +
  72. EOW
  73. ## Default section
  74. - $cf->print("\noid_section = oids\n\n[ oids ]\n");
  75. + $cf->print("[ oids ]\n");
  76. $self->addFile($cf,"$self->{dir}/etc/oids.conf");
  77. $cf->print("\n[ csp ]\n\n");
  78. my ($k,$v);
  79. - while (($k,$v) = each %{$vars})
  80. + while (($k,$v) = each %{$args})
  81. {
  82. $cf->print("$k\t= $v\n") if ($k ne 'keypass' && $k ne 'capass');
  83. }
  84. @@ -209,9 +227,9 @@
  85. [ ca ]
  86. default_ca = $self->{name}
  87. -
  88. +
  89. [ $self->{name} ]
  90. -
  91. +
  92. dir = \${csp::home}/csp/\${csp::ca}
  93. certs = \$dir/certs
  94. database = \$dir/index.txt
  95. @@ -228,7 +246,7 @@
  96. policy = policy
  97. [ req ]
  98. -
  99. +
  100. default_bits = \${csp::keysize}
  101. default_keyfile = privkey.pem
  102. distinguished_name = req_dn
  103. @@ -241,15 +259,15 @@
  104. ## Extension based on command
  105. - my $type = $vars->{type};
  106. + my $type = $args->{type};
  107. my $name = $self->{name};
  108. - if ($cmd eq 'x509' || $cmd eq 'req' || $cmd eq 'ca')
  109. + if ($cmd eq 'x509' || $cmd eq 'req' || $cmd eq 'ca')
  110. {
  111. - $self->die("missing \"type\" parameter")
  112. + $self->die("missing \"type\" parameter")
  113. unless $type;
  114. $cf->print("[ policy ]\n\n");
  115. - foreach my $attr (keys %{$vars->{name_attributes}})
  116. + foreach my $attr (keys %{$args->{name_attributes}})
  117. {
  118. next unless $attr;
  119. if ($self->{aname}->{lc($attr)})
  120. @@ -261,43 +279,43 @@
  121. $cf->print("$attr = optional\n");
  122. }
  123. }
  124. -
  125. +
  126. ## Define a few CPP/MPP-style variables and run the prototype file
  127. - $vars->{uc("type_$type")}++;
  128. - foreach my $x (qw(email url ip dns))
  129. + $args->{uc("type_$type")}++;
  130. + foreach my $x (qw(email url ip dns))
  131. {
  132. - $vars->{uc($x)} = $vars->{$x};
  133. + $args->{uc($x)} = $args->{$x};
  134. }
  135. $cf->print("\n\n");
  136. - if ($name)
  137. + if ($name)
  138. {
  139. my $econf = "$self->{dir}/csp/$name/extensions.conf";
  140. $econf = "$self->{dir}/etc/extensions.conf" unless -f $econf;
  141. - $self->mppFile($cf,$vars,$econf);
  142. + $self->mppFile($cf,$args,$econf);
  143. }
  144. $cf->print("\n\n");
  145. - if ($name)
  146. + if ($name)
  147. {
  148. my $econf = "$self->{dir}/csp/$name/crl_extensions.conf";
  149. $econf = "$self->{dir}/etc/crl_extensions.conf" unless -f $econf;
  150. - $self->mppFile($cf,$vars,$econf);
  151. + $self->mppFile($cf,$args,$econf);
  152. }
  153. $cf->print("\n");
  154. }
  155. - my $dn = $vars->{dn};
  156. - if ($dn)
  157. + my $dn = $args->{dn};
  158. + if ($dn)
  159. {
  160. my %acount;
  161. -
  162. +
  163. $cf->print("[ req_dn ]\n\n");
  164. foreach my $rdn (split /\s*,\s*/,$dn)
  165. {
  166. next unless $rdn =~ /^([^=]+)\s*=\s*([^=]+)$/;
  167. my $n = exists $self->{aname}->{lc($1)} ? $self->{aname}->{lc($1)} : $1;
  168. - $vars->{_nrdn}++; ## At the end of the run _nrdn contains the
  169. + $args->{_nrdn}++; ## At the end of the run _nrdn contains the
  170. ## number of newlines to send to openssl.
  171. my $pos = $acount{$n}++;
  172. $cf->print($pos.".${n}\t\t= $2\n");
  173. @@ -307,13 +325,13 @@
  174. $cf->close;
  175. };
  176. - if ($@)
  177. + if ($@)
  178. {
  179. $cf->close;
  180. #unlink $cff; ## uncomment when debugging
  181. $self->die($@);
  182. }
  183. -
  184. +
  185. return $cff;
  186. }
  187. @@ -321,7 +339,7 @@
  188. {
  189. my $self = shift;
  190. my $dir = $self->caDir();
  191. -
  192. +
  193. mkdir $dir,00755;
  194. mkdir "$dir/certs",00755;
  195. open SERIAL,">$dir/serial";
  196. @@ -329,7 +347,7 @@
  197. close SERIAL;
  198. mkdir "$dir/tmp",00700;
  199. system('touch',"$dir/index.txt");
  200. -
  201. +
  202. mkdir "$dir/private",00700;
  203. mkdir "$dir/private/keys",00700;
  204. system('cp','-p',"$self->{dir}/etc/extensions.conf","$dir/extensions.conf");
  205. @@ -337,12 +355,12 @@
  206. system('cp','-rp',"$self->{dir}/etc/public_html","$dir/");
  207. }
  208. -sub caDir
  209. +sub caDir
  210. {
  211. my $self = shift;
  212. my $name = $self->{name};
  213. $self->die("CA Name not set") unless $name;
  214. -
  215. +
  216. "$self->{dir}/csp/$self->{name}";
  217. }
  218. @@ -360,9 +378,9 @@
  219. my $self = shift;
  220. my $comment = shift;
  221. my $reenter = shift;
  222. -
  223. +
  224. my ($pw,$pwr);
  225. -
  226. +
  227. system("stty -echo") &&
  228. $self->die("Unable to configure tty for password entry");
  229. @@ -370,22 +388,22 @@
  230. chop($pw = <STDIN>);
  231. print STDERR "\n";
  232. - if ($reenter)
  233. + if ($reenter)
  234. {
  235. $pwr = $self->getPassword("Re-enter $comment");
  236. }
  237. - else
  238. + else
  239. {
  240. $pwr = $pw;
  241. }
  242. -
  243. +
  244. system("stty echo") &&
  245. $self->die("Unable to configure tty for password entry");
  246. -
  247. +
  248. $self->die("Passwords do not match")
  249. unless $pw eq $pwr;
  250. - $self->die("Zero-length password")
  251. + return undef
  252. if length($pw) == 0;
  253. $pw;
  254. @@ -398,17 +416,14 @@
  255. $self->die("Required parameter keyfile missing")
  256. unless $args->{keyfile};
  257. -
  258. +
  259. $args->{keysize} = 1024 unless $args->{keysize} > 0;
  260. - $args->{keypass} = $self->getPassword("Private key password",1);
  261. -
  262. - my $process =
  263. - CSP::OpenSSL->new($self,
  264. - 'genrsa',
  265. - "-des3 -passout stdin -out $args->{keyfile} $args->{keysize}",$args);
  266. -
  267. - $process->print($args->{keypass});
  268. - $process->closeok();
  269. + $args->{keypass} = $self->getPassword("Private key password",1)
  270. + unless $args->{keypass};
  271. +
  272. + my $cmd = "-out $args->{keyfile} $args->{keysize}";
  273. + $cmd = "-des3 -passout pass:$args->{keypass} ".$cmd if defined($args->{keypass});
  274. + $self->{openssl}->cmd('genrsa',$cmd,$args);
  275. }
  276. sub create
  277. @@ -417,35 +432,35 @@
  278. my $args = shift;
  279. $self->createFiles();
  280. - $self->warn("Successfully created CA $self->{name}")
  281. - unless $args->{verobse} > 1;
  282. + $self->warn("Successfully created CA $self->{name}")
  283. + if $args->{verbose};
  284. }
  285. sub delete
  286. {
  287. my $self = shift;
  288. my $args = shift;
  289. -
  290. +
  291. my $dir = $self->caDir();
  292. system('rm','-rf',$dir);
  293. - $self->warn("Successfully deleted CA $self->{name}")
  294. - unless $args->{verbose} > 1;
  295. + $self->warn("Successfully deleted CA $self->{name}")
  296. + if $args->{verbose};
  297. }
  298. sub init
  299. {
  300. my $self = shift;
  301. my $args = shift;
  302. -
  303. +
  304. my $dir = $self->caDir();
  305. - $self->create($args) unless -d $dir;
  306. -
  307. + $self->die("You must create the CA before it can be initialized") unless -d $dir;
  308. +
  309. if ($args->{crtfile})
  310. {
  311. system('cp',$args->{crtfile},"$dir/ca.crt");
  312. - $self->warn("Successfully initialized CA $self->{name}")
  313. - unless $args->{verbose} > 1;
  314. + $self->warn("Successfully initialized CA $self->{name}")
  315. + if $args->{verbose};
  316. }
  317. else
  318. {
  319. @@ -458,38 +473,38 @@
  320. my $cakey = "$dir/private/ca.key";
  321. my $cacert = "$dir/ca.crt";
  322. - ## Generate the CA key
  323. - $self->warn("Generating CA key")
  324. - unless $args->{verbose} > 1;
  325. - $args->{keyfile} = $cakey;
  326. - $self->genkey($args) or
  327. - $self->die("Unable to generate CA key in $cakey");
  328. + unless (-f $args->{keyfile})
  329. + {
  330. + ## Generate the CA key
  331. + $self->warn("Generating CA key")
  332. + if $args->{verbose};
  333. + $args->{keyfile} = $cakey;
  334. + defined $self->genkey($args) or
  335. + $self->die("Unable to generate CA key in $cakey");
  336. + $self->die("CA key must have a password")
  337. + unless defined($args->{keypass});
  338. + }
  339. $args->{capass} = $args->{keypass};
  340. ## Generate and optionally self-sign the request
  341. my $process;
  342. my $what;
  343. - my $common_args = "-$args->{digest} -days $args->{days} -key $cakey -passin stdin";
  344. + my $common_args = "-$args->{digest} -days $args->{days} ".
  345. + " -key $cakey -passin pass:$args->{keypass}";
  346. if ($args->{csrfile})
  347. {
  348. - $process =
  349. - $self->req("-new $common_args -out $args->{csrfile}",$args);
  350. - $process->print("$args->{keypass}\n");
  351. - $process->closeok();
  352. + $self->{openssl}->cmd('req',"-new $common_args -out $args->{csrfile}",$args);
  353. $what = "generated CA request for";
  354. }
  355. - else
  356. + else
  357. {
  358. - $process =
  359. - $self->req("-x509 $common_args -new -out $cacert",$args);
  360. - $process->print("$args->{keypass}\n");
  361. - $process->closeok();
  362. + $self->{openssl}->cmd('req',"-x509 $common_args -new -out $cacert",$args);
  363. $what = "initialized self-signed";
  364. }
  365. - $self->warn("Successfully $what CA $self->{name}")
  366. - unless $args->{verbose} > 1;
  367. + $self->warn("Successfully $what CA $self->{name}")
  368. + if $args->{verbose};
  369. }
  370. }
  371. @@ -497,13 +512,13 @@
  372. {
  373. my $self = shift;
  374. my $dir = $self->caDir();
  375. -
  376. +
  377. $self->die("Uninitialized CA: missing or unreadable ca certificate")
  378. unless -r "$dir/ca.crt";
  379. $self->die("Uninitialized CA: missing or unreadable ca private key")
  380. unless -r "$dir/private/ca.key";
  381. -
  382. +
  383. $dir;
  384. }
  385. @@ -518,7 +533,7 @@
  386. my $file = "$dir/tmp/$base-$$.$ext";
  387. $self->{_tmpfiles}->{$file}++;
  388. -
  389. +
  390. $file;
  391. }
  392. @@ -526,7 +541,7 @@
  393. {
  394. my $self = shift;
  395. my $file = shift;
  396. -
  397. +
  398. delete $self->{_tmpfiles}->{$file};
  399. }
  400. @@ -534,7 +549,7 @@
  401. {
  402. my $self = shift;
  403. my $dir = $self->caDir();
  404. -
  405. +
  406. my $serial = shift;
  407. "$dir/private/keys/$serial.key";
  408. }
  409. @@ -543,7 +558,7 @@
  410. {
  411. my $self = shift;
  412. my $dir = $self->caDir();
  413. -
  414. +
  415. my $serial = shift;
  416. "$dir/certs/$serial.pem";
  417. }
  418. @@ -552,30 +567,29 @@
  419. {
  420. my $self = shift;
  421. my $args = shift;
  422. -
  423. - $self->die("Required parameter dn missing")
  424. +
  425. + $self->die("Required parameter dn missing")
  426. unless $args->{'dn'};
  427. -
  428. +
  429. my $dir = $self->checkCA();
  430. -
  431. +
  432. $args->{type} = 'user' unless $args->{type};
  433. $args->{csrfile} = $self->tempFile("request","csr") unless $args->{csrfile};
  434. $args->{keyfile} = $self->tempFile("request","key") unless $args->{keyfile};
  435. -
  436. ## Generate a key unless one already exists
  437. - unless (-r $args->{keyfile})
  438. + if (! -r $args->{keyfile})
  439. {
  440. - $self->warn("Generating new key") unless $args->{verbose} > 1;
  441. + $self->warn("Generating new key") if $args->{verbose};
  442. $self->genkey($args)
  443. or $self->die("Unable to generate key in $args->{keyfile}");
  444. }
  445. ## Generate a certificate request
  446. - $self->warn("Create certificate request for $args->{dn}")
  447. - unless $args->{verbose} > 1;
  448. - my $process = $self->req("-new -$args->{digest} -key $args->{keyfile} -out $args->{csrfile} -passin stdin",$args);
  449. - $process->print("$args->{keypass}\n");
  450. - $process->closedie();
  451. + $self->warn("Create certificate request for $args->{dn}")
  452. + if $args->{verbose};
  453. + my $cmd = "-new -$args->{digest} -key $args->{keyfile} -out $args->{csrfile}";
  454. + $cmd .= " -passin pass:$args->{keypass}" if defined($args->{keypass});
  455. + $self->{openssl}->cmd('req',$cmd,$args);
  456. }
  457. sub gencrl
  458. @@ -587,6 +601,8 @@
  459. $args->{capass} = $self->getPassword("CA Private key password")
  460. unless $args->{capass};
  461. + $self->die("CA key must have a password")
  462. + unless defined($args->{capass});
  463. my $days = $args->{crldays} || 30;
  464. my $hours = $args->{crlhours};
  465. @@ -600,26 +616,19 @@
  466. {
  467. $time = "-crldays $days";
  468. }
  469. - my $common = "-batch -passin stdin -gencrl $time";
  470. + my $common = "-batch -passin pass:$args->{capass} -gencrl $time";
  471. ## Generate both version 1 and version 2 (with extensions) CRLs
  472. ## and convert from PEM to DER format
  473. - my $p1 =
  474. - $self->ca("$common -out $dir/crl-v1.pem",$args);
  475. - $p1->print("$args->{capass}\n");
  476. - $p1->closedie();
  477. -
  478. - CSP::OpenSSL->new()->
  479. - sopen($self,'dummy',"crl -outform DER -out $dir/crl-v1.crl -in $dir/crl-v1.pem")->closeok();
  480. -
  481. - my $p2 =
  482. - $self->ca("$common -crlexts crl_extensions -out $dir/crl-v2.pem",$args);
  483. - $p2->print("$args->{capass}\n");
  484. - $p2->closedie();
  485. + $self->{openssl}->cmd('ca',"$common -out $dir/crl-v1.pem",$args);
  486. +
  487. + $self->{openssl}->cmd('crl',"-outform DER -out $dir/crl-v1.crl -in $dir/crl-v1.pem");
  488. +
  489. + $self->{openssl}->cmd('ca',"$common -crlexts crl_extensions -out $dir/crl-v2.pem",$args);
  490. - CSP::OpenSSL->new()->
  491. - sopen($self,'dummy',"crl -outform DER -out $dir/crl-v2.crl -in $dir/crl-v2.pem")->closedie();
  492. + $self->{openssl}->
  493. + cmd('crl',"-outform DER -out $dir/crl-v2.crl -in $dir/crl-v2.pem");
  494. }
  495. sub list
  496. @@ -639,8 +648,7 @@
  497. my @row = split /\t/;
  498. next if ($row[0] ne 'V' && !$args->{all});
  499. -
  500. - next if ($args->{serial} && $row[3] ne $args->{serial});
  501. + next if ($args->{serial} && $row[3] != $args->{serial});
  502. my $entity = $eclass->new($self,\@row,$args->{xinfo},$args->{contents});
  503. push(@out,$entity) if ref $entity;
  504. @@ -653,7 +661,7 @@
  505. {
  506. my $date = shift;
  507. my @parts = split /\s+/,$date;
  508. - warn "$parts[0] $parts[1] $parts[3]";
  509. + #warn "$parts[0] $parts[1] $parts[3]";
  510. my ($y,$m,$d) = Date::Calc::Parse_Date("$parts[0] $parts[1] $parts[3]");
  511. my $t = $parts[2];
  512. $t =~ s/://og;
  513. @@ -674,9 +682,8 @@
  514. $self->die("Not a directory: $args->{export}")
  515. unless -d $args->{export};
  516. -
  517. +
  518. my $odir = $args->{export};
  519. - mkdir $odir,00755;
  520. mkdir "$odir/certs",00755;
  521. my $expired_count = 0;
  522. @@ -721,7 +728,7 @@
  523. <csp:fingerprint type="md5">$e->{info}->{fingerprint_md5}</csp:fingerprint>
  524. <csp:validity>
  525. <csp:notbefore dateandtime="$from">$e->{info}->{notbefore}</csp:notbefore>
  526. - <csp:notafter dateandtime="$to">$e->{info}->{notbefore}</csp:notbefore>
  527. + <csp:notafter dateandtime="$to">$e->{info}->{notafter}</csp:notafter>
  528. </csp:validity>
  529. </csp:entity>
  530. EOXML
  531. @@ -733,8 +740,8 @@
  532. }
  533. my $file = $self->certFile($serial);
  534. - CSP::OpenSSL->new()->
  535. - ropen($self,'dummy',"x509 -in $file -outform DER -out $odir/certs/$serial.crt")->closeok();
  536. + $self->{openssl}->
  537. + cmd('x509',"-in $file -outform DER -out $odir/certs/$serial.crt",{noconfig=>1});
  538. system('cp',$file,"$odir/certs/$serial.pem");
  539. @@ -764,8 +771,8 @@
  540. $revoked_html .= "</table>\n";
  541. $expired_html .= "</table>\n";
  542. - my $pp = CSP::OpenSSL->new()->
  543. - sopen($self,'dummy',"x509 -inform PEM -in $dir/ca.crt -outform PEM -out $odir/ca.crt")->closeok();
  544. + my $pp = $self->{openssl}->
  545. + cmd('x509',"-inform PEM -in $dir/ca.crt -outform PEM -out $odir/ca.crt",{noconfig=>1});
  546. #system('cp',"$dir/ca.crt","$odir/ca.crt");
  547. system('cp',"$dir/crl-v1.crl","$odir/crl-v1.crl");
  548. system('cp',"$dir/crl-v2.crl","$odir/crl-v2.crl");
  549. @@ -844,7 +851,7 @@
  550. {
  551. my $self = shift;
  552. my $fn = shift;
  553. -
  554. +
  555. my $html = IO::File->new();
  556. my ($base) = $fn =~ /(.+)\.html\.mpp$/;
  557. $self->die("Filename missing .html.mpp extension: $fn")
  558. @@ -858,16 +865,10 @@
  559. {
  560. my $self = shift;
  561. my $args = shift;
  562. -
  563. +
  564. my $dir = $self->checkCA();
  565. -
  566. - my $process = CSP::OpenSSL->new()->
  567. - ropen($self,'dummy',"x509 -noout -text -in $dir/ca.crt");
  568. - my $fh = $process->handle();
  569. - while (<$fh>)
  570. - {
  571. - print $_;
  572. - }
  573. +
  574. + print $self->{openssl}->cmd('x509',"-noout -text -in $dir/ca.crt",{noconfig=>1});
  575. }
  576. sub caBundle
  577. @@ -894,10 +895,10 @@
  578. print BUNDLE $_;
  579. }
  580. close CERT;
  581. - my $process = CSP::OpenSSL->new()->
  582. - ropen($self,'dummy',"x509 -noout -text -in $certfile");
  583. + my $process = $self->{openssl}->
  584. + cmd('x509',"-noout -text -in $certfile",{noconfig=>1});
  585. my $fh = $process->handle();
  586. - while (<$fh>)
  587. + while (<$fh>)
  588. {
  589. print BUNDLE $_;
  590. }
  591. @@ -910,27 +911,39 @@
  592. {
  593. my $self = shift;
  594. my $args = shift;
  595. -
  596. +
  597. my $dir = $self->checkCA();
  598. my $serial = $args->{serial};
  599. my $file = $self->certFile($serial);
  600. -
  601. +
  602. $self->die("Serial $serial not issued by this CA") unless -f $file;
  603. -
  604. +
  605. if ($args->{confirm})
  606. {
  607. $self->dumpcert($file);
  608. $self->confirm("Really revoke this?","Bye...");
  609. }
  610. -
  611. +
  612. $args->{capass} = $self->getPassword("CA Private key password")
  613. unless $args->{capass};
  614. + $self->die("CA key must have a password")
  615. + unless defined($args->{capass});
  616. - my $process =
  617. - $self->ca("-passin stdin -batch -revoke $file",$args);
  618. - $process->print("$args->{capass}\n");
  619. - $process->closeok();
  620. + $self->{openssl}->cmd('ca',"-passin pass:$args->{capass} -batch -revoke $file",$args);
  621. + }
  622. +
  623. +sub _time
  624. + {
  625. + my ($self,$Dd,$Dh,$Dm,$Ds) = @_;
  626. +
  627. + my ($year,$month,$day,$hour,$min,$sec,$doy,$dow,$dst) = Gmtime();
  628. + my ($nyear,$nmonth,$nday,$nhour,$nmin,$nsec) =
  629. + Add_Delta_DHMS($year,$month,$day,$hour,$min,$sec,$Dd,$Dh,$Dm,$Ds);
  630. +
  631. + my $tmp = sprintf("%02d%02d%02d%02d%02d%02dZ",$nyear,$nmonth,$nday,$nhour,$nmin,$nsec);
  632. + $tmp =~ s/^[0-9][0-9]//;
  633. + $tmp;
  634. }
  635. sub issue
  636. @@ -939,26 +952,26 @@
  637. my $args = shift;
  638. my $dir = $self->checkCA();
  639. -
  640. +
  641. $args->{type} = 'user' unless $args->{type};
  642. - unless ($args->{csrfile})
  643. + unless ($args->{csrfile})
  644. {
  645. $args->{csrfile} = $self->tempFile("request","csr");
  646. - eval
  647. + eval
  648. {
  649. $self->request($args);
  650. $args->{p12pass} = $args->{keypass};
  651. };
  652. - if ($@)
  653. + if ($@)
  654. {
  655. $self->die("Unable to generate request: ".$self->exm($@));
  656. }
  657. }
  658. -
  659. - $self->die("No csr file $args->{csrfile}")
  660. - unless -f $args->{csrfile};
  661. -
  662. +
  663. +# $self->die("No csr file $args->{csrfile}")
  664. +# unless -r $args->{csrfile};
  665. +
  666. eval
  667. {
  668. if ($args->{confirm})
  669. @@ -967,7 +980,7 @@
  670. $self->confirm("Really sign this?","Bye...");
  671. }
  672. - $self->warn("Signing request") unless $args->{verbose} > 1;
  673. + $self->warn("Signing request") if $args->{verbose};
  674. my $serial;
  675. open SERIAL,"$dir/serial";
  676. @@ -976,18 +989,25 @@
  677. $args->{capass} = $self->getPassword("CA Private key password")
  678. unless $args->{capass};
  679. -
  680. - $args->{days} = 365 unless $args->{days};
  681. -
  682. - my $process =
  683. - $self->ca("-batch -md $args->{digest} -days $args->{days} -passin stdin -preserveDN -outdir $dir/certs -in $args->{csrfile}",$args);
  684. - $process->print("$args->{capass}\n");
  685. - $process->closeok();
  686. + $self->die("CA key must have a password")
  687. + unless defined($args->{capass});
  688. +
  689. + $args->{startdate} = $self->_time()
  690. + unless $args->{startdate};
  691. + $args->{enddate} =
  692. + $self->_time($args->{days} or 365,$args->{hours},$args->{mins},$args->{secs})
  693. + unless $args->{enddate};
  694. +
  695. + $self->{openssl}->cmd('ca',
  696. + "-batch -md $args->{digest} -startdate $args->{startdate} ".
  697. + "-enddate $args->{enddate} ".
  698. + "-passin pass:$args->{capass} -preserveDN -outdir $dir/certs ".
  699. + "-in $args->{csrfile}",$args);
  700. rename $args->{keyfile},"$dir/private/keys/$serial.key";
  701. $self->unTempFile($args->{keyfile});
  702. $args->{serial} = $serial;
  703. };
  704. - if ($@)
  705. + if ($@)
  706. {
  707. $self->die("Unable to sign request: ".$self->exm($@));
  708. }
  709. @@ -999,26 +1019,26 @@
  710. my $args = shift;
  711. my $dir = $self->checkCA();
  712. -
  713. +
  714. my $serial = $args->{serial};
  715. $self->die("Missing serial number") unless $serial;
  716. -
  717. +
  718. $args->{keypass} = $self->getPassword("Private key password")
  719. - unless $args->{keypass};
  720. -
  721. + unless defined($args->{keypass});
  722. +
  723. $args->{p12pass} = $self->getPassword("PKCS12 export password")
  724. - unless $args->{p12pass};
  725. + unless defined($args->{p12pass});
  726. my $othercerts;
  727. - if (-f "$dir/certpath.crt")
  728. + if (-f "$dir/certpath.crt")
  729. {
  730. $othercerts = "-certfile $dir/certpath.crt";
  731. }
  732. - else
  733. + else
  734. {
  735. $othercerts = "-certfile $dir/ca.crt";
  736. }
  737. -
  738. +
  739. my $certFile = $self->certFile($serial);
  740. my $keyFile = $self->keyFile($serial);
  741. $self->die("The private key of $serial is not on-line")
  742. @@ -1026,15 +1046,14 @@
  743. $self->die("The certificate of $serial is not on-line")
  744. unless -f $certFile;
  745. - eval
  746. + eval
  747. {
  748. mkdir "$dir/p12",00755 unless -d "$dir/p12";
  749. my $p12File = "$dir/p12/$serial.p12";
  750. - my $process =
  751. - $self->pkcs12("-export -des3 $othercerts -inkey $keyFile -in $certFile -out $p12File -passout stdin -passin stdin",$args);
  752. - $process->print("$args->{keypass}\n");
  753. - $process->print("$args->{p12pass}\n");
  754. - $process->closeok();
  755. + my $cmd = "-export -des3 $othercerts -inkey $keyFile -in $certFile -out $p12File";
  756. + $cmd .= " -passout pass:$args->{p12pass}" if defined($args->{p12pass});
  757. + $cmd .= " -passin pass:$args->{keypass}" if defined($args->{keypass});
  758. + $self->{openssl}->cmd('pkcs12',$cmd,$args);
  759. };
  760. if ($@)
  761. {
  762. @@ -1046,10 +1065,10 @@
  763. {
  764. my $self = shift;
  765. my $dn = shift;
  766. -
  767. +
  768. my @rdns = split /\//,$dn;
  769. shift @rdns;
  770. - foreach my $aname (keys %{$self->{alias}})
  771. + foreach my $aname (keys %{$self->{alias}})
  772. {
  773. map { s/$aname/$self->{alias}->{$aname}/ig; } @rdns;
  774. }
  775. @@ -1063,21 +1082,21 @@
  776. my $args = shift;
  777. my $dn;
  778. -
  779. - SWITCH:
  780. +
  781. + SWITCH:
  782. {
  783. - $dn = $x,last SWITCH
  784. + $dn = $x,last SWITCH
  785. if $x =~ /=/; ## probably a distinguished name
  786. -
  787. - $dn = $self->email2DN($1,$2,$args),last SWITCH
  788. +
  789. + $dn = $self->email2DN($1,$2,$args),last SWITCH
  790. if $x =~ /([^@]+)\@([^@]+)/; ## probably an email address
  791. -
  792. - $dn = $self->domainName2DN($x,$args),last SWITCH
  793. +
  794. + $dn = $self->domainName2DN($x,$args),last SWITCH
  795. if $x =~/\./; ## probably a DNS domain name
  796. $self->die("Unknown name form: $x");
  797. }
  798. -
  799. +
  800. foreach my $av (split /\s*[,\/]\s*/,$dn)
  801. {
  802. $self->die("Bad X.501 name $dn") unless $av =~ /([a-zA-Z]+)\s*=\s*([^=]+)/;
  803. @@ -1095,14 +1114,14 @@
  804. {
  805. my $self = shift;
  806. my ($lp,$dp,$args) = @_;
  807. -
  808. +
  809. #my $attr = 'uid';
  810. #$attr = 'CN' if $lp =~ /[-\.\_]/;
  811. my $attr = 'CN';
  812. -
  813. +
  814. $args->{email} = "$lp\@$dp";
  815. - return "$attr=$lp,".$self->domainName2DN($dp);
  816. + return $self->domainName2DN($dp).",$attr=$lp";
  817. }
  818. sub domainName2DN
  819. @@ -1115,59 +1134,29 @@
  820. $args->{ip} = $dns;
  821. my @dn = split /\./,$dns;
  822. @dn = map { "dc=$_" } @dn;
  823. - join(',',@dn);
  824. - }
  825. -
  826. -sub req
  827. - {
  828. - my $self = shift;
  829. -
  830. - CSP::OpenSSL->new($self,'req',@_);
  831. - }
  832. -
  833. -sub ca
  834. - {
  835. - my $self = shift;
  836. -
  837. - CSP::OpenSSL->new($self,'ca',@_);
  838. - }
  839. -
  840. -sub pkcs12
  841. - {
  842. - my $self = shift;
  843. -
  844. - CSP::OpenSSL->new($self,'pkcs12',@_);
  845. - }
  846. -
  847. -sub x509
  848. - {
  849. - my $self = shift;
  850. -
  851. - CSP::OpenSSL->new($self,'x509',@_);
  852. + join(',',reverse @dn);
  853. }
  854. sub dumpcert
  855. {
  856. my $self = shift;
  857. my $certfile = shift;
  858. -
  859. - CSP::OpenSSL->new()->
  860. - sopen($self,
  861. - 'x509',
  862. - "-text -in $certfile -noout -nameopt RFC2253",
  863. - {noconfig=>1,verbose=>1})->closeok();
  864. +
  865. + print $self->{openssl}->
  866. + cmd('x509',
  867. + "-text -in $certfile -noout -nameopt RFC2253",
  868. + {noconfig=>1,verbose=>1});
  869. }
  870. sub dumpreq
  871. {
  872. my $self = shift;
  873. my $reqfile = shift;
  874. -
  875. - CSP::OpenSSL->new()->
  876. - sopen($self,
  877. - 'req',
  878. - "-text -in $reqfile -noout",
  879. - {noconfig=>1,verbose=>1})->closeok();
  880. +
  881. + print $self->{openssl}->
  882. + cmd('req',
  883. + "-text -in $reqfile -noout",
  884. + {noconfig=>1,verbose=>1});
  885. }
  886. sub exm
  887. @@ -1183,74 +1172,57 @@
  888. {
  889. my $self = shift;
  890. my $certfile = shift;
  891. -
  892. +
  893. my (%info,$fh,$process);
  894. -
  895. - $process = CSP::OpenSSL->new()->ropen($self,'dummy',"x509 -noout -hash -in $certfile");
  896. - $fh = $process->handle();
  897. - $info{hash} = <$fh>;
  898. - chomp $info{hash};
  899. - $process->closedie;
  900. -
  901. - $process =
  902. - CSP::OpenSSL->new()->ropen($self,'dummy',"x509 -noout -serial -dates -subject -issuer -in $certfile");
  903. - $fh = $process->handle();
  904. - while (<$fh>)
  905. +
  906. + $info{hash} = $self->{openssl}->cmd('x509',"-noout -hash -in $certfile",{noconfig=>1});
  907. +
  908. + local $_ = $self->{openssl}->cmd('x509',"-noout -serial -dates -subject -issuer -in $certfile",{noconfig=>1});
  909. + while ($_)
  910. {
  911. - chomp;
  912. - if (/^subject=\s*(.+)/)
  913. + s/^\s*\n//o;
  914. + if (s/^subject=\s*(.+)//o)
  915. {
  916. $info{subject}=$1;
  917. $info{subject} =~ s/\//,/og;
  918. $info{subject} =~ s/^,//og;
  919. - next;
  920. }
  921. - elsif (/^issuer=\s*(.+)/)
  922. + elsif (s/^issuer=\s*(.+)//o)
  923. {
  924. $info{issuer}=$1;
  925. $info{issuer} =~ s/\//,/og;
  926. $info{issuer} =~ s/^,//og;
  927. - next;
  928. }
  929. - elsif (/^notBefore=\s*(.+)/)
  930. + elsif (s/^notBefore=\s*(.+)//o)
  931. {
  932. $info{notbefore}=$1;
  933. - next;
  934. }
  935. - elsif (/^notAfter=\s*(.+)/)
  936. + elsif (s/^notAfter=\s*(.+)//o)
  937. {
  938. $info{notafter}=$1;
  939. - next;
  940. }
  941. - elsif (/^serial=\s*(.+)/)
  942. + elsif (s/^serial=\s*(.+)//o)
  943. {
  944. $info{serial}=$1;
  945. - next;
  946. }
  947. }
  948. -
  949. - $process->closedie;
  950. -
  951. - $process =
  952. - CSP::OpenSSL->new()->ropen($self,'dummy',"x509 -noout -md5 -fingerprint -in $certfile");
  953. - $fh = $process->handle();
  954. - while (<$fh>)
  955. +
  956. + $_ = $self->{openssl}->cmd('x509',"-noout -md5 -fingerprint -in $certfile",{noconfig=>1});
  957. + while ($_)
  958. {
  959. - chomp;
  960. - $info{fingerprint_md5}=$1,next if /MD5 Fingerprint=(.+)/;
  961. + chomp;
  962. + s/^\s*\n//o;
  963. + $info{fingerprint_md5}=$1,last if /MD5 Fingerprint=(.+)/o;
  964. }
  965. - $process->closedie;
  966. - $process =
  967. - CSP::OpenSSL->new()->ropen($self,'dummy',"x509 -noout -sha1 -fingerprint -in $certfile");
  968. - $fh = $process->handle();
  969. - while (<$fh>)
  970. + $_ = $self->{openssl}->cmd('x509',"-noout -sha1 -fingerprint -in $certfile",{noconfig=>1});
  971. + while ($_)
  972. {
  973. - chomp;
  974. - $info{fingerprint_sha1}=$1,next if /SHA1 Fingerprint=(.+)/;
  975. + chomp;
  976. + s/^\s*\n//o;
  977. + $info{fingerprint_sha1}=$1,last if /SHA1 Fingerprint=(.+)/;
  978. }
  979. - $process->closedie;
  980. -
  981. +
  982. \%info;
  983. }
  984. @@ -1260,7 +1232,7 @@
  985. {
  986. my $self = shift;
  987. my $class = ref $self || $self;
  988. -
  989. +
  990. my @stack = @_;
  991. bless \@stack,$class;
  992. }
  993. @@ -1284,15 +1256,15 @@
  994. package CSP::Entity; # Just a db object
  995. @CSP::Entity::ISA = qw(CSP);
  996. -use Date::Calc qw(Day_of_Week);
  997. +use Date::Calc qw(Day_of_Week Gmtime Add_Delta_Days Add_Delta_DHMS);
  998. use POSIX qw(strftime);
  999. sub parse_date
  1000. {
  1001. my $str = shift;
  1002. -
  1003. +
  1004. my ($y,$mon,$mday,$h,$m,$s) = $str =~ /([0-9]{2})([0-9]{2})([0-9]{2})([0-9]{2})([0-9]{2})([0-9]{2})Z$/;
  1005. -
  1006. +
  1007. $y += 100;
  1008. my $wday = Day_of_Week($y+1999,$mon,$mday);
  1009. my @date = ($s,$m,$h,$mday,$mon,$y,$wday,0);
  1010. @@ -1303,12 +1275,12 @@
  1011. {
  1012. my $self = shift;
  1013. my $class = ref $self || $self;
  1014. -
  1015. +
  1016. my $csp = shift;
  1017. my $row = shift;
  1018. my $getinfo = shift;
  1019. my $getcontents = shift;
  1020. -
  1021. +
  1022. my $serial = $row->[3];
  1023. my $file = ($row->[4] && $row->[4] ne 'unknown' ? $row->[4] : $csp->certFile($serial));
  1024. @@ -1335,7 +1307,7 @@
  1025. sub dump
  1026. {
  1027. my $self = shift;
  1028. -
  1029. +
  1030. printf "%-8s: %s\n",'Serial',$self->{serial};
  1031. my $status = $self->{status};
  1032. printf "%-8s: %s\n",'Status',exists $_status{$status} ? $_status{$status} : "Unknown";
  1033. @@ -1344,7 +1316,7 @@
  1034. printf "%-8s: %s\n",'Revoked',strftime("%a %b %e %H:%M:%S %Y",@{$self->{revoked}}) if $self->{revoked};
  1035. printf "%-8s: %s\n",'SHA1',$self->info('fingerprint_sha1') if $self->info('fingerprint_sha1');
  1036. printf "%-8s: %s\n",'MD5',$self->info('fingerprint_md5') if $self->info('fingerprint_md5');
  1037. - if ($self->{getcontents})
  1038. + if ($self->{getcontents})
  1039. {
  1040. $self->dumpcert($self->{file});
  1041. }
  1042. @@ -1362,53 +1334,86 @@
  1043. ***
  1044. EOTXT
  1045. +use IPC::Run qw( start pump finish timeout new_appender new_chunker);
  1046. +
  1047. sub new
  1048. {
  1049. my $self = shift;
  1050. my $class = ref $self || $self;
  1051. + my $csp = shift;
  1052. - local *FH;
  1053. - my $me = bless
  1054. - {
  1055. - fh=>*FH,
  1056. - openssl=>$ENV{OPENSSL} || die $_unset
  1057. - },$class;
  1058. - @_ > 0 ? $me->wopen(@_) : $me;
  1059. - }
  1060. + my %me;
  1061. + my @openssl = ($ENV{OPENSSL},@_);
  1062. -sub DESTROY
  1063. - {
  1064. - $_[0]->closeok();
  1065. - }
  1066. + $me{csp} = $csp;
  1067. + $me{_handle} = start(\@openssl,
  1068. + '<',new_appender("\n"),\${$me{_in}},
  1069. + '>',\${$me{_out}},'2>&1',debug=>0)
  1070. + or die "Cannot start $ENV{OPENSSL}: $!\n";
  1071. -sub ropen
  1072. - {
  1073. - my $self = shift;
  1074. - $self->rws_open('r',@_);
  1075. + bless \%me,$class;
  1076. }
  1077. -sub wopen
  1078. +sub cmd
  1079. {
  1080. my $self = shift;
  1081. - $self->rws_open('w',@_);
  1082. - }
  1083. + my $cmd = shift;
  1084. + my $cmdline = shift;
  1085. + my $args = shift;
  1086. -sub sopen
  1087. - {
  1088. - my $self = shift;
  1089. - $self->rws_open('s',@_);
  1090. + my $conf;
  1091. + my $cfgcmd;
  1092. + if ( (grep $_ eq $cmd,qw(req ca)) && !$args->{noconfig})
  1093. + {
  1094. + $conf = $self->{csp}->writeConfig($cmd,$args);
  1095. + $self->{csp}->die("Unable to write configuration file") unless -f $conf;
  1096. + $cfgcmd = " -config $conf ";
  1097. + }
  1098. + elsif ($cmd eq 'x509' && !$args->{noconfig})
  1099. + {
  1100. + $conf = $self->{csp}->writeConfig($cmd,$args);
  1101. + $self->{csp}->die("Unable to write configuration file") unless -f $conf;
  1102. + $cfgcmd = " -extfile $conf -extensions extensions ";
  1103. + }
  1104. + $cmd = '' if $cmd eq 'dummy';
  1105. +
  1106. + ${$self->{_in}} = "$cmd $cfgcmd $cmdline";
  1107. + $self->warn("# openssl $cmd $cfgcmd $cmdline\n") if $ENV{CSPDEBUG};
  1108. + $self->{_handle}->pump while length ${$self->{_in}};
  1109. + $self->{_handle}->finish;
  1110. +
  1111. + my @out = split /\n/,${$self->{_out}};
  1112. + my @err;
  1113. + my @nout;
  1114. + foreach $_ (@out)
  1115. + {
  1116. + chomp;
  1117. + s/\s*OpenSSL>\s*//og;
  1118. + next unless $_;
  1119. + if (/:error:/) {
  1120. + push (@err,$_);
  1121. + } else {
  1122. + push (@nout,$_);
  1123. + }
  1124. + }
  1125. +
  1126. + $self->{csp}->die(sprintf "OpenSSL Error\n%s",join("\n",@err))
  1127. + if @err;
  1128. +
  1129. + join("\n",@nout)."\n";
  1130. }
  1131. -sub handle
  1132. +sub DESTROY
  1133. {
  1134. - $_[0]->{fh};
  1135. + $_[0]->{_handle}->close();
  1136. + finish $_[0]->{_handle};
  1137. }
  1138. sub rws_open
  1139. {
  1140. my $self = shift;
  1141. my $rw = shift;
  1142. - my $scp = shift;
  1143. + my $csp = shift;
  1144. my $cmd = shift;
  1145. my $cmdline = shift;
  1146. my $args = shift;
  1147. @@ -1428,31 +1433,33 @@
  1148. my $cfgcmd;
  1149. if ( (grep $_ eq $cmd,qw(req ca)) && !$args->{noconfig})
  1150. {
  1151. - $self->{conf} = $scp->writeConfig($cmd,$args);
  1152. - $scp->die("Unable to write configuration file") unless -f $self->{conf};
  1153. + $self->{conf} = $self->{csp}->writeConfig($cmd,$args);
  1154. + $self->{csp}->die("Unable to write configuration file") unless -f $self->{conf};
  1155. $cfgcmd = " -config $self->{conf} ";
  1156. }
  1157. - elsif ($cmd eq 'x509' && !$args->{noconfig})
  1158. + elsif ($cmd eq 'x509' && !$args->{noconfig})
  1159. {
  1160. - $self->{conf} = $scp->writeConfig($cmd,$args);
  1161. - $scp->die("Unable to write configuration file") unless -f $self->{conf};
  1162. + $self->{conf} = $self->{csp}->writeConfig($cmd,$args);
  1163. + $self->{csp}->die("Unable to write configuration file") unless -f $self->{conf};
  1164. $cfgcmd = " -extfile $self->{conf} -extensions extensions ";
  1165. }
  1166. - $self->{csp} = $scp;
  1167. + $self->{csp} = $csp;
  1168. $cmd = '' if $cmd eq 'dummy';
  1169. + my $engine = "-engine opensc" if $ENV{CSP_OPENSC};
  1170. +
  1171. my $redirect = ($args->{verbose} == 0 && $rw ne 'r' ? ">/dev/null 2>&1" : "");
  1172. warn "${lp}$self->{openssl} $cmd $cfgcmd $cmdline ${redirect}${rp}"
  1173. if $ENV{CSPDEBUG};
  1174. if ($rw eq 's')
  1175. {
  1176. - $self->{rc} = system("$self->{openssl} $cmd $cfgcmd $cmdline ${redirect}");
  1177. + $self->{rc} = system("$self->{openssl} $cmd $engine $cfgcmd $cmdline ${redirect}");
  1178. }
  1179. else
  1180. {
  1181. - open $self->{fh},"${lp}$self->{openssl} $cmd $cfgcmd $cmdline ${redirect}${rp}" or
  1182. - $scp->die("Unable to execute: $!");
  1183. + open $self->{fh},"${lp}$self->{openssl} $cmd $engine $cfgcmd $cmdline ${redirect}${rp}" or
  1184. + $self->{csp}->die("Unable to execute: $!");
  1185. }
  1186. $self;
  1187. @@ -1463,7 +1470,7 @@
  1188. my $self = shift;
  1189. close $self->{fh} if defined $self->{fh};
  1190. - unless ($ENV{CSPDEBUG})
  1191. + unless ($ENV{CSPDEBUG})
  1192. {
  1193. unlink $self->{conf} if $self->{conf};
  1194. }
  1195. @@ -1523,12 +1530,12 @@
  1196. CSP is designed to easily handle multiple distinct Certificate Authorities.
  1197. Hence the name which stands for Certificate Service Provider.
  1198. -= item o
  1199. +=item o
  1200. CSP can be used to produce a web site (certificate repository, CRLs etc etc)
  1201. without the need for cgi-scripts.
  1202. -= item o
  1203. +=item o
  1204. CSP tries to be as PKIX-compliant as OpenSSL allows.
  1205. @@ -1551,22 +1558,22 @@
  1206. writer or some other means for making backups of the certificate directory.
  1207. Day to day operations include the following tasks.
  1208. -= over 4
  1209. +=over 4
  1210. -= item 1
  1211. +=item 1
  1212. Issuing certificates based on pkcs10 or out-of-band (non pkcs10) requests.
  1213. -= item 2
  1214. +=item 2
  1215. Backing up the csp main directory (see below) to read-only medium.
  1216. -= item 3
  1217. +=item 3
  1218. Producing the public web site and exporting it (typically using floppy or
  1219. zip-drive) to your web server.
  1220. -= back
  1221. +=back
  1222. =head1 CONFIGURATION
  1223. Index: csp
  1224. --- csp.orig 2005-05-06 21:41:40 +0200
  1225. +++ csp 2005-05-06 21:44:23 +0200
  1226. @@ -15,101 +15,157 @@
  1227. closedir CSPD;
  1228. grep /^[^.]/,@dirs;
  1229. }
  1230. -
  1231. -$usage=<<EOU;
  1232. -Usage: $0 <ca name> create
  1233. +my %usage;
  1234. +
  1235. +$usage{create}=<<EOU;
  1236. +$0 <ca name> create
  1237. +EOU
  1238. +
  1239. +$usage{delete}=<<EOU;
  1240. +$0 <ca name> delete
  1241. +EOU
  1242. +
  1243. +$usage{init}=<<EOU;
  1244. +$0 <ca name> init
  1245. + [--crtfile=<PEM certificate>]
  1246. +
  1247. +$0 <ca name> init
  1248. + [--keysize=<size>]
  1249. + [--keypass=<ca private key password>]
  1250. + [--keyfile=<private key file>]
  1251. + [--csrfile=<output PKCS10 request>]
  1252. + [--days=<ca certificate validity (days)>]
  1253. + [--email=<subjectAltName email>]
  1254. + [--url=<subjectAltName url>]
  1255. + [--crldays=<days to first CRL update>]
  1256. + [--crlhours=<hours to first CRL update>]
  1257. + [--digest=<sha1*|md5|md2|mdc2>]
  1258. + [--verbose]+
  1259. + <CA Subject (X509 Name)>
  1260. +EOU
  1261. +
  1262. +$usage{request}=<<EOU;
  1263. +$0 <ca name> request
  1264. + [--keysize=<size>]
  1265. + [--keypass=<subject private key password>]
  1266. + [--keyfile=<private key file>]
  1267. + [--type=<*user|server|objsign|ca>]
  1268. + [--csrfile=<output pkcs10 request file>]
  1269. + [--noconfirm]
  1270. + [--verbose]+
  1271. + [--digest=<sha1*|md5|md2|mdc2>]
  1272. + {<X509 Name>|<RFC822 address>|<DNS name>}
  1273. +EOU
  1274. +
  1275. +$usage{issue}=<<EOU;
  1276. +$0 <ca name> issue
  1277. + [--keysize=<size> ]
  1278. + [--keypass=<subject private key password>]
  1279. + [--keyfile=<private key file>]
  1280. + [--noconfirm]
  1281. + [--verbose]+
  1282. + [--type=<*user|server|objsign|ca>]
  1283. +
  1284. + - delta -
  1285. + [--days=<certificate validity (days)>]
  1286. + [--hours=<certificate validity (hours)>]
  1287. + [--mins=<certificate validity (minutes)>]
  1288. + [--secs=<certificate validity (seconds)>]
  1289. + - absolute -
  1290. + [--startdate=<certificate validity (start-date)>]
  1291. + [--enddate=<certificate validity (end-date)>]
  1292. +
  1293. + [--capass=<CA private key password>]
  1294. + [--email=<subjectAltName email>]
  1295. + [--url=<subjectAltName url>]
  1296. + [--ip=<subjectAltName ip address>]
  1297. + [--dns=<subjectAltName dns name>]
  1298. + [--digest=<sha1*|md5|md2|mdc2>]
  1299. + {<X509 Name>|<RFC822 address>|<DNS name>}
  1300. +EOU
  1301. +
  1302. +$usage{sign}=<<EOU;
  1303. +$0 <ca name> sign
  1304. + [--type=<*user|server|objsign|ca>]
  1305. + - delta -
  1306. + [--days=<certificate validity (days)>]
  1307. + [--hours=<certificate validity (hours)>]
  1308. + [--mins=<certificate validity (minutes)>]
  1309. + [--secs=<certificate validity (seconds)>]
  1310. + - absolute -
  1311. + [--startdate=<certificate validity (start-date)>]
  1312. + [--enddate=<certificate validity (end-date)>]
  1313. +
  1314. + [--capass=<CA private key password>]
  1315. + [--csrfile=<input PKCS10 request>]
  1316. + [--email=<subjectAltName email>]
  1317. + [--url=<subjectAltName url>]
  1318. + [--ip=<subjectAltName ip address>]
  1319. + [--dns=<subjectAltName dns name>]
  1320. + [--digest=<sha1*|md5|md2|mdc2>]
  1321. + [--verbose]+
  1322. +EOU
  1323. +
  1324. +$usage{p12}=<<EOU;
  1325. +$0 <ca name> p12
  1326. + [--p12pass=<pkcs12 export password>]
  1327. + [--keypass=<private key password>]
  1328. + [--verbose]+
  1329. + <serial>
  1330. +EOU
  1331. +
  1332. +$usage{revoke}=<<EOU;
  1333. +$0 <ca name> revoke <serial>
  1334. + [--noconfirm] [--quiet[=<level>]]
  1335. +EOU
  1336. +
  1337. +$usage{gencrl}=<<EOU;
  1338. +$0 <ca name> gencrl
  1339. + [--crldays=<days to next CRL update>]
  1340. + [--crlhours=<hours to next CRL update>]
  1341. + [--digest=<sha1*|md5|md2|mdc2>]
  1342. + [--verbose]+
  1343. +EOU
  1344. +
  1345. +$usage{genpublic}=<<EOU;
  1346. +$0 <ca name> genpublic
  1347. + [--export=<export directory>]
  1348. + [--verbose]+
  1349. +EOU
  1350. +
  1351. +$usage{list}=<<EOU;
  1352. +$0 <ca name> list
  1353. + [--serial=<serial>]
  1354. + [--all]
  1355. + [--xinfo]
  1356. + [--contents]
  1357. + [--verbose]+
  1358. +EOU
  1359. +
  1360. +$usage{dump}=<<EOU;
  1361. +$0 <ca name> dump
  1362. +EOU
  1363. +
  1364. +my $cmds = join(' ',sort keys %usage);
  1365. +
  1366. +$usage{_nocmd_}=<<EOU;
  1367. +
  1368. +$0 --list
  1369. - $0 <ca name> delete
  1370. +$0 --bundle
  1371. - $0 <ca name> init
  1372. - [--crtfile=<PEM certificate>]
  1373. -
  1374. - $0 <ca name> init
  1375. - [--keysize=<size>]
  1376. - [--keypass=<ca private key password>]
  1377. - [--keyfile=<private key file>]
  1378. - [--csrfile=<output PKCS10 request>]
  1379. - [--days=<ca certificate validity (days)>]
  1380. - [--email=<subjectAltName email>]
  1381. - [--url=<subjectAltName url>]
  1382. - [--crldays=<days to first CRL update>]
  1383. - [--crlhours=<hours to first CRL update>]
  1384. - [--digest=<sha1*|md5|md2|mdc2>]
  1385. - [--verbose]+
  1386. - <CA Subject (X509 Name)>
  1387. -
  1388. - $0 <ca name> request
  1389. - [--keysize=<size>]
  1390. - [--keypass=<subject private key password>]
  1391. - [--keyfile=<private key file>]
  1392. - [--type=<*user|server|objsign|ca>]
  1393. - [--csrfile=<output pkcs10 request file>]
  1394. - [--noconfirm]
  1395. - [--verbose]+
  1396. - [--digest=<sha1*|md5|md2|mdc2>]
  1397. - {<X509 Name>|<RFC822 address>|<DNS name>}
  1398. -
  1399. - $0 <ca name> issue
  1400. - [--keysize=<size> ]
  1401. - [--keypass=<subject private key password>]
  1402. - [--keyfile=<private key file>]
  1403. - [--noconfirm]
  1404. - [--verbose]+
  1405. - [--type=<*user|server|objsign|ca>]
  1406. - [--days=<certificate validity (days)>]
  1407. - [--capass=<CA private key password>]
  1408. - [--email=<subjectAltName email>]
  1409. - [--url=<subjectAltName url>]
  1410. - [--ip=<subjectAltName ip address>]
  1411. - [--dns=<subjectAltName dns name>]
  1412. - [--digest=<sha1*|md5|md2|mdc2>]
  1413. - {<X509 Name>|<RFC822 address>|<DNS name>}
  1414. -
  1415. - $0 <ca name> sign
  1416. - [--type=<*user|server|objsign|ca>]
  1417. - [--capass=<CA private key password>]
  1418. - [--csrfile=<input PKCS10 request>]
  1419. - [--email=<subjectAltName email>]
  1420. - [--url=<subjectAltName url>]
  1421. - [--ip=<subjectAltName ip address>]
  1422. - [--dns=<subjectAltName dns name>]
  1423. - [--digest=<sha1*|md5|md2|mdc2>]
  1424. - [--verbose]+
  1425. -
  1426. - $0 <ca name> p12
  1427. - [--p12pass=<pkcs12 export password>]
  1428. - [--keypass=<private key password>]
  1429. - [--verbose]+
  1430. - <serial>
  1431. -
  1432. - $0 <ca name> revoke <serial>
  1433. - [--noconfirm] [--quiet[=<level>]]
  1434. -
  1435. - $0 <ca name> gencrl
  1436. - [--crldays=<days to next CRL update>]
  1437. - [--crlhours=<hours to next CRL update>]
  1438. - [--digest=<sha1*|md5|md2|mdc2>]
  1439. - [--verbose]+
  1440. -
  1441. - $0 <ca name> genpublic
  1442. - [--export=<export directory>]
  1443. - [--verbose]+
  1444. -
  1445. - $0 <ca name> list
  1446. - [--serial=<serial>]
  1447. - [--all]
  1448. - [--xinfo]
  1449. - [--contents]
  1450. - [--verbose]+
  1451. +$0 --help [<cmd>]
  1452. - $0 --list
  1453. +$0 <ca name> <cmd> [--help] <options>*
  1454. - $0 --bundle
  1455. +Where <cmd> is one of
  1456. +
  1457. +$cmds.
  1458. EOU
  1459. -die $usage unless @ARGV > 0;
  1460. +die $usage{_nocmd_} unless @ARGV > 0;
  1461. my $name = shift @ARGV;
  1462. @@ -129,7 +185,7 @@
  1463. mkdir "$home/csp",00755 unless -d "$home/csp";
  1464. $name eq '--list' and
  1465. - do
  1466. + do
  1467. {
  1468. map { print "$_\n"; } &list_csp($home);
  1469. },exit;
  1470. @@ -141,7 +197,9 @@
  1471. CSP->caBundle({bundle=>"$home/ca-bundle.crt"},@certs);
  1472. },exit;
  1473. -die $usage unless @ARGV > 0;
  1474. +
  1475. +$name eq '--help' && @ARGV == 1 and die $usage{$ARGV[0]};
  1476. +$name eq '--help' || @ARGV == 0 and die $usage{_nocmd_};
  1477. my $cmd = shift @ARGV;
  1478. @@ -157,6 +215,7 @@
  1479. xinfo => 0,
  1480. contents=> 0,
  1481. digest => 'sha1',
  1482. + help => 0,
  1483. all => 0);
  1484. my @args = ("type=s",
  1485. @@ -165,10 +224,17 @@
  1486. "confirm!",
  1487. "keysize=i",
  1488. "days=i",
  1489. + "hours=i",
  1490. + "mins=i",
  1491. + "secs=i",
  1492. + "startdate=s",
  1493. + "enddate=s",
  1494. "xinfo!",
  1495. "contents!",
  1496. "serial=i",
  1497. "keypass=s",
  1498. + "capass=s",
  1499. + "p12pass:s",
  1500. "keyfile=s",
  1501. "csrfile=s",
  1502. "crtfile=s",
  1503. @@ -177,59 +243,55 @@
  1504. "dns=s",
  1505. "export:s",
  1506. "digest=s",
  1507. + "help!",
  1508. "url=s");
  1509. -SWITCH:
  1510. +GetOptions(\%args,@args) or die $usage{$cmd};
  1511. +die $usage{$cmd} if $args{help};
  1512. +
  1513. +SWITCH:
  1514. {
  1515. ##
  1516. ## Dump (text form) the CA certificate
  1517. - ##
  1518. + ##
  1519. $cmd eq 'dump' and
  1520. do
  1521. {
  1522. - GetOptions(\%args,@args) or die $usage;
  1523. -
  1524. $csp->dump(\%args);
  1525. },last SWITCH;
  1526. - ##
  1527. + ##
  1528. ## Drop the CA
  1529. ##
  1530. - $cmd eq 'delete' and
  1531. - do
  1532. + $cmd eq 'delete' and
  1533. + do
  1534. {
  1535. - GetOptions(\%args,@args) or die $usage;
  1536. -
  1537. $csp->delete(\%args);
  1538. },last SWITCH;
  1539. -
  1540. - ##
  1541. +
  1542. + ##
  1543. ## Initialize a ca using a self-signed certificate.
  1544. ##
  1545. - $cmd eq 'create' and
  1546. + $cmd eq 'create' and
  1547. do
  1548. {
  1549. - GetOptions(\%args,@args) or die $usage;
  1550. + $args{keysize} = 2048 unless $args{keysize};
  1551. + $args{type} = 'root';
  1552. $csp->create(\%args);
  1553. },last SWITCH;
  1554. -
  1555. - ##
  1556. +
  1557. + ##
  1558. ## Initialize a ca using a self-signed certificate.
  1559. ##
  1560. - $cmd eq 'init' and
  1561. - do
  1562. + $cmd eq 'init' and
  1563. + do
  1564. {
  1565. - $args{keysize} = 2048;
  1566. - $args{type} = 'root';
  1567. -
  1568. - GetOptions(\%args,@args) or die $usage;
  1569. -
  1570. - die $usage unless @ARGV == 1 or $args{crtfile};
  1571. + die $usage{init} unless @ARGV == 1 or $args{crtfile};
  1572. $args{dn} = $csp->getDN(shift @ARGV,\%args) if @ARGV;
  1573. $csp->init(\%args);
  1574. @@ -238,13 +300,11 @@
  1575. ##
  1576. ## Request a certificate of a specific type
  1577. ##
  1578. -
  1579. +
  1580. $cmd eq 'request' and
  1581. do
  1582. {
  1583. - GetOptions(\%args,@args) or die $usage;
  1584. -
  1585. - die $usage unless @ARGV == 1;
  1586. + die $usage{request} unless @ARGV == 1;
  1587. $args{dn} = $csp->getDN(shift @ARGV,\%args);
  1588. @@ -258,10 +318,8 @@
  1589. $cmd eq 'p12' and
  1590. do
  1591. {
  1592. - GetOptions(\%args,@args) or die $usage;
  1593. -
  1594. - die $usage unless @ARGV == 1;
  1595. - $args{serial} = $ARGV[0];
  1596. + die $usage{p12} unless @ARGV == 1;
  1597. + $args{serial} = $ARGV[0] unless $args{serial};
  1598. $csp->export_pkcs12(\%args);
  1599. },last SWITCH;
  1600. @@ -273,15 +331,13 @@
  1601. $cmd eq 'issue' and
  1602. do
  1603. {
  1604. - GetOptions(\%args,@args) or die $usage;
  1605. -
  1606. - die $usage unless @ARGV == 1;
  1607. + die $usage{issue} unless 1 == @ARGV;
  1608. $args{dn} = $csp->getDN(shift @ARGV,\%args);
  1609. $csp->issue(\%args);
  1610. },last SWITCH;
  1611. -
  1612. +
  1613. ##
  1614. ## Sign a certificate request (PKCS10 file)
  1615. ##
  1616. @@ -289,11 +345,9 @@
  1617. $cmd eq 'sign' and
  1618. do
  1619. {
  1620. - GetOptions(\%args,@args) or die $usage;
  1621. -
  1622. $csp->issue(\%args);
  1623. },last SWITCH;
  1624. -
  1625. +
  1626. ##
  1627. ## Revoke a certificate given by serial
  1628. ##
  1629. @@ -301,9 +355,7 @@
  1630. $cmd eq 'revoke' and
  1631. do
  1632. {
  1633. - GetOptions(\%args,@args) or die $usage;
  1634. -
  1635. - die $usage unless @ARGV == 1 || $args{serial};
  1636. + die $usage{revoke} unless 1 == @ARGV || $args{serial};
  1637. $args{serial} = shift unless $args{serial};
  1638. @@ -317,20 +369,16 @@
  1639. $cmd eq 'gencrl' and
  1640. do
  1641. {
  1642. - GetOptions(\%args,@args) or die $usage;
  1643. -
  1644. $csp->gencrl(\%args);
  1645. },last SWITCH;
  1646. -
  1647. +
  1648. ##
  1649. ## Generate public sites (www & ldap)
  1650. - ##
  1651. + ##
  1652. ($cmd eq 'genpublic') and
  1653. do
  1654. {
  1655. - GetOptions(\%args,@args) or die $usage;
  1656. -
  1657. $csp->genPublic(\%args);
  1658. },last SWITCH;
  1659. @@ -341,9 +389,8 @@
  1660. ($cmd eq 'list' or $cmd eq 'show') and
  1661. do
  1662. {
  1663. - GetOptions(\%args,@args) or die $usage;
  1664. map { $_->dump(); } $csp->list(\%args,'CSP::Entity');
  1665. },last SWITCH;
  1666. -
  1667. - die $usage;
  1668. +
  1669. + die $usage{_nocmd_};
  1670. }