pk7_doit.c 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986
  1. /* crypto/pkcs7/pk7_doit.c */
  2. /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
  3. * All rights reserved.
  4. *
  5. * This package is an SSL implementation written
  6. * by Eric Young (eay@cryptsoft.com).
  7. * The implementation was written so as to conform with Netscapes SSL.
  8. *
  9. * This library is free for commercial and non-commercial use as long as
  10. * the following conditions are aheared to. The following conditions
  11. * apply to all code found in this distribution, be it the RC4, RSA,
  12. * lhash, DES, etc., code; not just the SSL code. The SSL documentation
  13. * included with this distribution is covered by the same copyright terms
  14. * except that the holder is Tim Hudson (tjh@cryptsoft.com).
  15. *
  16. * Copyright remains Eric Young's, and as such any Copyright notices in
  17. * the code are not to be removed.
  18. * If this package is used in a product, Eric Young should be given attribution
  19. * as the author of the parts of the library used.
  20. * This can be in the form of a textual message at program startup or
  21. * in documentation (online or textual) provided with the package.
  22. *
  23. * Redistribution and use in source and binary forms, with or without
  24. * modification, are permitted provided that the following conditions
  25. * are met:
  26. * 1. Redistributions of source code must retain the copyright
  27. * notice, this list of conditions and the following disclaimer.
  28. * 2. Redistributions in binary form must reproduce the above copyright
  29. * notice, this list of conditions and the following disclaimer in the
  30. * documentation and/or other materials provided with the distribution.
  31. * 3. All advertising materials mentioning features or use of this software
  32. * must display the following acknowledgement:
  33. * "This product includes cryptographic software written by
  34. * Eric Young (eay@cryptsoft.com)"
  35. * The word 'cryptographic' can be left out if the rouines from the library
  36. * being used are not cryptographic related :-).
  37. * 4. If you include any Windows specific code (or a derivative thereof) from
  38. * the apps directory (application code) you must include an acknowledgement:
  39. * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
  40. *
  41. * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
  42. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  43. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  44. * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
  45. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  46. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  47. * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  48. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  49. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  50. * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  51. * SUCH DAMAGE.
  52. *
  53. * The licence and distribution terms for any publically available version or
  54. * derivative of this code cannot be changed. i.e. this code cannot simply be
  55. * copied and put under another distribution licence
  56. * [including the GNU Public Licence.]
  57. */
  58. #include <stdio.h>
  59. #include "cryptlib.h"
  60. #include <openssl/rand.h>
  61. #include <openssl/objects.h>
  62. #include <openssl/x509.h>
  63. #include <openssl/x509v3.h>
  64. static int add_attribute(STACK_OF(X509_ATTRIBUTE) **sk, int nid, int atrtype,
  65. void *value);
  66. static ASN1_TYPE *get_attribute(STACK_OF(X509_ATTRIBUTE) *sk, int nid);
  67. static int PKCS7_type_is_other(PKCS7* p7)
  68. {
  69. int isOther=1;
  70. int nid=OBJ_obj2nid(p7->type);
  71. switch( nid )
  72. {
  73. case NID_pkcs7_data:
  74. case NID_pkcs7_signed:
  75. case NID_pkcs7_enveloped:
  76. case NID_pkcs7_signedAndEnveloped:
  77. case NID_pkcs7_digest:
  78. case NID_pkcs7_encrypted:
  79. isOther=0;
  80. break;
  81. default:
  82. isOther=1;
  83. }
  84. return isOther;
  85. }
  86. static int PKCS7_type_is_octet_string(PKCS7* p7)
  87. {
  88. if ( 0==PKCS7_type_is_other(p7) )
  89. return 0;
  90. return (V_ASN1_OCTET_STRING==p7->d.other->type) ? 1 : 0;
  91. }
  92. BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio)
  93. {
  94. int i,j;
  95. BIO *out=NULL,*btmp=NULL;
  96. X509_ALGOR *xa;
  97. const EVP_MD *evp_md;
  98. const EVP_CIPHER *evp_cipher=NULL;
  99. STACK_OF(X509_ALGOR) *md_sk=NULL;
  100. STACK_OF(PKCS7_RECIP_INFO) *rsk=NULL;
  101. X509_ALGOR *xalg=NULL;
  102. PKCS7_RECIP_INFO *ri=NULL;
  103. EVP_PKEY *pkey;
  104. i=OBJ_obj2nid(p7->type);
  105. p7->state=PKCS7_S_HEADER;
  106. switch (i)
  107. {
  108. case NID_pkcs7_signed:
  109. md_sk=p7->d.sign->md_algs;
  110. break;
  111. case NID_pkcs7_signedAndEnveloped:
  112. rsk=p7->d.signed_and_enveloped->recipientinfo;
  113. md_sk=p7->d.signed_and_enveloped->md_algs;
  114. xalg=p7->d.signed_and_enveloped->enc_data->algorithm;
  115. evp_cipher=p7->d.signed_and_enveloped->enc_data->cipher;
  116. if (evp_cipher == NULL)
  117. {
  118. PKCS7err(PKCS7_F_PKCS7_DATAINIT,
  119. PKCS7_R_CIPHER_NOT_INITIALIZED);
  120. goto err;
  121. }
  122. break;
  123. case NID_pkcs7_enveloped:
  124. rsk=p7->d.enveloped->recipientinfo;
  125. xalg=p7->d.enveloped->enc_data->algorithm;
  126. evp_cipher=p7->d.enveloped->enc_data->cipher;
  127. if (evp_cipher == NULL)
  128. {
  129. PKCS7err(PKCS7_F_PKCS7_DATAINIT,
  130. PKCS7_R_CIPHER_NOT_INITIALIZED);
  131. goto err;
  132. }
  133. break;
  134. default:
  135. PKCS7err(PKCS7_F_PKCS7_DATAINIT,PKCS7_R_UNSUPPORTED_CONTENT_TYPE);
  136. goto err;
  137. }
  138. if (md_sk != NULL)
  139. {
  140. for (i=0; i<sk_X509_ALGOR_num(md_sk); i++)
  141. {
  142. xa=sk_X509_ALGOR_value(md_sk,i);
  143. if ((btmp=BIO_new(BIO_f_md())) == NULL)
  144. {
  145. PKCS7err(PKCS7_F_PKCS7_DATAINIT,ERR_R_BIO_LIB);
  146. goto err;
  147. }
  148. j=OBJ_obj2nid(xa->algorithm);
  149. evp_md=EVP_get_digestbyname(OBJ_nid2sn(j));
  150. if (evp_md == NULL)
  151. {
  152. PKCS7err(PKCS7_F_PKCS7_DATAINIT,PKCS7_R_UNKNOWN_DIGEST_TYPE);
  153. goto err;
  154. }
  155. BIO_set_md(btmp,evp_md);
  156. if (out == NULL)
  157. out=btmp;
  158. else
  159. BIO_push(out,btmp);
  160. btmp=NULL;
  161. }
  162. }
  163. if (evp_cipher != NULL)
  164. {
  165. unsigned char key[EVP_MAX_KEY_LENGTH];
  166. unsigned char iv[EVP_MAX_IV_LENGTH];
  167. int keylen,ivlen;
  168. int jj,max;
  169. unsigned char *tmp;
  170. EVP_CIPHER_CTX *ctx;
  171. if ((btmp=BIO_new(BIO_f_cipher())) == NULL)
  172. {
  173. PKCS7err(PKCS7_F_PKCS7_DATAINIT,ERR_R_BIO_LIB);
  174. goto err;
  175. }
  176. BIO_get_cipher_ctx(btmp, &ctx);
  177. keylen=EVP_CIPHER_key_length(evp_cipher);
  178. ivlen=EVP_CIPHER_iv_length(evp_cipher);
  179. if (RAND_bytes(key,keylen) <= 0)
  180. goto err;
  181. xalg->algorithm = OBJ_nid2obj(EVP_CIPHER_type(evp_cipher));
  182. if (ivlen > 0) RAND_pseudo_bytes(iv,ivlen);
  183. EVP_CipherInit_ex(ctx, evp_cipher, NULL, key, iv, 1);
  184. if (ivlen > 0) {
  185. if (xalg->parameter == NULL)
  186. xalg->parameter=ASN1_TYPE_new();
  187. if(EVP_CIPHER_param_to_asn1(ctx, xalg->parameter) < 0)
  188. goto err;
  189. }
  190. /* Lets do the pub key stuff :-) */
  191. max=0;
  192. for (i=0; i<sk_PKCS7_RECIP_INFO_num(rsk); i++)
  193. {
  194. ri=sk_PKCS7_RECIP_INFO_value(rsk,i);
  195. if (ri->cert == NULL)
  196. {
  197. PKCS7err(PKCS7_F_PKCS7_DATAINIT,PKCS7_R_MISSING_CERIPEND_INFO);
  198. goto err;
  199. }
  200. pkey=X509_get_pubkey(ri->cert);
  201. jj=EVP_PKEY_size(pkey);
  202. EVP_PKEY_free(pkey);
  203. if (max < jj) max=jj;
  204. }
  205. if ((tmp=(unsigned char *)OPENSSL_malloc(max)) == NULL)
  206. {
  207. PKCS7err(PKCS7_F_PKCS7_DATAINIT,ERR_R_MALLOC_FAILURE);
  208. goto err;
  209. }
  210. for (i=0; i<sk_PKCS7_RECIP_INFO_num(rsk); i++)
  211. {
  212. ri=sk_PKCS7_RECIP_INFO_value(rsk,i);
  213. pkey=X509_get_pubkey(ri->cert);
  214. jj=EVP_PKEY_encrypt(tmp,key,keylen,pkey);
  215. EVP_PKEY_free(pkey);
  216. if (jj <= 0)
  217. {
  218. PKCS7err(PKCS7_F_PKCS7_DATAINIT,ERR_R_EVP_LIB);
  219. OPENSSL_free(tmp);
  220. goto err;
  221. }
  222. M_ASN1_OCTET_STRING_set(ri->enc_key,tmp,jj);
  223. }
  224. OPENSSL_free(tmp);
  225. OPENSSL_cleanse(key, keylen);
  226. if (out == NULL)
  227. out=btmp;
  228. else
  229. BIO_push(out,btmp);
  230. btmp=NULL;
  231. }
  232. if (bio == NULL) {
  233. if (PKCS7_is_detached(p7))
  234. bio=BIO_new(BIO_s_null());
  235. else {
  236. if (PKCS7_type_is_signed(p7) ) {
  237. if ( PKCS7_type_is_data(p7->d.sign->contents)) {
  238. ASN1_OCTET_STRING *os;
  239. os=p7->d.sign->contents->d.data;
  240. if (os->length > 0)
  241. bio = BIO_new_mem_buf(os->data, os->length);
  242. }
  243. else if ( PKCS7_type_is_octet_string(p7->d.sign->contents) ) {
  244. ASN1_OCTET_STRING *os;
  245. os=p7->d.sign->contents->d.other->value.octet_string;
  246. if (os->length > 0)
  247. bio = BIO_new_mem_buf(os->data, os->length);
  248. }
  249. }
  250. if(bio == NULL) {
  251. bio=BIO_new(BIO_s_mem());
  252. BIO_set_mem_eof_return(bio,0);
  253. }
  254. }
  255. }
  256. BIO_push(out,bio);
  257. bio=NULL;
  258. if (0)
  259. {
  260. err:
  261. if (out != NULL)
  262. BIO_free_all(out);
  263. if (btmp != NULL)
  264. BIO_free_all(btmp);
  265. out=NULL;
  266. }
  267. return(out);
  268. }
  269. /* int */
  270. BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert)
  271. {
  272. int i,j;
  273. BIO *out=NULL,*btmp=NULL,*etmp=NULL,*bio=NULL;
  274. unsigned char *tmp=NULL;
  275. X509_ALGOR *xa;
  276. ASN1_OCTET_STRING *data_body=NULL;
  277. const EVP_MD *evp_md;
  278. const EVP_CIPHER *evp_cipher=NULL;
  279. EVP_CIPHER_CTX *evp_ctx=NULL;
  280. X509_ALGOR *enc_alg=NULL;
  281. STACK_OF(X509_ALGOR) *md_sk=NULL;
  282. STACK_OF(PKCS7_RECIP_INFO) *rsk=NULL;
  283. X509_ALGOR *xalg=NULL;
  284. PKCS7_RECIP_INFO *ri=NULL;
  285. i=OBJ_obj2nid(p7->type);
  286. p7->state=PKCS7_S_HEADER;
  287. switch (i)
  288. {
  289. case NID_pkcs7_signed:
  290. data_body=p7->d.sign->contents->d.data;
  291. md_sk=p7->d.sign->md_algs;
  292. break;
  293. case NID_pkcs7_signedAndEnveloped:
  294. rsk=p7->d.signed_and_enveloped->recipientinfo;
  295. md_sk=p7->d.signed_and_enveloped->md_algs;
  296. data_body=p7->d.signed_and_enveloped->enc_data->enc_data;
  297. enc_alg=p7->d.signed_and_enveloped->enc_data->algorithm;
  298. evp_cipher=EVP_get_cipherbyname(OBJ_nid2sn(OBJ_obj2nid(enc_alg->algorithm)));
  299. if (evp_cipher == NULL)
  300. {
  301. PKCS7err(PKCS7_F_PKCS7_DATADECODE,PKCS7_R_UNSUPPORTED_CIPHER_TYPE);
  302. goto err;
  303. }
  304. xalg=p7->d.signed_and_enveloped->enc_data->algorithm;
  305. break;
  306. case NID_pkcs7_enveloped:
  307. rsk=p7->d.enveloped->recipientinfo;
  308. enc_alg=p7->d.enveloped->enc_data->algorithm;
  309. data_body=p7->d.enveloped->enc_data->enc_data;
  310. evp_cipher=EVP_get_cipherbyname(OBJ_nid2sn(OBJ_obj2nid(enc_alg->algorithm)));
  311. if (evp_cipher == NULL)
  312. {
  313. PKCS7err(PKCS7_F_PKCS7_DATADECODE,PKCS7_R_UNSUPPORTED_CIPHER_TYPE);
  314. goto err;
  315. }
  316. xalg=p7->d.enveloped->enc_data->algorithm;
  317. break;
  318. default:
  319. PKCS7err(PKCS7_F_PKCS7_DATADECODE,PKCS7_R_UNSUPPORTED_CONTENT_TYPE);
  320. goto err;
  321. }
  322. /* We will be checking the signature */
  323. if (md_sk != NULL)
  324. {
  325. for (i=0; i<sk_X509_ALGOR_num(md_sk); i++)
  326. {
  327. xa=sk_X509_ALGOR_value(md_sk,i);
  328. if ((btmp=BIO_new(BIO_f_md())) == NULL)
  329. {
  330. PKCS7err(PKCS7_F_PKCS7_DATADECODE,ERR_R_BIO_LIB);
  331. goto err;
  332. }
  333. j=OBJ_obj2nid(xa->algorithm);
  334. evp_md=EVP_get_digestbyname(OBJ_nid2sn(j));
  335. if (evp_md == NULL)
  336. {
  337. PKCS7err(PKCS7_F_PKCS7_DATADECODE,PKCS7_R_UNKNOWN_DIGEST_TYPE);
  338. goto err;
  339. }
  340. BIO_set_md(btmp,evp_md);
  341. if (out == NULL)
  342. out=btmp;
  343. else
  344. BIO_push(out,btmp);
  345. btmp=NULL;
  346. }
  347. }
  348. if (evp_cipher != NULL)
  349. {
  350. #if 0
  351. unsigned char key[EVP_MAX_KEY_LENGTH];
  352. unsigned char iv[EVP_MAX_IV_LENGTH];
  353. unsigned char *p;
  354. int keylen,ivlen;
  355. int max;
  356. X509_OBJECT ret;
  357. #endif
  358. int jj;
  359. if ((etmp=BIO_new(BIO_f_cipher())) == NULL)
  360. {
  361. PKCS7err(PKCS7_F_PKCS7_DATADECODE,ERR_R_BIO_LIB);
  362. goto err;
  363. }
  364. /* It was encrypted, we need to decrypt the secret key
  365. * with the private key */
  366. /* Find the recipientInfo which matches the passed certificate
  367. * (if any)
  368. */
  369. for (i=0; i<sk_PKCS7_RECIP_INFO_num(rsk); i++) {
  370. ri=sk_PKCS7_RECIP_INFO_value(rsk,i);
  371. if(!X509_NAME_cmp(ri->issuer_and_serial->issuer,
  372. pcert->cert_info->issuer) &&
  373. !M_ASN1_INTEGER_cmp(pcert->cert_info->serialNumber,
  374. ri->issuer_and_serial->serial)) break;
  375. ri=NULL;
  376. }
  377. if (ri == NULL) {
  378. PKCS7err(PKCS7_F_PKCS7_DATADECODE,
  379. PKCS7_R_NO_RECIPIENT_MATCHES_CERTIFICATE);
  380. goto err;
  381. }
  382. jj=EVP_PKEY_size(pkey);
  383. tmp=(unsigned char *)OPENSSL_malloc(jj+10);
  384. if (tmp == NULL)
  385. {
  386. PKCS7err(PKCS7_F_PKCS7_DATADECODE,ERR_R_MALLOC_FAILURE);
  387. goto err;
  388. }
  389. jj=EVP_PKEY_decrypt(tmp, M_ASN1_STRING_data(ri->enc_key),
  390. M_ASN1_STRING_length(ri->enc_key), pkey);
  391. if (jj <= 0)
  392. {
  393. PKCS7err(PKCS7_F_PKCS7_DATADECODE,ERR_R_EVP_LIB);
  394. goto err;
  395. }
  396. evp_ctx=NULL;
  397. BIO_get_cipher_ctx(etmp,&evp_ctx);
  398. EVP_CipherInit_ex(evp_ctx,evp_cipher,NULL,NULL,NULL,0);
  399. if (EVP_CIPHER_asn1_to_param(evp_ctx,enc_alg->parameter) < 0)
  400. goto err;
  401. if (jj != EVP_CIPHER_CTX_key_length(evp_ctx)) {
  402. /* Some S/MIME clients don't use the same key
  403. * and effective key length. The key length is
  404. * determined by the size of the decrypted RSA key.
  405. */
  406. if(!EVP_CIPHER_CTX_set_key_length(evp_ctx, jj))
  407. {
  408. PKCS7err(PKCS7_F_PKCS7_DATADECODE,
  409. PKCS7_R_DECRYPTED_KEY_IS_WRONG_LENGTH);
  410. goto err;
  411. }
  412. }
  413. EVP_CipherInit_ex(evp_ctx,NULL,NULL,tmp,NULL,0);
  414. OPENSSL_cleanse(tmp,jj);
  415. if (out == NULL)
  416. out=etmp;
  417. else
  418. BIO_push(out,etmp);
  419. etmp=NULL;
  420. }
  421. #if 1
  422. if (PKCS7_is_detached(p7) || (in_bio != NULL))
  423. {
  424. bio=in_bio;
  425. }
  426. else
  427. {
  428. #if 0
  429. bio=BIO_new(BIO_s_mem());
  430. /* We need to set this so that when we have read all
  431. * the data, the encrypt BIO, if present, will read
  432. * EOF and encode the last few bytes */
  433. BIO_set_mem_eof_return(bio,0);
  434. if (data_body->length > 0)
  435. BIO_write(bio,(char *)data_body->data,data_body->length);
  436. #else
  437. if (data_body->length > 0)
  438. bio = BIO_new_mem_buf(data_body->data,data_body->length);
  439. else {
  440. bio=BIO_new(BIO_s_mem());
  441. BIO_set_mem_eof_return(bio,0);
  442. }
  443. #endif
  444. }
  445. BIO_push(out,bio);
  446. bio=NULL;
  447. #endif
  448. if (0)
  449. {
  450. err:
  451. if (out != NULL) BIO_free_all(out);
  452. if (btmp != NULL) BIO_free_all(btmp);
  453. if (etmp != NULL) BIO_free_all(etmp);
  454. if (bio != NULL) BIO_free_all(bio);
  455. out=NULL;
  456. }
  457. if (tmp != NULL)
  458. OPENSSL_free(tmp);
  459. return(out);
  460. }
  461. int PKCS7_dataFinal(PKCS7 *p7, BIO *bio)
  462. {
  463. int ret=0;
  464. int i,j;
  465. BIO *btmp;
  466. BUF_MEM *buf_mem=NULL;
  467. BUF_MEM *buf=NULL;
  468. PKCS7_SIGNER_INFO *si;
  469. EVP_MD_CTX *mdc,ctx_tmp;
  470. STACK_OF(X509_ATTRIBUTE) *sk;
  471. STACK_OF(PKCS7_SIGNER_INFO) *si_sk=NULL;
  472. ASN1_OCTET_STRING *os=NULL;
  473. EVP_MD_CTX_init(&ctx_tmp);
  474. i=OBJ_obj2nid(p7->type);
  475. p7->state=PKCS7_S_HEADER;
  476. switch (i)
  477. {
  478. case NID_pkcs7_signedAndEnveloped:
  479. /* XXXXXXXXXXXXXXXX */
  480. si_sk=p7->d.signed_and_enveloped->signer_info;
  481. os=M_ASN1_OCTET_STRING_new();
  482. p7->d.signed_and_enveloped->enc_data->enc_data=os;
  483. break;
  484. case NID_pkcs7_enveloped:
  485. /* XXXXXXXXXXXXXXXX */
  486. os=M_ASN1_OCTET_STRING_new();
  487. p7->d.enveloped->enc_data->enc_data=os;
  488. break;
  489. case NID_pkcs7_signed:
  490. si_sk=p7->d.sign->signer_info;
  491. os=p7->d.sign->contents->d.data;
  492. /* If detached data then the content is excluded */
  493. if(p7->detached) {
  494. M_ASN1_OCTET_STRING_free(os);
  495. p7->d.sign->contents->d.data = NULL;
  496. }
  497. break;
  498. }
  499. if (si_sk != NULL)
  500. {
  501. if ((buf=BUF_MEM_new()) == NULL)
  502. {
  503. PKCS7err(PKCS7_F_PKCS7_DATASIGN,ERR_R_BIO_LIB);
  504. goto err;
  505. }
  506. for (i=0; i<sk_PKCS7_SIGNER_INFO_num(si_sk); i++)
  507. {
  508. si=sk_PKCS7_SIGNER_INFO_value(si_sk,i);
  509. if (si->pkey == NULL) continue;
  510. j=OBJ_obj2nid(si->digest_alg->algorithm);
  511. btmp=bio;
  512. for (;;)
  513. {
  514. if ((btmp=BIO_find_type(btmp,BIO_TYPE_MD))
  515. == NULL)
  516. {
  517. PKCS7err(PKCS7_F_PKCS7_DATASIGN,PKCS7_R_UNABLE_TO_FIND_MESSAGE_DIGEST);
  518. goto err;
  519. }
  520. BIO_get_md_ctx(btmp,&mdc);
  521. if (mdc == NULL)
  522. {
  523. PKCS7err(PKCS7_F_PKCS7_DATASIGN,ERR_R_INTERNAL_ERROR);
  524. goto err;
  525. }
  526. if (EVP_MD_CTX_type(mdc) == j)
  527. break;
  528. else
  529. btmp=BIO_next(btmp);
  530. }
  531. /* We now have the EVP_MD_CTX, lets do the
  532. * signing. */
  533. EVP_MD_CTX_copy_ex(&ctx_tmp,mdc);
  534. if (!BUF_MEM_grow_clean(buf,EVP_PKEY_size(si->pkey)))
  535. {
  536. PKCS7err(PKCS7_F_PKCS7_DATASIGN,ERR_R_BIO_LIB);
  537. goto err;
  538. }
  539. sk=si->auth_attr;
  540. /* If there are attributes, we add the digest
  541. * attribute and only sign the attributes */
  542. if ((sk != NULL) && (sk_X509_ATTRIBUTE_num(sk) != 0))
  543. {
  544. unsigned char md_data[EVP_MAX_MD_SIZE], *abuf=NULL;
  545. unsigned int md_len, alen;
  546. ASN1_OCTET_STRING *digest;
  547. ASN1_UTCTIME *sign_time;
  548. const EVP_MD *md_tmp;
  549. /* Add signing time if not already present */
  550. if (!PKCS7_get_signed_attribute(si,
  551. NID_pkcs9_signingTime))
  552. {
  553. sign_time=X509_gmtime_adj(NULL,0);
  554. PKCS7_add_signed_attribute(si,
  555. NID_pkcs9_signingTime,
  556. V_ASN1_UTCTIME,sign_time);
  557. }
  558. /* Add digest */
  559. md_tmp=EVP_MD_CTX_md(&ctx_tmp);
  560. EVP_DigestFinal_ex(&ctx_tmp,md_data,&md_len);
  561. digest=M_ASN1_OCTET_STRING_new();
  562. M_ASN1_OCTET_STRING_set(digest,md_data,md_len);
  563. PKCS7_add_signed_attribute(si,
  564. NID_pkcs9_messageDigest,
  565. V_ASN1_OCTET_STRING,digest);
  566. /* Now sign the attributes */
  567. EVP_SignInit_ex(&ctx_tmp,md_tmp,NULL);
  568. alen = ASN1_item_i2d((ASN1_VALUE *)sk,&abuf,
  569. ASN1_ITEM_rptr(PKCS7_ATTR_SIGN));
  570. if(!abuf) goto err;
  571. EVP_SignUpdate(&ctx_tmp,abuf,alen);
  572. OPENSSL_free(abuf);
  573. }
  574. #ifndef OPENSSL_NO_DSA
  575. if (si->pkey->type == EVP_PKEY_DSA)
  576. ctx_tmp.digest=EVP_dss1();
  577. #endif
  578. #ifndef OPENSSL_NO_ECDSA
  579. if (si->pkey->type == EVP_PKEY_EC)
  580. ctx_tmp.digest=EVP_ecdsa();
  581. #endif
  582. if (!EVP_SignFinal(&ctx_tmp,(unsigned char *)buf->data,
  583. (unsigned int *)&buf->length,si->pkey))
  584. {
  585. PKCS7err(PKCS7_F_PKCS7_DATASIGN,ERR_R_EVP_LIB);
  586. goto err;
  587. }
  588. if (!ASN1_STRING_set(si->enc_digest,
  589. (unsigned char *)buf->data,buf->length))
  590. {
  591. PKCS7err(PKCS7_F_PKCS7_DATASIGN,ERR_R_ASN1_LIB);
  592. goto err;
  593. }
  594. }
  595. }
  596. if (!PKCS7_is_detached(p7))
  597. {
  598. btmp=BIO_find_type(bio,BIO_TYPE_MEM);
  599. if (btmp == NULL)
  600. {
  601. PKCS7err(PKCS7_F_PKCS7_DATASIGN,PKCS7_R_UNABLE_TO_FIND_MEM_BIO);
  602. goto err;
  603. }
  604. BIO_get_mem_ptr(btmp,&buf_mem);
  605. /* Mark the BIO read only then we can use its copy of the data
  606. * instead of making an extra copy.
  607. */
  608. BIO_set_flags(btmp, BIO_FLAGS_MEM_RDONLY);
  609. BIO_set_mem_eof_return(btmp, 0);
  610. os->data = (unsigned char *)buf_mem->data;
  611. os->length = buf_mem->length;
  612. #if 0
  613. M_ASN1_OCTET_STRING_set(os,
  614. (unsigned char *)buf_mem->data,buf_mem->length);
  615. #endif
  616. }
  617. ret=1;
  618. err:
  619. EVP_MD_CTX_cleanup(&ctx_tmp);
  620. if (buf != NULL) BUF_MEM_free(buf);
  621. return(ret);
  622. }
  623. int PKCS7_dataVerify(X509_STORE *cert_store, X509_STORE_CTX *ctx, BIO *bio,
  624. PKCS7 *p7, PKCS7_SIGNER_INFO *si)
  625. {
  626. PKCS7_ISSUER_AND_SERIAL *ias;
  627. int ret=0,i;
  628. STACK_OF(X509) *cert;
  629. X509 *x509;
  630. if (PKCS7_type_is_signed(p7))
  631. {
  632. cert=p7->d.sign->cert;
  633. }
  634. else if (PKCS7_type_is_signedAndEnveloped(p7))
  635. {
  636. cert=p7->d.signed_and_enveloped->cert;
  637. }
  638. else
  639. {
  640. PKCS7err(PKCS7_F_PKCS7_DATAVERIFY,PKCS7_R_WRONG_PKCS7_TYPE);
  641. goto err;
  642. }
  643. /* XXXXXXXXXXXXXXXXXXXXXXX */
  644. ias=si->issuer_and_serial;
  645. x509=X509_find_by_issuer_and_serial(cert,ias->issuer,ias->serial);
  646. /* were we able to find the cert in passed to us */
  647. if (x509 == NULL)
  648. {
  649. PKCS7err(PKCS7_F_PKCS7_DATAVERIFY,PKCS7_R_UNABLE_TO_FIND_CERTIFICATE);
  650. goto err;
  651. }
  652. /* Lets verify */
  653. if(!X509_STORE_CTX_init(ctx,cert_store,x509,cert))
  654. {
  655. PKCS7err(PKCS7_F_PKCS7_DATAVERIFY,ERR_R_X509_LIB);
  656. goto err;
  657. }
  658. X509_STORE_CTX_set_purpose(ctx, X509_PURPOSE_SMIME_SIGN);
  659. i=X509_verify_cert(ctx);
  660. if (i <= 0)
  661. {
  662. PKCS7err(PKCS7_F_PKCS7_DATAVERIFY,ERR_R_X509_LIB);
  663. X509_STORE_CTX_cleanup(ctx);
  664. goto err;
  665. }
  666. X509_STORE_CTX_cleanup(ctx);
  667. return PKCS7_signatureVerify(bio, p7, si, x509);
  668. err:
  669. return ret;
  670. }
  671. int PKCS7_signatureVerify(BIO *bio, PKCS7 *p7, PKCS7_SIGNER_INFO *si,
  672. X509 *x509)
  673. {
  674. ASN1_OCTET_STRING *os;
  675. EVP_MD_CTX mdc_tmp,*mdc;
  676. int ret=0,i;
  677. int md_type;
  678. STACK_OF(X509_ATTRIBUTE) *sk;
  679. BIO *btmp;
  680. EVP_PKEY *pkey;
  681. EVP_MD_CTX_init(&mdc_tmp);
  682. if (!PKCS7_type_is_signed(p7) &&
  683. !PKCS7_type_is_signedAndEnveloped(p7)) {
  684. PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY,
  685. PKCS7_R_WRONG_PKCS7_TYPE);
  686. goto err;
  687. }
  688. md_type=OBJ_obj2nid(si->digest_alg->algorithm);
  689. btmp=bio;
  690. for (;;)
  691. {
  692. if ((btmp == NULL) ||
  693. ((btmp=BIO_find_type(btmp,BIO_TYPE_MD)) == NULL))
  694. {
  695. PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY,
  696. PKCS7_R_UNABLE_TO_FIND_MESSAGE_DIGEST);
  697. goto err;
  698. }
  699. BIO_get_md_ctx(btmp,&mdc);
  700. if (mdc == NULL)
  701. {
  702. PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY,
  703. ERR_R_INTERNAL_ERROR);
  704. goto err;
  705. }
  706. if (EVP_MD_CTX_type(mdc) == md_type)
  707. break;
  708. btmp=BIO_next(btmp);
  709. }
  710. /* mdc is the digest ctx that we want, unless there are attributes,
  711. * in which case the digest is the signed attributes */
  712. EVP_MD_CTX_copy_ex(&mdc_tmp,mdc);
  713. sk=si->auth_attr;
  714. if ((sk != NULL) && (sk_X509_ATTRIBUTE_num(sk) != 0))
  715. {
  716. unsigned char md_dat[EVP_MAX_MD_SIZE], *abuf = NULL;
  717. unsigned int md_len, alen;
  718. ASN1_OCTET_STRING *message_digest;
  719. EVP_DigestFinal_ex(&mdc_tmp,md_dat,&md_len);
  720. message_digest=PKCS7_digest_from_attributes(sk);
  721. if (!message_digest)
  722. {
  723. PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY,
  724. PKCS7_R_UNABLE_TO_FIND_MESSAGE_DIGEST);
  725. goto err;
  726. }
  727. if ((message_digest->length != (int)md_len) ||
  728. (memcmp(message_digest->data,md_dat,md_len)))
  729. {
  730. #if 0
  731. {
  732. int ii;
  733. for (ii=0; ii<message_digest->length; ii++)
  734. printf("%02X",message_digest->data[ii]); printf(" sent\n");
  735. for (ii=0; ii<md_len; ii++) printf("%02X",md_dat[ii]); printf(" calc\n");
  736. }
  737. #endif
  738. PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY,
  739. PKCS7_R_DIGEST_FAILURE);
  740. ret= -1;
  741. goto err;
  742. }
  743. EVP_VerifyInit_ex(&mdc_tmp,EVP_get_digestbynid(md_type), NULL);
  744. alen = ASN1_item_i2d((ASN1_VALUE *)sk, &abuf,
  745. ASN1_ITEM_rptr(PKCS7_ATTR_VERIFY));
  746. EVP_VerifyUpdate(&mdc_tmp, abuf, alen);
  747. OPENSSL_free(abuf);
  748. }
  749. os=si->enc_digest;
  750. pkey = X509_get_pubkey(x509);
  751. if (!pkey)
  752. {
  753. ret = -1;
  754. goto err;
  755. }
  756. #ifndef OPENSSL_NO_DSA
  757. if(pkey->type == EVP_PKEY_DSA) mdc_tmp.digest=EVP_dss1();
  758. #endif
  759. #ifndef OPENSSL_NO_ECDSA
  760. if (pkey->type == EVP_PKEY_EC) mdc_tmp.digest=EVP_ecdsa();
  761. #endif
  762. i=EVP_VerifyFinal(&mdc_tmp,os->data,os->length, pkey);
  763. EVP_PKEY_free(pkey);
  764. if (i <= 0)
  765. {
  766. PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY,
  767. PKCS7_R_SIGNATURE_FAILURE);
  768. ret= -1;
  769. goto err;
  770. }
  771. else
  772. ret=1;
  773. err:
  774. EVP_MD_CTX_cleanup(&mdc_tmp);
  775. return(ret);
  776. }
  777. PKCS7_ISSUER_AND_SERIAL *PKCS7_get_issuer_and_serial(PKCS7 *p7, int idx)
  778. {
  779. STACK_OF(PKCS7_RECIP_INFO) *rsk;
  780. PKCS7_RECIP_INFO *ri;
  781. int i;
  782. i=OBJ_obj2nid(p7->type);
  783. if (i != NID_pkcs7_signedAndEnveloped) return(NULL);
  784. rsk=p7->d.signed_and_enveloped->recipientinfo;
  785. ri=sk_PKCS7_RECIP_INFO_value(rsk,0);
  786. if (sk_PKCS7_RECIP_INFO_num(rsk) <= idx) return(NULL);
  787. ri=sk_PKCS7_RECIP_INFO_value(rsk,idx);
  788. return(ri->issuer_and_serial);
  789. }
  790. ASN1_TYPE *PKCS7_get_signed_attribute(PKCS7_SIGNER_INFO *si, int nid)
  791. {
  792. return(get_attribute(si->auth_attr,nid));
  793. }
  794. ASN1_TYPE *PKCS7_get_attribute(PKCS7_SIGNER_INFO *si, int nid)
  795. {
  796. return(get_attribute(si->unauth_attr,nid));
  797. }
  798. static ASN1_TYPE *get_attribute(STACK_OF(X509_ATTRIBUTE) *sk, int nid)
  799. {
  800. int i;
  801. X509_ATTRIBUTE *xa;
  802. ASN1_OBJECT *o;
  803. o=OBJ_nid2obj(nid);
  804. if (!o || !sk) return(NULL);
  805. for (i=0; i<sk_X509_ATTRIBUTE_num(sk); i++)
  806. {
  807. xa=sk_X509_ATTRIBUTE_value(sk,i);
  808. if (OBJ_cmp(xa->object,o) == 0)
  809. {
  810. if (!xa->single && sk_ASN1_TYPE_num(xa->value.set))
  811. return(sk_ASN1_TYPE_value(xa->value.set,0));
  812. else
  813. return(NULL);
  814. }
  815. }
  816. return(NULL);
  817. }
  818. ASN1_OCTET_STRING *PKCS7_digest_from_attributes(STACK_OF(X509_ATTRIBUTE) *sk)
  819. {
  820. ASN1_TYPE *astype;
  821. if(!(astype = get_attribute(sk, NID_pkcs9_messageDigest))) return NULL;
  822. return astype->value.octet_string;
  823. }
  824. int PKCS7_set_signed_attributes(PKCS7_SIGNER_INFO *p7si,
  825. STACK_OF(X509_ATTRIBUTE) *sk)
  826. {
  827. int i;
  828. if (p7si->auth_attr != NULL)
  829. sk_X509_ATTRIBUTE_pop_free(p7si->auth_attr,X509_ATTRIBUTE_free);
  830. p7si->auth_attr=sk_X509_ATTRIBUTE_dup(sk);
  831. for (i=0; i<sk_X509_ATTRIBUTE_num(sk); i++)
  832. {
  833. if ((sk_X509_ATTRIBUTE_set(p7si->auth_attr,i,
  834. X509_ATTRIBUTE_dup(sk_X509_ATTRIBUTE_value(sk,i))))
  835. == NULL)
  836. return(0);
  837. }
  838. return(1);
  839. }
  840. int PKCS7_set_attributes(PKCS7_SIGNER_INFO *p7si, STACK_OF(X509_ATTRIBUTE) *sk)
  841. {
  842. int i;
  843. if (p7si->unauth_attr != NULL)
  844. sk_X509_ATTRIBUTE_pop_free(p7si->unauth_attr,
  845. X509_ATTRIBUTE_free);
  846. p7si->unauth_attr=sk_X509_ATTRIBUTE_dup(sk);
  847. for (i=0; i<sk_X509_ATTRIBUTE_num(sk); i++)
  848. {
  849. if ((sk_X509_ATTRIBUTE_set(p7si->unauth_attr,i,
  850. X509_ATTRIBUTE_dup(sk_X509_ATTRIBUTE_value(sk,i))))
  851. == NULL)
  852. return(0);
  853. }
  854. return(1);
  855. }
  856. int PKCS7_add_signed_attribute(PKCS7_SIGNER_INFO *p7si, int nid, int atrtype,
  857. void *value)
  858. {
  859. return(add_attribute(&(p7si->auth_attr),nid,atrtype,value));
  860. }
  861. int PKCS7_add_attribute(PKCS7_SIGNER_INFO *p7si, int nid, int atrtype,
  862. void *value)
  863. {
  864. return(add_attribute(&(p7si->unauth_attr),nid,atrtype,value));
  865. }
  866. static int add_attribute(STACK_OF(X509_ATTRIBUTE) **sk, int nid, int atrtype,
  867. void *value)
  868. {
  869. X509_ATTRIBUTE *attr=NULL;
  870. if (*sk == NULL)
  871. {
  872. *sk = sk_X509_ATTRIBUTE_new_null();
  873. new_attrib:
  874. attr=X509_ATTRIBUTE_create(nid,atrtype,value);
  875. sk_X509_ATTRIBUTE_push(*sk,attr);
  876. }
  877. else
  878. {
  879. int i;
  880. for (i=0; i<sk_X509_ATTRIBUTE_num(*sk); i++)
  881. {
  882. attr=sk_X509_ATTRIBUTE_value(*sk,i);
  883. if (OBJ_obj2nid(attr->object) == nid)
  884. {
  885. X509_ATTRIBUTE_free(attr);
  886. attr=X509_ATTRIBUTE_create(nid,atrtype,value);
  887. sk_X509_ATTRIBUTE_set(*sk,i,attr);
  888. goto end;
  889. }
  890. }
  891. goto new_attrib;
  892. }
  893. end:
  894. return(1);
  895. }