80-test_cms.t 49 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274
  1. #! /usr/bin/env perl
  2. # Copyright 2015-2025 The OpenSSL Project Authors. All Rights Reserved.
  3. #
  4. # Licensed under the Apache License 2.0 (the "License"). You may not use
  5. # this file except in compliance with the License. You can obtain a copy
  6. # in the file LICENSE in the source distribution or at
  7. # https://www.openssl.org/source/license.html
  8. use strict;
  9. use warnings;
  10. use POSIX;
  11. use File::Spec::Functions qw/catfile/;
  12. use File::Compare qw/compare_text compare/;
  13. use OpenSSL::Test qw/:DEFAULT srctop_dir srctop_file bldtop_dir bldtop_file with data_file/;
  14. use OpenSSL::Test::Utils;
  15. BEGIN {
  16. setup("test_cms");
  17. }
  18. use lib srctop_dir('Configurations');
  19. use lib bldtop_dir('.');
  20. my $no_fips = disabled('fips') || ($ENV{NO_FIPS} // 0);
  21. my $old_fips = 0;
  22. plan skip_all => "CMS is not supported by this OpenSSL build"
  23. if disabled("cms");
  24. my $provpath = bldtop_dir("providers");
  25. # Some tests require legacy algorithms to be included.
  26. my @legacyprov = ("-provider-path", $provpath,
  27. "-provider", "default",
  28. "-provider", "legacy" );
  29. my @defaultprov = ("-provider-path", $provpath,
  30. "-provider", "default");
  31. my @config = ( );
  32. my $provname = 'default';
  33. my $datadir = srctop_dir("test", "recipes", "80-test_cms_data");
  34. my $smdir = srctop_dir("test", "smime-certs");
  35. my $smcont = srctop_file("test", "smcont.txt");
  36. my $smcont_zero = srctop_file("test", "smcont_zero.txt");
  37. my ($no_des, $no_dh, $no_dsa, $no_ec, $no_ec2m, $no_rc2, $no_zlib)
  38. = disabled qw/des dh dsa ec ec2m rc2 zlib/;
  39. $no_rc2 = 1 if disabled("legacy");
  40. plan tests => 24;
  41. ok(run(test(["pkcs7_test"])), "test pkcs7");
  42. unless ($no_fips) {
  43. my $provconf = srctop_file("test", "fips-and-base.cnf");
  44. @config = ( "-config", $provconf );
  45. $provname = 'fips';
  46. run(test(["fips_version_test", "-config", $provconf, "<3.4.0"]),
  47. capture => 1, statusvar => $old_fips);
  48. }
  49. $ENV{OPENSSL_TEST_LIBCTX} = "1";
  50. my @prov = ("-provider-path", $provpath,
  51. @config,
  52. "-provider", $provname);
  53. my $smrsa1024 = catfile($smdir, "smrsa1024.pem");
  54. my $smrsa1 = catfile($smdir, "smrsa1.pem");
  55. my $smroot = catfile($smdir, "smroot.pem");
  56. my @smime_pkcs7_tests = (
  57. [ "signed content DER format, RSA key",
  58. [ "{cmd1}", @prov, "-sign", "-in", $smcont, "-outform", "DER", "-nodetach",
  59. "-certfile", $smroot, "-signer", $smrsa1, "-out", "{output}.cms" ],
  60. [ "{cmd2}", @prov, "-verify", "-in", "{output}.cms", "-inform", "DER",
  61. "-CAfile", $smroot, "-out", "{output}.txt" ],
  62. \&final_compare
  63. ],
  64. [ "signed detached content DER format, RSA key",
  65. [ "{cmd1}", @prov, "-sign", "-in", $smcont, "-outform", "DER",
  66. "-signer", $smrsa1, "-out", "{output}.cms" ],
  67. [ "{cmd2}", @prov, "-verify", "-in", "{output}.cms", "-inform", "DER",
  68. "-CAfile", $smroot, "-out", "{output}.txt",
  69. "-content", $smcont ],
  70. \&final_compare
  71. ],
  72. [ "signed content test streaming BER format, RSA",
  73. [ "{cmd1}", @prov, "-sign", "-in", $smcont, "-outform", "DER", "-nodetach",
  74. "-stream",
  75. "-signer", $smrsa1, "-out", "{output}.cms" ],
  76. [ "{cmd2}", @prov, "-verify", "-in", "{output}.cms", "-inform", "DER",
  77. "-CAfile", $smroot, "-out", "{output}.txt" ],
  78. \&final_compare
  79. ],
  80. [ "signed content DER format, DSA key",
  81. [ "{cmd1}", @prov, "-sign", "-in", $smcont, "-outform", "DER", "-nodetach",
  82. "-signer", catfile($smdir, "smdsa1.pem"), "-out", "{output}.cms" ],
  83. [ "{cmd2}", @prov, "-verify", "-in", "{output}.cms", "-inform", "DER",
  84. "-CAfile", $smroot, "-out", "{output}.txt" ],
  85. \&final_compare
  86. ],
  87. [ "signed detached content DER format, DSA key",
  88. [ "{cmd1}", @prov, "-sign", "-in", $smcont, "-outform", "DER",
  89. "-signer", catfile($smdir, "smdsa1.pem"), "-out", "{output}.cms" ],
  90. [ "{cmd2}", @prov, "-verify", "-in", "{output}.cms", "-inform", "DER",
  91. "-CAfile", $smroot, "-out", "{output}.txt",
  92. "-content", $smcont ],
  93. \&final_compare
  94. ],
  95. [ "signed detached content DER format, add RSA signer (with DSA existing)",
  96. [ "{cmd1}", @prov, "-sign", "-in", $smcont, "-outform", "DER",
  97. "-signer", catfile($smdir, "smdsa1.pem"), "-out", "{output}.cms" ],
  98. [ "{cmd1}", @prov, "-resign", "-in", "{output}.cms", "-inform", "DER", "-outform", "DER",
  99. "-signer", $smrsa1, "-out", "{output}2.cms" ],
  100. [ "{cmd2}", @prov, "-verify", "-in", "{output}2.cms", "-inform", "DER",
  101. "-CAfile", $smroot, "-out", "{output}.txt",
  102. "-content", $smcont ],
  103. \&final_compare
  104. ],
  105. [ "signed content test streaming BER format, DSA key",
  106. [ "{cmd1}", @prov, "-sign", "-in", $smcont, "-outform", "DER",
  107. "-nodetach", "-stream",
  108. "-signer", catfile($smdir, "smdsa1.pem"), "-out", "{output}.cms" ],
  109. [ "{cmd2}", @prov, "-verify", "-in", "{output}.cms", "-inform", "DER",
  110. "-CAfile", $smroot, "-out", "{output}.txt" ],
  111. \&final_compare
  112. ],
  113. [ "signed content test streaming BER format, 2 DSA and 2 RSA keys",
  114. [ "{cmd1}", @prov, "-sign", "-in", $smcont, "-outform", "DER",
  115. "-nodetach", "-stream",
  116. "-signer", $smrsa1,
  117. "-signer", catfile($smdir, "smrsa2.pem"),
  118. "-signer", catfile($smdir, "smdsa1.pem"),
  119. "-signer", catfile($smdir, "smdsa2.pem"),
  120. "-out", "{output}.cms" ],
  121. [ "{cmd2}", @prov, "-verify", "-in", "{output}.cms", "-inform", "DER",
  122. "-CAfile", $smroot, "-out", "{output}.txt" ],
  123. \&final_compare
  124. ],
  125. [ "signed content test streaming BER format, 2 DSA and 2 RSA keys, no attributes",
  126. [ "{cmd1}", @prov, "-sign", "-in", $smcont, "-outform", "DER",
  127. "-noattr", "-nodetach", "-stream",
  128. "-signer", $smrsa1,
  129. "-signer", catfile($smdir, "smrsa2.pem"),
  130. "-signer", catfile($smdir, "smdsa1.pem"),
  131. "-signer", catfile($smdir, "smdsa2.pem"),
  132. "-out", "{output}.cms" ],
  133. [ "{cmd2}", @prov, "-verify", "-in", "{output}.cms", "-inform", "DER",
  134. "-CAfile", $smroot, "-out", "{output}.txt" ],
  135. \&final_compare
  136. ],
  137. [ "signed content S/MIME format, RSA key SHA1",
  138. [ "{cmd1}", @defaultprov, "-sign", "-in", $smcont, "-md", "sha1",
  139. "-certfile", $smroot,
  140. "-signer", $smrsa1, "-out", "{output}.cms" ],
  141. [ "{cmd2}", @prov, "-verify", "-in", "{output}.cms",
  142. "-CAfile", $smroot, "-out", "{output}.txt" ],
  143. \&final_compare
  144. ],
  145. [ "signed zero-length content S/MIME format, RSA key SHA1",
  146. [ "{cmd1}", @defaultprov, "-sign", "-in", $smcont_zero, "-md", "sha1",
  147. "-certfile", $smroot, "-signer", $smrsa1, "-out", "{output}.cms" ],
  148. [ "{cmd2}", @prov, "-verify", "-in", "{output}.cms",
  149. "-CAfile", $smroot, "-out", "{output}.txt" ],
  150. \&zero_compare
  151. ],
  152. [ "signed content test streaming S/MIME format, 2 DSA and 2 RSA keys",
  153. [ "{cmd1}", @prov, "-sign", "-in", $smcont, "-nodetach",
  154. "-signer", $smrsa1,
  155. "-signer", catfile($smdir, "smrsa2.pem"),
  156. "-signer", catfile($smdir, "smdsa1.pem"),
  157. "-signer", catfile($smdir, "smdsa2.pem"),
  158. "-stream", "-out", "{output}.cms" ],
  159. [ "{cmd2}", @prov, "-verify", "-in", "{output}.cms",
  160. "-CAfile", $smroot, "-out", "{output}.txt" ],
  161. \&final_compare
  162. ],
  163. [ "signed content test streaming multipart S/MIME format, 2 DSA and 2 RSA keys",
  164. [ "{cmd1}", @prov, "-sign", "-in", $smcont,
  165. "-signer", $smrsa1,
  166. "-signer", catfile($smdir, "smrsa2.pem"),
  167. "-signer", catfile($smdir, "smdsa1.pem"),
  168. "-signer", catfile($smdir, "smdsa2.pem"),
  169. "-stream", "-out", "{output}.cms" ],
  170. [ "{cmd2}", @prov, "-verify", "-in", "{output}.cms",
  171. "-CAfile", $smroot, "-out", "{output}.txt" ],
  172. \&final_compare
  173. ],
  174. [ "enveloped content test streaming S/MIME format, DES, 3 recipients",
  175. [ "{cmd1}", @defaultprov, "-encrypt", "-in", $smcont,
  176. "-stream", "-out", "{output}.cms",
  177. $smrsa1,
  178. catfile($smdir, "smrsa2.pem"),
  179. catfile($smdir, "smrsa3.pem") ],
  180. [ "{cmd2}", @defaultprov, "-decrypt", "-recip", $smrsa1,
  181. "-in", "{output}.cms", "-out", "{output}.txt" ],
  182. \&final_compare
  183. ],
  184. [ "enveloped content test streaming S/MIME format, DES, 3 recipients, 3rd used",
  185. [ "{cmd1}", @defaultprov, "-encrypt", "-in", $smcont,
  186. "-stream", "-out", "{output}.cms",
  187. $smrsa1,
  188. catfile($smdir, "smrsa2.pem"),
  189. catfile($smdir, "smrsa3.pem") ],
  190. [ "{cmd2}", @defaultprov, "-decrypt", "-recip", catfile($smdir, "smrsa3.pem"),
  191. "-in", "{output}.cms", "-out", "{output}.txt" ],
  192. \&final_compare
  193. ],
  194. [ "enveloped content test streaming S/MIME format, DES, 3 recipients, cert and key files used",
  195. [ "{cmd1}", @defaultprov, "-encrypt", "-in", $smcont,
  196. "-stream", "-out", "{output}.cms",
  197. $smrsa1,
  198. catfile($smdir, "smrsa2.pem"),
  199. catfile($smdir, "smrsa3-cert.pem") ],
  200. [ "{cmd2}", @defaultprov, "-decrypt",
  201. "-recip", catfile($smdir, "smrsa3-cert.pem"),
  202. "-inkey", catfile($smdir, "smrsa3-key.pem"),
  203. "-in", "{output}.cms", "-out", "{output}.txt" ],
  204. \&final_compare
  205. ],
  206. [ "enveloped content test streaming S/MIME format, AES-256 cipher, 3 recipients",
  207. [ "{cmd1}", @prov, "-encrypt", "-in", $smcont,
  208. "-aes256", "-stream", "-out", "{output}.cms",
  209. $smrsa1,
  210. catfile($smdir, "smrsa2.pem"),
  211. catfile($smdir, "smrsa3.pem") ],
  212. [ "{cmd2}", @prov, "-decrypt", "-recip", $smrsa1,
  213. "-in", "{output}.cms", "-out", "{output}.txt" ],
  214. \&final_compare
  215. ],
  216. );
  217. my @smime_cms_tests = (
  218. [ "signed content test streaming BER format, 2 DSA and 2 RSA keys, keyid",
  219. [ "{cmd1}", @prov, "-sign", "-in", $smcont, "-outform", "DER",
  220. "-nodetach", "-keyid",
  221. "-signer", $smrsa1,
  222. "-signer", catfile($smdir, "smrsa2.pem"),
  223. "-signer", catfile($smdir, "smdsa1.pem"),
  224. "-signer", catfile($smdir, "smdsa2.pem"),
  225. "-stream", "-out", "{output}.cms" ],
  226. [ "{cmd2}", @prov, "-verify", "-in", "{output}.cms", "-inform", "DER",
  227. "-CAfile", $smroot, "-out", "{output}.txt" ],
  228. \&final_compare
  229. ],
  230. [ "signed content test streaming PEM format, 2 DSA and 2 RSA keys",
  231. [ "{cmd1}", @prov, "-sign", "-in", $smcont, "-outform", "PEM", "-nodetach",
  232. "-signer", $smrsa1,
  233. "-signer", catfile($smdir, "smrsa2.pem"),
  234. "-signer", catfile($smdir, "smdsa1.pem"),
  235. "-signer", catfile($smdir, "smdsa2.pem"),
  236. "-stream", "-out", "{output}.cms" ],
  237. [ "{cmd2}", @prov, "-verify", "-in", "{output}.cms", "-inform", "PEM",
  238. "-CAfile", $smroot, "-out", "{output}.txt" ],
  239. \&final_compare
  240. ],
  241. [ "signed content MIME format, RSA key, signed receipt request",
  242. [ "{cmd1}", @prov, "-sign", "-in", $smcont, "-nodetach",
  243. "-signer", $smrsa1,
  244. "-receipt_request_to", "test\@openssl.org", "-receipt_request_all",
  245. "-out", "{output}.cms" ],
  246. [ "{cmd2}", @prov, "-verify", "-in", "{output}.cms",
  247. "-CAfile", $smroot, "-out", "{output}.txt" ],
  248. \&final_compare
  249. ],
  250. [ "signed receipt MIME format, RSA key",
  251. [ "{cmd1}", @prov, "-sign", "-in", $smcont, "-nodetach",
  252. "-signer", $smrsa1,
  253. "-receipt_request_to", "test\@openssl.org", "-receipt_request_all",
  254. "-out", "{output}.cms" ],
  255. [ "{cmd1}", @prov, "-sign_receipt", "-in", "{output}.cms",
  256. "-signer", catfile($smdir, "smrsa2.pem"), "-out", "{output}2.cms" ],
  257. [ "{cmd2}", @prov, "-verify_receipt", "{output}2.cms", "-in", "{output}.cms",
  258. "-CAfile", $smroot ]
  259. ],
  260. [ "enveloped content test streaming S/MIME format, DES, 3 recipients, keyid",
  261. [ "{cmd1}", @defaultprov, "-encrypt", "-in", $smcont,
  262. "-stream", "-out", "{output}.cms", "-keyid",
  263. $smrsa1,
  264. catfile($smdir, "smrsa2.pem"),
  265. catfile($smdir, "smrsa3.pem") ],
  266. [ "{cmd2}", @defaultprov, "-decrypt", "-recip", $smrsa1,
  267. "-in", "{output}.cms", "-out", "{output}.txt" ],
  268. \&final_compare
  269. ],
  270. [ "enveloped content test streaming PEM format, AES-256-CBC cipher, KEK",
  271. [ "{cmd1}", @prov, "-encrypt", "-in", $smcont, "-outform", "PEM", "-aes128",
  272. "-stream", "-out", "{output}.cms",
  273. "-secretkey", "000102030405060708090A0B0C0D0E0F",
  274. "-secretkeyid", "C0FEE0" ],
  275. [ "{cmd2}", @prov, "-decrypt", "-in", "{output}.cms", "-out", "{output}.txt",
  276. "-inform", "PEM",
  277. "-secretkey", "000102030405060708090A0B0C0D0E0F",
  278. "-secretkeyid", "C0FEE0" ],
  279. \&final_compare
  280. ],
  281. [ "enveloped content test streaming PEM format, AES-256-GCM cipher, KEK",
  282. [ "{cmd1}", @prov, "-encrypt", "-in", $smcont, "-outform", "PEM", "-aes-128-gcm",
  283. "-stream", "-out", "{output}.cms",
  284. "-secretkey", "000102030405060708090A0B0C0D0E0F",
  285. "-secretkeyid", "C0FEE0" ],
  286. [ "{cmd2}", "-decrypt", "-in", "{output}.cms", "-out", "{output}.txt",
  287. "-inform", "PEM",
  288. "-secretkey", "000102030405060708090A0B0C0D0E0F",
  289. "-secretkeyid", "C0FEE0" ],
  290. \&final_compare
  291. ],
  292. [ "enveloped content test streaming PEM format, KEK, key only",
  293. [ "{cmd1}", @prov, "-encrypt", "-in", $smcont, "-outform", "PEM", "-aes128",
  294. "-stream", "-out", "{output}.cms",
  295. "-secretkey", "000102030405060708090A0B0C0D0E0F",
  296. "-secretkeyid", "C0FEE0" ],
  297. [ "{cmd2}", @prov, "-decrypt", "-in", "{output}.cms", "-out", "{output}.txt",
  298. "-inform", "PEM",
  299. "-secretkey", "000102030405060708090A0B0C0D0E0F" ],
  300. \&final_compare
  301. ],
  302. [ "data content test streaming PEM format",
  303. [ "{cmd1}", @prov, "-data_create", "-in", $smcont, "-outform", "PEM",
  304. "-nodetach", "-stream", "-out", "{output}.cms" ],
  305. [ "{cmd2}", @prov, "-data_out", "-in", "{output}.cms", "-inform", "PEM",
  306. "-out", "{output}.txt" ],
  307. \&final_compare
  308. ],
  309. [ "encrypted content test streaming PEM format, 128 bit RC2 key",
  310. [ "{cmd1}", @legacyprov, "-EncryptedData_encrypt",
  311. "-in", $smcont, "-outform", "PEM",
  312. "-rc2", "-secretkey", "000102030405060708090A0B0C0D0E0F",
  313. "-stream", "-out", "{output}.cms" ],
  314. [ "{cmd2}", @legacyprov, "-EncryptedData_decrypt", "-in", "{output}.cms",
  315. "-inform", "PEM",
  316. "-secretkey", "000102030405060708090A0B0C0D0E0F",
  317. "-out", "{output}.txt" ],
  318. \&final_compare
  319. ],
  320. [ "encrypted content test streaming PEM format, 40 bit RC2 key",
  321. [ "{cmd1}", @legacyprov, "-EncryptedData_encrypt",
  322. "-in", $smcont, "-outform", "PEM",
  323. "-rc2", "-secretkey", "0001020304",
  324. "-stream", "-out", "{output}.cms" ],
  325. [ "{cmd2}", @legacyprov, "-EncryptedData_decrypt", "-in", "{output}.cms",
  326. "-inform", "PEM",
  327. "-secretkey", "0001020304", "-out", "{output}.txt" ],
  328. \&final_compare
  329. ],
  330. [ "encrypted content test streaming PEM format, triple DES key",
  331. [ "{cmd1}", @prov, "-EncryptedData_encrypt", "-in", $smcont, "-outform", "PEM",
  332. "-des3", "-secretkey", "000102030405060708090A0B0C0D0E0F1011121314151617",
  333. "-stream", "-out", "{output}.cms" ],
  334. [ "{cmd2}", @prov, "-EncryptedData_decrypt", "-in", "{output}.cms",
  335. "-inform", "PEM",
  336. "-secretkey", "000102030405060708090A0B0C0D0E0F1011121314151617",
  337. "-out", "{output}.txt" ],
  338. \&final_compare
  339. ],
  340. [ "encrypted content test streaming PEM format, 128 bit AES key",
  341. [ "{cmd1}", @prov, "-EncryptedData_encrypt", "-in", $smcont, "-outform", "PEM",
  342. "-aes128", "-secretkey", "000102030405060708090A0B0C0D0E0F",
  343. "-stream", "-out", "{output}.cms" ],
  344. [ "{cmd2}", @prov, "-EncryptedData_decrypt", "-in", "{output}.cms",
  345. "-inform", "PEM",
  346. "-secretkey", "000102030405060708090A0B0C0D0E0F",
  347. "-out", "{output}.txt" ],
  348. \&final_compare
  349. ],
  350. [ "encrypted content test streaming PEM format -noout, 128 bit AES key",
  351. [ "{cmd1}", @prov, "-EncryptedData_encrypt", "-in", $smcont, "-outform", "PEM",
  352. "-aes128", "-secretkey", "000102030405060708090A0B0C0D0E0F",
  353. "-stream", "-noout" ],
  354. [ "{cmd2}", @prov, "-help" ]
  355. ],
  356. );
  357. my @smime_cms_cades_tests = (
  358. [ "signed content DER format, RSA key, CAdES-BES compatible",
  359. [ "{cmd1}", @prov, "-sign", "-cades", "-in", $smcont, "-outform", "DER",
  360. "-nodetach",
  361. "-certfile", $smroot, "-signer", $smrsa1, "-out", "{output}.cms" ],
  362. [ "{cmd2}", @prov, "-verify", "-cades", "-in", "{output}.cms", "-inform", "DER",
  363. "-CAfile", $smroot, "-out", "{output}.txt" ],
  364. \&final_compare
  365. ],
  366. [ "signed content DER format, RSA key, SHA256 md, CAdES-BES compatible",
  367. [ "{cmd1}", @prov, "-sign", "-cades", "-md", "sha256", "-in", $smcont, "-outform",
  368. "DER", "-nodetach", "-certfile", $smroot,
  369. "-signer", $smrsa1, "-out", "{output}.cms" ],
  370. [ "{cmd2}", @prov, "-verify", "-cades", "-in", "{output}.cms", "-inform", "DER",
  371. "-CAfile", $smroot, "-out", "{output}.txt" ],
  372. \&final_compare
  373. ],
  374. [ "signed content DER format, RSA key, SHA512 md, CAdES-BES compatible",
  375. [ "{cmd1}", @prov, "-sign", "-cades", "-md", "sha512", "-in", $smcont, "-outform",
  376. "DER", "-nodetach", "-certfile", $smroot,
  377. "-signer", $smrsa1, "-out", "{output}.cms" ],
  378. [ "{cmd2}", @prov, "-verify", "-cades", "-in", "{output}.cms", "-inform", "DER",
  379. "-CAfile", $smroot, "-out", "{output}.txt" ],
  380. \&final_compare
  381. ],
  382. [ "signed content DER format, RSA key, SHA256 md, CAdES-BES compatible",
  383. [ "{cmd1}", @prov, "-sign", "-cades", "-binary", "-nodetach", "-nosmimecap", "-md", "sha256",
  384. "-in", $smcont, "-outform", "DER",
  385. "-certfile", $smroot, "-signer", $smrsa1,
  386. "-outform", "DER", "-out", "{output}.cms" ],
  387. [ "{cmd2}", @prov, "-verify", "-cades", "-in", "{output}.cms", "-inform", "DER",
  388. "-CAfile", $smroot, "-out", "{output}.txt" ],
  389. \&final_compare
  390. ],
  391. [ "resigned content DER format, RSA key, SHA256 md, CAdES-BES compatible",
  392. [ "{cmd1}", @prov, "-sign", "-cades", "-binary", "-nodetach", "-nosmimecap", "-md", "sha256",
  393. "-in", $smcont, "-outform", "DER",
  394. "-certfile", $smroot, "-signer", $smrsa1,
  395. "-outform", "DER", "-out", "{output}.cms" ],
  396. [ "{cmd1}", @prov, "-resign", "-cades", "-binary", "-nodetach", "-nosmimecap", "-md", "sha256",
  397. "-inform", "DER", "-in", "{output}.cms",
  398. "-certfile", $smroot, "-signer", catfile($smdir, "smrsa2.pem"),
  399. "-outform", "DER", "-out", "{output}2.cms" ],
  400. [ "{cmd2}", @prov, "-verify", "-cades", "-in", "{output}2.cms", "-inform", "DER",
  401. "-CAfile", $smroot, "-out", "{output}.txt" ],
  402. \&final_compare
  403. ],
  404. );
  405. my @smime_cms_cades_ko_tests = (
  406. [ "sign content DER format, RSA key, not CAdES-BES compatible",
  407. [ @prov, "-sign", "-in", $smcont, "-outform", "DER", "-nodetach",
  408. "-certfile", $smroot, "-signer", $smrsa1, "-out", "cades-ko.cms" ],
  409. "fail to verify token since requiring CAdES-BES compatibility",
  410. [ @prov, "-verify", "-cades", "-in", "cades-ko.cms", "-inform", "DER",
  411. "-CAfile", $smroot, "-out", "cades-ko.txt" ],
  412. \&final_compare
  413. ]
  414. );
  415. # cades options test - check that some combinations are rejected
  416. my @smime_cms_cades_invalid_option_tests = (
  417. [
  418. [ "-cades", "-noattr" ],
  419. ],[
  420. [ "-verify", "-cades", "-noattr" ],
  421. ],[
  422. [ "-verify", "-cades", "-noverify" ],
  423. ],
  424. );
  425. my @smime_cms_comp_tests = (
  426. [ "compressed content test streaming PEM format",
  427. [ "{cmd1}", @prov, "-compress", "-in", $smcont, "-outform", "PEM", "-nodetach",
  428. "-stream", "-out", "{output}.cms" ],
  429. [ "{cmd2}", @prov, "-uncompress", "-in", "{output}.cms", "-inform", "PEM",
  430. "-out", "{output}.txt" ],
  431. \&final_compare
  432. ]
  433. );
  434. my @smime_cms_param_tests = (
  435. [ "signed content test streaming PEM format, RSA keys, PSS signature",
  436. [ "{cmd1}", @prov, "-sign", "-in", $smcont, "-outform", "PEM", "-nodetach",
  437. "-signer", $smrsa1,
  438. "-keyopt", "rsa_padding_mode:pss",
  439. "-out", "{output}.cms" ],
  440. [ "{cmd2}", @prov, "-verify", "-in", "{output}.cms", "-inform", "PEM",
  441. "-CAfile", $smroot, "-out", "{output}.txt" ],
  442. \&final_compare
  443. ],
  444. [ "signed content test streaming PEM format, RSA keys, PSS signature, saltlen=max",
  445. [ "{cmd1}", @prov, "-sign", "-in", $smcont, "-outform", "PEM", "-nodetach",
  446. "-signer", $smrsa1,
  447. "-keyopt", "rsa_padding_mode:pss", "-keyopt", "rsa_pss_saltlen:max",
  448. "-out", "{output}.cms" ],
  449. sub { my %opts = @_; rsapssSaltlen("$opts{output}.cms") == 222; },
  450. [ "{cmd2}", @prov, "-verify", "-in", "{output}.cms", "-inform", "PEM",
  451. "-CAfile", $smroot, "-out", "{output}.txt" ],
  452. \&final_compare
  453. ],
  454. [ "signed content test streaming PEM format, RSA keys, PSS signature, no attributes",
  455. [ "{cmd1}", @prov, "-sign", "-in", $smcont, "-outform", "PEM", "-nodetach",
  456. "-noattr", "-signer", $smrsa1,
  457. "-keyopt", "rsa_padding_mode:pss",
  458. "-out", "{output}.cms" ],
  459. [ "{cmd2}", @prov, "-verify", "-in", "{output}.cms", "-inform", "PEM",
  460. "-CAfile", $smroot, "-out", "{output}.txt" ],
  461. \&final_compare
  462. ],
  463. [ "signed content test streaming PEM format, RSA keys, PSS signature, SHA384 MGF1",
  464. [ "{cmd1}", @prov, "-sign", "-in", $smcont, "-outform", "PEM", "-nodetach",
  465. "-signer", $smrsa1,
  466. "-keyopt", "rsa_padding_mode:pss", "-keyopt", "rsa_mgf1_md:sha384",
  467. "-out", "{output}.cms" ],
  468. [ "{cmd2}", @prov, "-verify", "-in", "{output}.cms", "-inform", "PEM",
  469. "-CAfile", $smroot, "-out", "{output}.txt" ],
  470. \&final_compare
  471. ],
  472. [ "signed content test streaming PEM format, RSA keys, PSS signature, saltlen=16",
  473. [ "{cmd1}", @prov, "-sign", "-in", $smcont, "-outform", "PEM", "-nodetach",
  474. "-signer", $smrsa1, "-md", "sha256",
  475. "-keyopt", "rsa_padding_mode:pss", "-keyopt", "rsa_pss_saltlen:16",
  476. "-out", "{output}.cms" ],
  477. sub { my %opts = @_; rsapssSaltlen("$opts{output}.cms") == 16; },
  478. [ "{cmd2}", @prov, "-verify", "-in", "{output}.cms", "-inform", "PEM",
  479. "-CAfile", $smroot, "-out", "{output}.txt" ],
  480. \&final_compare
  481. ],
  482. [ "signed content test streaming PEM format, RSA keys, PSS signature, saltlen=digest",
  483. [ "{cmd1}", @prov, "-sign", "-in", $smcont, "-outform", "PEM", "-nodetach",
  484. "-signer", $smrsa1, "-md", "sha256",
  485. "-keyopt", "rsa_padding_mode:pss", "-keyopt", "rsa_pss_saltlen:digest",
  486. "-out", "{output}.cms" ],
  487. # digest is SHA-256, which produces 32 bytes of output
  488. sub { my %opts = @_; rsapssSaltlen("$opts{output}.cms") == 32; },
  489. [ "{cmd2}", @prov, "-verify", "-in", "{output}.cms", "-inform", "PEM",
  490. "-CAfile", $smroot, "-out", "{output}.txt" ],
  491. \&final_compare
  492. ],
  493. [ "enveloped content test streaming S/MIME format, DES, OAEP default parameters",
  494. [ "{cmd1}", @defaultprov, "-encrypt", "-in", $smcont,
  495. "-stream", "-out", "{output}.cms",
  496. "-recip", $smrsa1,
  497. "-keyopt", "rsa_padding_mode:oaep" ],
  498. [ "{cmd2}", @defaultprov, "-decrypt", "-recip", $smrsa1,
  499. "-in", "{output}.cms", "-out", "{output}.txt" ],
  500. \&final_compare
  501. ],
  502. [ "enveloped content test streaming S/MIME format, DES, OAEP SHA256",
  503. [ "{cmd1}", @defaultprov, "-encrypt", "-in", $smcont,
  504. "-stream", "-out", "{output}.cms",
  505. "-recip", $smrsa1,
  506. "-keyopt", "rsa_padding_mode:oaep",
  507. "-keyopt", "rsa_oaep_md:sha256" ],
  508. [ "{cmd2}", @defaultprov, "-decrypt", "-recip", $smrsa1,
  509. "-in", "{output}.cms", "-out", "{output}.txt" ],
  510. \&final_compare
  511. ],
  512. [ "enveloped content test streaming S/MIME format, DES, ECDH",
  513. [ "{cmd1}", @defaultprov, "-encrypt", "-in", $smcont,
  514. "-stream", "-out", "{output}.cms",
  515. "-recip", catfile($smdir, "smec1.pem") ],
  516. [ "{cmd2}", @defaultprov, "-decrypt", "-recip", catfile($smdir, "smec1.pem"),
  517. "-in", "{output}.cms", "-out", "{output}.txt" ],
  518. \&final_compare
  519. ],
  520. [ "enveloped content test streaming S/MIME format, DES, ECDH, 2 recipients, key only used",
  521. [ "{cmd1}", @defaultprov, "-encrypt", "-in", $smcont,
  522. "-stream", "-out", "{output}.cms",
  523. catfile($smdir, "smec1.pem"),
  524. catfile($smdir, "smec3.pem") ],
  525. [ "{cmd2}", @defaultprov, "-decrypt", "-inkey", catfile($smdir, "smec3.pem"),
  526. "-in", "{output}.cms", "-out", "{output}.txt" ],
  527. \&final_compare
  528. ],
  529. [ "enveloped content test streaming S/MIME format, ECDH, DES, key identifier",
  530. [ "{cmd1}", @defaultprov, "-encrypt", "-keyid", "-in", $smcont,
  531. "-stream", "-out", "{output}.cms",
  532. "-recip", catfile($smdir, "smec1.pem") ],
  533. [ "{cmd2}", @defaultprov, "-decrypt", "-recip", catfile($smdir, "smec1.pem"),
  534. "-in", "{output}.cms", "-out", "{output}.txt" ],
  535. \&final_compare
  536. ],
  537. [ "enveloped content test streaming S/MIME format, ECDH, AES-128-CBC, SHA256 KDF",
  538. [ "{cmd1}", @prov, "-encrypt", "-in", $smcont,
  539. "-stream", "-out", "{output}.cms",
  540. "-recip", catfile($smdir, "smec1.pem"), "-aes128",
  541. "-keyopt", "ecdh_kdf_md:sha256" ],
  542. sub { my %opts = @_; smimeType_matches("$opts{output}.cms", "enveloped-data"); },
  543. [ "{cmd2}", @prov, "-decrypt", "-recip", catfile($smdir, "smec1.pem"),
  544. "-in", "{output}.cms", "-out", "{output}.txt" ],
  545. \&final_compare
  546. ],
  547. [ "enveloped content test streaming S/MIME format, ECDH, AES-128-GCM cipher, SHA256 KDF",
  548. [ "{cmd1}", @prov, "-encrypt", "-in", $smcont,
  549. "-stream", "-out", "{output}.cms",
  550. "-recip", catfile($smdir, "smec1.pem"), "-aes-128-gcm", "-keyopt", "ecdh_kdf_md:sha256" ],
  551. sub { my %opts = @_; smimeType_matches("$opts{output}.cms", "authEnveloped-data"); },
  552. [ "{cmd2}", "-decrypt", "-recip", catfile($smdir, "smec1.pem"),
  553. "-in", "{output}.cms", "-out", "{output}.txt" ],
  554. \&final_compare
  555. ],
  556. [ "enveloped content test streaming S/MIME format, ECDH, K-283, cofactor DH",
  557. [ "{cmd1}", @prov, "-encrypt", "-in", $smcont,
  558. "-stream", "-out", "{output}.cms",
  559. "-recip", catfile($smdir, "smec2.pem"), "-aes128",
  560. "-keyopt", "ecdh_kdf_md:sha256", "-keyopt", "ecdh_cofactor_mode:1" ],
  561. [ "{cmd2}", @prov, "-decrypt", "-recip", catfile($smdir, "smec2.pem"),
  562. "-in", "{output}.cms", "-out", "{output}.txt" ],
  563. \&final_compare
  564. ]
  565. );
  566. if ($no_fips || $old_fips) {
  567. # Only SHA1 supported in dh_cms_encrypt()
  568. push(@smime_cms_param_tests,
  569. [ "enveloped content test streaming S/MIME format, X9.42 DH",
  570. [ "{cmd1}", @prov, "-encrypt", "-in", $smcont,
  571. "-stream", "-out", "{output}.cms",
  572. "-recip", catfile($smdir, "smdh.pem"), "-aes128" ],
  573. [ "{cmd2}", @prov, "-decrypt", "-recip", catfile($smdir, "smdh.pem"),
  574. "-in", "{output}.cms", "-out", "{output}.txt" ],
  575. \&final_compare
  576. ]
  577. );
  578. }
  579. my @smime_cms_param_tests_autodigestmax = (
  580. [ "signed content test streaming PEM format, RSA keys, PSS signature, saltlen=auto-digestmax, digestsize < maximum salt length",
  581. [ "{cmd1}", @prov, "-sign", "-in", $smcont, "-outform", "PEM", "-nodetach",
  582. "-signer", $smrsa1, "-md", "sha256",
  583. "-keyopt", "rsa_padding_mode:pss", "-keyopt", "rsa_pss_saltlen:auto-digestmax",
  584. "-out", "{output}.cms" ],
  585. # digest is SHA-256, which produces 32, bytes of output
  586. sub { my %opts = @_; rsapssSaltlen("$opts{output}.cms") == 32; },
  587. [ "{cmd2}", @defaultprov, "-verify", "-in", "{output}.cms", "-inform", "PEM",
  588. "-CAfile", $smroot, "-out", "{output}.txt" ],
  589. \&final_compare
  590. ],
  591. [ "signed content test streaming PEM format, RSA keys, PSS signature, saltlen=auto-digestmax, digestsize > maximum salt length",
  592. [ "{cmd1}", @defaultprov, "-sign", "-in", $smcont, "-outform", "PEM", "-nodetach",
  593. "-signer", $smrsa1024, "-md", "sha512",
  594. "-keyopt", "rsa_padding_mode:pss", "-keyopt", "rsa_pss_saltlen:auto-digestmax",
  595. "-out", "{output}.cms" ],
  596. # digest is SHA-512, which produces 64, bytes of output, but an RSA-PSS
  597. # signature with a 1024 bit RSA key can only accommodate 62
  598. sub { my %opts = @_; rsapssSaltlen("$opts{output}.cms") == 62; },
  599. [ "{cmd2}", @defaultprov, "-verify", "-in", "{output}.cms", "-inform", "PEM",
  600. "-CAfile", $smroot, "-out", "{output}.txt" ],
  601. \&final_compare
  602. ]
  603. );
  604. my @contenttype_cms_test = (
  605. [ "signed content test - check that content type is added to additional signerinfo, RSA keys",
  606. [ "{cmd1}", @prov, "-sign", "-binary", "-nodetach", "-stream", "-in", $smcont,
  607. "-outform", "DER", "-signer", $smrsa1, "-md", "SHA256",
  608. "-out", "{output}.cms" ],
  609. [ "{cmd1}", @prov, "-resign", "-binary", "-nodetach", "-in", "{output}.cms",
  610. "-inform", "DER", "-outform", "DER",
  611. "-signer", catfile($smdir, "smrsa2.pem"), "-md", "SHA256",
  612. "-out", "{output}2.cms" ],
  613. sub { my %opts = @_; contentType_matches("$opts{output}2.cms") == 2; },
  614. [ "{cmd2}", @prov, "-verify", "-in", "{output}2.cms", "-inform", "DER",
  615. "-CAfile", $smroot, "-out", "{output}.txt" ]
  616. ],
  617. );
  618. my @incorrect_attribute_cms_test = (
  619. "bad_signtime_attr.cms",
  620. "no_ct_attr.cms",
  621. "no_md_attr.cms",
  622. "ct_multiple_attr.cms"
  623. );
  624. # Runs a standard loop on the input array
  625. sub runner_loop {
  626. my %opts = ( @_ );
  627. my $cnt1 = 0;
  628. foreach (@{$opts{tests}}) {
  629. $cnt1++;
  630. $opts{output} = "$opts{prefix}-$cnt1";
  631. SKIP: {
  632. my $skip_reason = check_availability($$_[0]);
  633. skip $skip_reason, 1 if $skip_reason;
  634. my $ok = 1;
  635. 1 while unlink "$opts{output}.txt";
  636. foreach (@$_[1..$#$_]) {
  637. if (ref $_ eq 'CODE') {
  638. $ok &&= $_->(%opts);
  639. } else {
  640. my @cmd = map {
  641. my $x = $_;
  642. while ($x =~ /\{([^\}]+)\}/) {
  643. $x = $`.$opts{$1}.$' if exists $opts{$1};
  644. }
  645. $x;
  646. } @$_;
  647. diag "CMD: openssl ", join(" ", @cmd);
  648. $ok &&= run(app(["openssl", @cmd]));
  649. $opts{input} = $opts{output};
  650. }
  651. }
  652. ok($ok, $$_[0]);
  653. }
  654. }
  655. }
  656. sub final_compare {
  657. my %opts = @_;
  658. diag "Comparing $smcont with $opts{output}.txt";
  659. return compare_text($smcont, "$opts{output}.txt") == 0;
  660. }
  661. sub zero_compare {
  662. my %opts = @_;
  663. diag "Checking for zero-length file";
  664. return (-e "$opts{output}.txt" && -z "$opts{output}.txt");
  665. }
  666. subtest "CMS => PKCS#7 compatibility tests\n" => sub {
  667. plan tests => scalar @smime_pkcs7_tests;
  668. runner_loop(prefix => 'cms2pkcs7', cmd1 => 'cms', cmd2 => 'smime',
  669. tests => [ @smime_pkcs7_tests ]);
  670. };
  671. subtest "CMS <= PKCS#7 compatibility tests\n" => sub {
  672. plan tests => scalar @smime_pkcs7_tests;
  673. runner_loop(prefix => 'pkcs72cms', cmd1 => 'smime', cmd2 => 'cms',
  674. tests => [ @smime_pkcs7_tests ]);
  675. };
  676. subtest "CMS <=> CMS consistency tests\n" => sub {
  677. plan tests => (scalar @smime_pkcs7_tests) + (scalar @smime_cms_tests);
  678. runner_loop(prefix => 'cms2cms-1', cmd1 => 'cms', cmd2 => 'cms',
  679. tests => [ @smime_pkcs7_tests ]);
  680. runner_loop(prefix => 'cms2cms-2', cmd1 => 'cms', cmd2 => 'cms',
  681. tests => [ @smime_cms_tests ]);
  682. };
  683. subtest "CMS <=> CMS consistency tests, modified key parameters\n" => sub {
  684. plan tests =>
  685. (scalar @smime_cms_param_tests) + (scalar @smime_cms_comp_tests) +
  686. (scalar @smime_cms_param_tests_autodigestmax) + 1;
  687. ok(run(app(["openssl", "cms", @prov,
  688. "-sign", "-in", $smcont,
  689. "-outform", "PEM",
  690. "-nodetach",
  691. "-signer", $smrsa1,
  692. "-keyopt", "rsa_padding_mode:pss",
  693. "-keyopt", "rsa_pss_saltlen:auto-digestmax",
  694. "-out", "digestmaxtest.cms"])));
  695. # Providers that do not support rsa_pss_saltlen:auto-digestmax will parse
  696. # it as 0
  697. my $no_autodigestmax = rsapssSaltlen("digestmaxtest.cms") == 0;
  698. 1 while unlink "digestmaxtest.cms";
  699. runner_loop(prefix => 'cms2cms-mod', cmd1 => 'cms', cmd2 => 'cms',
  700. tests => [ @smime_cms_param_tests ]);
  701. SKIP: {
  702. skip("Zlib not supported: compression tests skipped",
  703. scalar @smime_cms_comp_tests)
  704. if $no_zlib;
  705. runner_loop(prefix => 'cms2cms-comp', cmd1 => 'cms', cmd2 => 'cms',
  706. tests => [ @smime_cms_comp_tests ]);
  707. }
  708. SKIP: {
  709. skip("rsa_pss_saltlen:auto-digestmax not supported",
  710. scalar @smime_cms_param_tests_autodigestmax)
  711. if $no_autodigestmax;
  712. runner_loop(prefix => 'cms2cms-comp', 'cmd1' => 'cms', cmd2 => 'cms',
  713. tests => [ @smime_cms_param_tests_autodigestmax ]);
  714. }
  715. };
  716. # Returns the number of matches of a Content Type Attribute in a binary file.
  717. sub contentType_matches {
  718. # Read in a binary file
  719. my ($in) = @_;
  720. open (HEX_IN, "$in") or die("open failed for $in : $!");
  721. binmode(HEX_IN);
  722. local $/;
  723. my $str = <HEX_IN>;
  724. # Find ASN1 data for a Content Type Attribute (with a OID of PKCS7 data)
  725. my @c = $str =~ /\x30\x18\x06\x09\x2A\x86\x48\x86\xF7\x0D\x01\x09\x03\x31\x0B\x06\x09\x2A\x86\x48\x86\xF7\x0D\x01\x07\x01/gs;
  726. close(HEX_IN);
  727. return scalar(@c);
  728. }
  729. # Returns 1 if the smime-type matches the passed parameter, otherwise 0.
  730. sub smimeType_matches {
  731. my ($in, $expected_smime_type) = @_;
  732. # Read the text file
  733. open(my $fh, '<', $in) or die("open failed for $in : $!");
  734. local $/;
  735. my $content = <$fh>;
  736. close($fh);
  737. # Extract the Content-Type line with the smime-type attribute
  738. if ($content =~ /Content-Type:\s*application\/pkcs7-mime.*smime-type=([^\s;]+)/) {
  739. my $smime_type = $1;
  740. # Compare the extracted smime-type with the expected value
  741. return ($smime_type eq $expected_smime_type) ? 1 : 0;
  742. }
  743. # If no smime-type is found, return 0
  744. return 0;
  745. }
  746. sub rsapssSaltlen {
  747. my ($in) = @_;
  748. my $exit = 0;
  749. my @asn1parse = run(app(["openssl", "asn1parse", "-in", $in, "-dump"]),
  750. capture => 1,
  751. statusvar => $exit);
  752. return -1 if $exit != 0;
  753. my $pssparam_offset = -1;
  754. while ($_ = shift @asn1parse) {
  755. chomp;
  756. next unless /:rsassaPss/;
  757. # This line contains :rsassaPss, the next line contains a raw dump of the
  758. # RSA_PSS_PARAMS sequence; obtain its offset
  759. $_ = shift @asn1parse;
  760. if (/^\s*(\d+):/) {
  761. $pssparam_offset = int($1);
  762. }
  763. }
  764. if ($pssparam_offset == -1) {
  765. note "Failed to determine RSA_PSS_PARAM offset in CMS. " +
  766. "Was the file correctly signed with RSASSA-PSS?";
  767. return -1;
  768. }
  769. my @pssparam = run(app(["openssl", "asn1parse", "-in", $in,
  770. "-strparse", $pssparam_offset]),
  771. capture => 1,
  772. statusvar => $exit);
  773. return -1 if $exit != 0;
  774. my $saltlen = -1;
  775. # Can't use asn1parse -item RSA_PSS_PARAMS here, because that's deprecated.
  776. # This assumes the salt length is the last field, which may possibly be
  777. # incorrect if there is a non-standard trailer field, but there almost never
  778. # is in PSS.
  779. if ($pssparam[-1] =~ /prim:\s+INTEGER\s+:([A-Fa-f0-9]+)/) {
  780. $saltlen = hex($1);
  781. }
  782. if ($saltlen == -1) {
  783. note "Failed to determine salt length from RSA_PSS_PARAM struct. " +
  784. "Was the file correctly signed with RSASSA-PSS?";
  785. return -1;
  786. }
  787. return $saltlen;
  788. }
  789. subtest "CMS Check the content type attribute is added for additional signers\n" => sub {
  790. plan tests => (scalar @contenttype_cms_test);
  791. runner_loop(prefix => 'cms2cms-added', cmd1 => 'cms', cmd2 => 'cms',
  792. tests => [ @contenttype_cms_test ]);
  793. };
  794. subtest "CMS Check that bad attributes fail when verifying signers\n" => sub {
  795. plan tests =>
  796. (scalar @incorrect_attribute_cms_test);
  797. my $cnt = 0;
  798. foreach my $name (@incorrect_attribute_cms_test) {
  799. my $out = "incorrect-$cnt.txt";
  800. ok(!run(app(["openssl", "cms", @prov, "-verify", "-in",
  801. catfile($datadir, $name), "-inform", "DER", "-CAfile",
  802. $smroot, "-out", $out ])),
  803. $name);
  804. }
  805. };
  806. subtest "CMS Check that bad encryption algorithm fails\n" => sub {
  807. plan tests => 1;
  808. SKIP: {
  809. skip "DES or Legacy isn't supported in this build", 1
  810. if disabled("des") || disabled("legacy");
  811. my $out = "smtst.txt";
  812. ok(!run(app(["openssl", "cms", @legacyprov, "-encrypt",
  813. "-in", $smcont,
  814. "-stream", "-recip", $smrsa1,
  815. "-des-ede3",
  816. "-out", $out ])),
  817. "Decrypt message from OpenSSL 1.1.1");
  818. }
  819. };
  820. subtest "CMS Decrypt message encrypted with OpenSSL 1.1.1\n" => sub {
  821. plan tests => 1;
  822. SKIP: {
  823. skip "EC or DES isn't supported in this build", 1
  824. if disabled("ec") || disabled("des");
  825. my $out = "smtst.txt";
  826. ok(run(app(["openssl", "cms", @defaultprov, "-decrypt",
  827. "-inkey", catfile($smdir, "smec3.pem"),
  828. "-in", catfile($datadir, "ciphertext_from_1_1_1.cms"),
  829. "-out", $out ]))
  830. && compare_text($smcont, $out) == 0,
  831. "Decrypt message from OpenSSL 1.1.1");
  832. }
  833. };
  834. subtest "CAdES <=> CAdES consistency tests\n" => sub {
  835. plan tests => (scalar @smime_cms_cades_tests);
  836. runner_loop(prefix => 'cms-cades', cmd1 => 'cms', cmd2 => 'cms',
  837. tests => [ @smime_cms_cades_tests ]);
  838. };
  839. subtest "CAdES; cms incompatible arguments tests\n" => sub {
  840. plan tests => (scalar @smime_cms_cades_invalid_option_tests);
  841. foreach (@smime_cms_cades_invalid_option_tests) {
  842. ok(!run(app(["openssl", "cms", @{$$_[0]} ] )));
  843. }
  844. };
  845. subtest "CAdES ko tests\n" => sub {
  846. plan tests => 2 * scalar @smime_cms_cades_ko_tests;
  847. foreach (@smime_cms_cades_ko_tests) {
  848. SKIP: {
  849. my $skip_reason = check_availability($$_[0]);
  850. skip $skip_reason, 1 if $skip_reason;
  851. 1 while unlink "cades-ko.txt";
  852. ok(run(app(["openssl", "cms", @{$$_[1]}])), $$_[0]);
  853. ok(!run(app(["openssl", "cms", @{$$_[3]}])), $$_[2]);
  854. }
  855. }
  856. };
  857. subtest "CMS binary input tests\n" => sub {
  858. my $input = srctop_file("test", "smcont.bin");
  859. my $signed = "smcont.signed";
  860. my $verified = "smcont.verified";
  861. plan tests => 11;
  862. ok(run(app(["openssl", "cms", "-sign", "-md", "sha256", "-signer", $smrsa1,
  863. "-binary", "-in", $input, "-out", $signed])),
  864. "sign binary input with -binary");
  865. ok(run(app(["openssl", "cms", "-verify", "-CAfile", $smroot,
  866. "-binary", "-in", $signed, "-out", $verified])),
  867. "verify binary input with -binary");
  868. is(compare($input, $verified), 0, "binary input retained with -binary");
  869. ok(run(app(["openssl", "cms", "-sign", "-md", "sha256", "-signer", $smrsa1,
  870. "-in", $input, "-out", $signed.".nobin"])),
  871. "sign binary input without -binary");
  872. ok(run(app(["openssl", "cms", "-verify", "-CAfile", $smroot,
  873. "-in", $signed.".nobin", "-out", $verified.".nobin"])),
  874. "verify binary input without -binary");
  875. is(compare($input, $verified.".nobin"), 1, "binary input not retained without -binary");
  876. ok(!run(app(["openssl", "cms", "-verify", "-CAfile", $smroot, "-crlfeol",
  877. "-binary", "-in", $signed, "-out", $verified.".crlfeol"])),
  878. "verify binary input wrong crlfeol");
  879. ok(run(app(["openssl", "cms", "-sign", "-md", "sha256", "-signer", $smrsa1,
  880. "-crlfeol",
  881. "-binary", "-in", $input, "-out", $signed.".crlf"])),
  882. "sign binary input with -binary -crlfeol");
  883. ok(run(app(["openssl", "cms", "-verify", "-CAfile", $smroot, "-crlfeol",
  884. "-binary", "-in", $signed.".crlf", "-out", $verified.".crlf"])),
  885. "verify binary input with -binary -crlfeol");
  886. is(compare($input, $verified.".crlf"), 0,
  887. "binary input retained with -binary -crlfeol");
  888. ok(!run(app(["openssl", "cms", "-verify", "-CAfile", $smroot,
  889. "-binary", "-in", $signed.".crlf", "-out", $verified.".crlf2"])),
  890. "verify binary input with -binary missing -crlfeol");
  891. };
  892. subtest "CMS signed digest, DER format" => sub {
  893. plan tests => 2;
  894. # Pre-computed SHA256 digest of $smcont in hexadecimal form
  895. my $digest = "ff236ef61b396355f75a4cc6e1c306d4c309084ae271a9e2ad6888f10a101b32";
  896. my $sig_file = "signature.der";
  897. ok(run(app(["openssl", "cms", @prov, "-sign", "-digest", $digest,
  898. "-outform", "DER",
  899. "-certfile", catfile($smdir, "smroot.pem"),
  900. "-signer", catfile($smdir, "smrsa1.pem"),
  901. "-out", $sig_file])),
  902. "CMS sign pre-computed digest, DER format");
  903. ok(run(app(["openssl", "cms", @prov, "-verify", "-in", $sig_file,
  904. "-inform", "DER",
  905. "-CAfile", catfile($smdir, "smroot.pem"),
  906. "-content", $smcont])),
  907. "Verify CMS signed digest, DER format");
  908. };
  909. subtest "CMS signed digest, S/MIME format" => sub {
  910. plan tests => 2;
  911. # Pre-computed SHA256 digest of $smcont in hexadecimal form
  912. my $digest = "ff236ef61b396355f75a4cc6e1c306d4c309084ae271a9e2ad6888f10a101b32";
  913. my $sig_file = "signature.smime";
  914. ok(run(app(["openssl", "cms", @prov, "-sign", "-digest", $digest,
  915. "-outform", "SMIME",
  916. "-certfile", catfile($smdir, "smroot.pem"),
  917. "-signer", catfile($smdir, "smrsa1.pem"),
  918. "-out", $sig_file])),
  919. "CMS sign pre-computed digest, S/MIME format");
  920. ok(run(app(["openssl", "cms", @prov, "-verify", "-in", $sig_file,
  921. "-inform", "SMIME",
  922. "-CAfile", catfile($smdir, "smroot.pem"),
  923. "-content", $smcont])),
  924. "Verify CMS signed digest, S/MIME format");
  925. };
  926. subtest "CMS code signing test" => sub {
  927. plan tests => 7;
  928. my $sig_file = "signature.p7s";
  929. ok(run(app(["openssl", "cms", @prov, "-sign", "-in", $smcont,
  930. "-certfile", catfile($smdir, "smroot.pem"),
  931. "-signer", catfile($smdir, "smrsa1.pem"),
  932. "-out", $sig_file])),
  933. "accept perform CMS signature with smime certificate");
  934. ok(run(app(["openssl", "cms", @prov, "-verify", "-in", $sig_file,
  935. "-CAfile", catfile($smdir, "smroot.pem"),
  936. "-content", $smcont])),
  937. "accept verify CMS signature with smime certificate");
  938. ok(!run(app(["openssl", "cms", @prov, "-verify", "-in", $sig_file,
  939. "-CAfile", catfile($smdir, "smroot.pem"),
  940. "-purpose", "codesign",
  941. "-content", $smcont])),
  942. "fail verify CMS signature with smime certificate for purpose code signing");
  943. ok(!run(app(["openssl", "cms", @prov, "-verify", "-in", $sig_file,
  944. "-CAfile", catfile($smdir, "smroot.pem"),
  945. "-purpose", "football",
  946. "-content", $smcont])),
  947. "fail verify CMS signature with invalid purpose argument");
  948. ok(run(app(["openssl", "cms", @prov, "-sign", "-in", $smcont,
  949. "-certfile", catfile($smdir, "smroot.pem"),
  950. "-signer", catfile($smdir, "csrsa1.pem"),
  951. "-out", $sig_file])),
  952. "accept perform CMS signature with code signing certificate");
  953. ok(run(app(["openssl", "cms", @prov, "-verify", "-in", $sig_file,
  954. "-CAfile", catfile($smdir, "smroot.pem"),
  955. "-purpose", "codesign",
  956. "-content", $smcont])),
  957. "accept verify CMS signature with code signing certificate for purpose code signing");
  958. ok(!run(app(["openssl", "cms", @prov, "-verify", "-in", $sig_file,
  959. "-CAfile", catfile($smdir, "smroot.pem"),
  960. "-content", $smcont])),
  961. "fail verify CMS signature with code signing certificate for purpose smime_sign");
  962. };
  963. # Test case for missing MD algorithm (must not segfault)
  964. with({ exit_checker => sub { return shift == 4; } },
  965. sub {
  966. ok(run(app(['openssl', 'smime', '-verify', '-noverify',
  967. '-inform', 'PEM',
  968. '-in', data_file("pkcs7-md4.pem"),
  969. ])),
  970. "Check failure of EVP_DigestInit in PKCS7 signed is handled");
  971. ok(run(app(['openssl', 'smime', '-decrypt',
  972. '-inform', 'PEM',
  973. '-in', data_file("pkcs7-md4-encrypted.pem"),
  974. '-recip', srctop_file("test", "certs", "ee-cert.pem"),
  975. '-inkey', srctop_file("test", "certs", "ee-key.pem")
  976. ])),
  977. "Check failure of EVP_DigestInit in PKCS7 signedAndEnveloped is handled");
  978. });
  979. sub check_availability {
  980. my $tnam = shift;
  981. return "$tnam: skipped, EC disabled\n"
  982. if ($no_ec && $tnam =~ /ECDH/);
  983. return "$tnam: skipped, ECDH disabled\n"
  984. if ($no_ec && $tnam =~ /ECDH/);
  985. return "$tnam: skipped, EC2M disabled\n"
  986. if ($no_ec2m && $tnam =~ /K-283/);
  987. return "$tnam: skipped, DH disabled\n"
  988. if ($no_dh && $tnam =~ /X9\.42/);
  989. return "$tnam: skipped, RC2 disabled\n"
  990. if ($no_rc2 && $tnam =~ /RC2/);
  991. return "$tnam: skipped, DES disabled\n"
  992. if ($no_des && $tnam =~ /DES/);
  993. return "$tnam: skipped, DSA disabled\n"
  994. if ($no_dsa && $tnam =~ / DSA/);
  995. return "";
  996. }
  997. # Test case for the locking problem reported in #19643.
  998. # This will fail if the fix is in and deadlock on Windows (and possibly
  999. # other platforms) if not.
  1000. ok(!run(app(['openssl', 'cms', '-verify',
  1001. '-CAfile', srctop_file("test/certs", "pkitsta.pem"),
  1002. '-policy', 'anyPolicy',
  1003. '-in', srctop_file("test/smime-eml",
  1004. "SignedInvalidMappingFromanyPolicyTest7.eml")
  1005. ])),
  1006. "issue#19643");
  1007. # Check that kari encryption with originator does not segfault
  1008. with({ exit_checker => sub { return shift == 3; } },
  1009. sub {
  1010. SKIP: {
  1011. skip "EC is not supported in this build", 1 if $no_ec;
  1012. ok(run(app(['openssl', 'cms', '-encrypt',
  1013. '-in', srctop_file("test", "smcont.txt"), '-aes128',
  1014. '-recip', catfile($smdir, "smec1.pem"),
  1015. '-originator', catfile($smdir, "smec3.pem"),
  1016. '-inkey', catfile($smdir, "smec3.pem")
  1017. ])),
  1018. "Check failure for currently not supported kari encryption with static originator");
  1019. }
  1020. });
  1021. # Check that we get the expected failure return code
  1022. with({ exit_checker => sub { return shift == 6; } },
  1023. sub {
  1024. ok(run(app(['openssl', 'cms', '-encrypt',
  1025. '-in', srctop_file("test", "smcont.txt"),
  1026. '-aes128', '-stream', '-recip',
  1027. srctop_file("test/smime-certs", "badrsa.pem"),
  1028. ])),
  1029. "Check failure during BIO setup with -stream is handled correctly");
  1030. });
  1031. # Test case for return value mis-check reported in #21986
  1032. with({ exit_checker => sub { return shift == 3; } },
  1033. sub {
  1034. SKIP: {
  1035. skip "DSA is not supported in this build", 1 if $no_dsa;
  1036. ok(run(app(['openssl', 'cms', '-sign',
  1037. '-in', srctop_file("test", "smcont.txt"),
  1038. '-signer', srctop_file("test/smime-certs", "smdsa1.pem"),
  1039. '-md', 'SHAKE256'])),
  1040. "issue#21986");
  1041. }
  1042. });
  1043. # Test for problem reported in #22225
  1044. with({ exit_checker => sub { return shift == 3; } },
  1045. sub {
  1046. ok(run(app(['openssl', 'cms', '-encrypt',
  1047. '-in', srctop_file("test", "smcont.txt"),
  1048. '-aes-256-ctr', '-recip',
  1049. catfile($smdir, "smec1.pem"),
  1050. ])),
  1051. "Check for failure when cipher does not have an assigned OID (issue#22225)");
  1052. });
  1053. # Test encrypt to three recipients, and decrypt using key-only;
  1054. # i.e. do not follow the recommended practice of providing the
  1055. # recipient cert in the decrypt op.
  1056. #
  1057. # Use RSAES-OAEP for key-transport, not RSAES-PKCS-v1_5.
  1058. #
  1059. # Because the cert is not provided during decrypt, all RSA ciphertexts
  1060. # are decrypted in turn, and when/if there is a valid decryption, it
  1061. # is assumed the correct content-key has been recovered.
  1062. #
  1063. # That process may fail with RSAES-PKCS-v1_5 b/c there is a
  1064. # non-negligible chance that decrypting a random input using
  1065. # RSAES-PKCS-v1_5 can result in a valid plaintext (so two content-keys
  1066. # could be recovered and the wrong one might be used).
  1067. #
  1068. # See https://github.com/openssl/project/issues/380
  1069. subtest "encrypt to three recipients with RSA-OAEP, key only decrypt" => sub {
  1070. plan tests => 3;
  1071. my $pt = srctop_file("test", "smcont.txt");
  1072. my $ct = "smtst.cms";
  1073. my $ptpt = "smtst.txt";
  1074. ok(run(app(['openssl', 'cms',
  1075. @defaultprov,
  1076. '-encrypt', '-aes128',
  1077. '-in', $pt,
  1078. '-out', $ct,
  1079. '-stream',
  1080. '-recip', catfile($smdir, "smrsa1.pem"),
  1081. '-keyopt', 'rsa_padding_mode:oaep',
  1082. '-recip', catfile($smdir, "smrsa2.pem"),
  1083. '-keyopt', 'rsa_padding_mode:oaep',
  1084. '-recip', catfile($smdir, "smrsa3-cert.pem"),
  1085. '-keyopt', 'rsa_padding_mode:oaep',
  1086. ])),
  1087. "encrypt to three recipients with RSA-OAEP (avoid openssl/project issue#380)");
  1088. ok(run(app(['openssl', 'cms',
  1089. @defaultprov,
  1090. '-decrypt', '-aes128',
  1091. '-in', $ct,
  1092. '-out', $ptpt,
  1093. '-inkey', catfile($smdir, "smrsa3-key.pem"),
  1094. ])),
  1095. "decrypt with key only");
  1096. is(compare($pt, $ptpt), 0, "compare original message with decrypted ciphertext");
  1097. };