pk7_doit.c
上传用户:yisoukefu
上传日期:2020-08-09
资源大小:39506k
文件大小:27k
源码类别:

其他游戏

开发平台:

Visual C++

  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. #include <openssl/err.h>
  65. static int add_attribute(STACK_OF(X509_ATTRIBUTE) **sk, int nid, int atrtype,
  66.  void *value);
  67. static ASN1_TYPE *get_attribute(STACK_OF(X509_ATTRIBUTE) *sk, int nid);
  68. static int PKCS7_type_is_other(PKCS7* p7)
  69. {
  70. int isOther=1;
  71. int nid=OBJ_obj2nid(p7->type);
  72. switch( nid )
  73. {
  74. case NID_pkcs7_data:
  75. case NID_pkcs7_signed:
  76. case NID_pkcs7_enveloped:
  77. case NID_pkcs7_signedAndEnveloped:
  78. case NID_pkcs7_digest:
  79. case NID_pkcs7_encrypted:
  80. isOther=0;
  81. break;
  82. default:
  83. isOther=1;
  84. }
  85. return isOther;
  86. }
  87. static ASN1_OCTET_STRING *PKCS7_get_octet_string(PKCS7 *p7)
  88. {
  89. if ( PKCS7_type_is_data(p7))
  90. return p7->d.data;
  91. if ( PKCS7_type_is_other(p7) && p7->d.other
  92. && (p7->d.other->type == V_ASN1_OCTET_STRING))
  93. return p7->d.other->value.octet_string;
  94. return NULL;
  95. }
  96. static int PKCS7_bio_add_digest(BIO **pbio, X509_ALGOR *alg)
  97. {
  98. BIO *btmp;
  99. const EVP_MD *md;
  100. if ((btmp=BIO_new(BIO_f_md())) == NULL)
  101. {
  102. PKCS7err(PKCS7_F_PKCS7_BIO_ADD_DIGEST,ERR_R_BIO_LIB);
  103. goto err;
  104. }
  105. md=EVP_get_digestbyobj(alg->algorithm);
  106. if (md == NULL)
  107. {
  108. PKCS7err(PKCS7_F_PKCS7_BIO_ADD_DIGEST,PKCS7_R_UNKNOWN_DIGEST_TYPE);
  109. goto err;
  110. }
  111. BIO_set_md(btmp,md);
  112. if (*pbio == NULL)
  113. *pbio=btmp;
  114. else if (!BIO_push(*pbio,btmp))
  115. {
  116. PKCS7err(PKCS7_F_PKCS7_BIO_ADD_DIGEST,ERR_R_BIO_LIB);
  117. goto err;
  118. }
  119. btmp=NULL;
  120. return 1;
  121. err:
  122. if (btmp)
  123. BIO_free(btmp);
  124. return 0;
  125. }
  126. BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio)
  127. {
  128. int i;
  129. BIO *out=NULL,*btmp=NULL;
  130. X509_ALGOR *xa = NULL;
  131. const EVP_CIPHER *evp_cipher=NULL;
  132. STACK_OF(X509_ALGOR) *md_sk=NULL;
  133. STACK_OF(PKCS7_RECIP_INFO) *rsk=NULL;
  134. X509_ALGOR *xalg=NULL;
  135. PKCS7_RECIP_INFO *ri=NULL;
  136. EVP_PKEY *pkey;
  137. ASN1_OCTET_STRING *os=NULL;
  138. i=OBJ_obj2nid(p7->type);
  139. p7->state=PKCS7_S_HEADER;
  140. switch (i)
  141. {
  142. case NID_pkcs7_signed:
  143. md_sk=p7->d.sign->md_algs;
  144. os = PKCS7_get_octet_string(p7->d.sign->contents);
  145. break;
  146. case NID_pkcs7_signedAndEnveloped:
  147. rsk=p7->d.signed_and_enveloped->recipientinfo;
  148. md_sk=p7->d.signed_and_enveloped->md_algs;
  149. xalg=p7->d.signed_and_enveloped->enc_data->algorithm;
  150. evp_cipher=p7->d.signed_and_enveloped->enc_data->cipher;
  151. if (evp_cipher == NULL)
  152. {
  153. PKCS7err(PKCS7_F_PKCS7_DATAINIT,
  154. PKCS7_R_CIPHER_NOT_INITIALIZED);
  155. goto err;
  156. }
  157. break;
  158. case NID_pkcs7_enveloped:
  159. rsk=p7->d.enveloped->recipientinfo;
  160. xalg=p7->d.enveloped->enc_data->algorithm;
  161. evp_cipher=p7->d.enveloped->enc_data->cipher;
  162. if (evp_cipher == NULL)
  163. {
  164. PKCS7err(PKCS7_F_PKCS7_DATAINIT,
  165. PKCS7_R_CIPHER_NOT_INITIALIZED);
  166. goto err;
  167. }
  168. break;
  169. case NID_pkcs7_digest:
  170. xa = p7->d.digest->md;
  171. os = PKCS7_get_octet_string(p7->d.digest->contents);
  172. break;
  173. default:
  174. PKCS7err(PKCS7_F_PKCS7_DATAINIT,PKCS7_R_UNSUPPORTED_CONTENT_TYPE);
  175.         goto err;
  176. }
  177. for (i=0; i<sk_X509_ALGOR_num(md_sk); i++)
  178. if (!PKCS7_bio_add_digest(&out, sk_X509_ALGOR_value(md_sk, i)))
  179. goto err;
  180. if (xa && !PKCS7_bio_add_digest(&out, xa))
  181. goto err;
  182. if (evp_cipher != NULL)
  183. {
  184. unsigned char key[EVP_MAX_KEY_LENGTH];
  185. unsigned char iv[EVP_MAX_IV_LENGTH];
  186. int keylen,ivlen;
  187. int jj,max;
  188. unsigned char *tmp;
  189. EVP_CIPHER_CTX *ctx;
  190. if ((btmp=BIO_new(BIO_f_cipher())) == NULL)
  191. {
  192. PKCS7err(PKCS7_F_PKCS7_DATAINIT,ERR_R_BIO_LIB);
  193. goto err;
  194. }
  195. BIO_get_cipher_ctx(btmp, &ctx);
  196. keylen=EVP_CIPHER_key_length(evp_cipher);
  197. ivlen=EVP_CIPHER_iv_length(evp_cipher);
  198. xalg->algorithm = OBJ_nid2obj(EVP_CIPHER_type(evp_cipher));
  199. if (ivlen > 0) RAND_pseudo_bytes(iv,ivlen);
  200. if (EVP_CipherInit_ex(ctx, evp_cipher, NULL, NULL, NULL, 1)<=0)
  201. goto err;
  202. if (EVP_CIPHER_CTX_rand_key(ctx, key) <= 0)
  203. goto err;
  204. if (EVP_CipherInit_ex(ctx, NULL, NULL, key, iv, 1) <= 0)
  205. goto err;
  206. if (ivlen > 0) {
  207. if (xalg->parameter == NULL) 
  208. xalg->parameter=ASN1_TYPE_new();
  209. if(EVP_CIPHER_param_to_asn1(ctx, xalg->parameter) < 0)
  210.        goto err;
  211. }
  212. /* Lets do the pub key stuff :-) */
  213. max=0;
  214. for (i=0; i<sk_PKCS7_RECIP_INFO_num(rsk); i++)
  215. {
  216. ri=sk_PKCS7_RECIP_INFO_value(rsk,i);
  217. if (ri->cert == NULL)
  218. {
  219. PKCS7err(PKCS7_F_PKCS7_DATAINIT,PKCS7_R_MISSING_CERIPEND_INFO);
  220. goto err;
  221. }
  222. pkey=X509_get_pubkey(ri->cert);
  223. jj=EVP_PKEY_size(pkey);
  224. EVP_PKEY_free(pkey);
  225. if (max < jj) max=jj;
  226. }
  227. if ((tmp=(unsigned char *)OPENSSL_malloc(max)) == NULL)
  228. {
  229. PKCS7err(PKCS7_F_PKCS7_DATAINIT,ERR_R_MALLOC_FAILURE);
  230. goto err;
  231. }
  232. for (i=0; i<sk_PKCS7_RECIP_INFO_num(rsk); i++)
  233. {
  234. ri=sk_PKCS7_RECIP_INFO_value(rsk,i);
  235. pkey=X509_get_pubkey(ri->cert);
  236. jj=EVP_PKEY_encrypt(tmp,key,keylen,pkey);
  237. EVP_PKEY_free(pkey);
  238. if (jj <= 0)
  239. {
  240. PKCS7err(PKCS7_F_PKCS7_DATAINIT,ERR_R_EVP_LIB);
  241. OPENSSL_free(tmp);
  242. goto err;
  243. }
  244. if (!M_ASN1_OCTET_STRING_set(ri->enc_key,tmp,jj))
  245. {
  246. PKCS7err(PKCS7_F_PKCS7_DATAINIT,
  247. ERR_R_MALLOC_FAILURE);
  248. OPENSSL_free(tmp);
  249. goto err;
  250. }
  251. }
  252. OPENSSL_free(tmp);
  253. OPENSSL_cleanse(key, keylen);
  254. if (out == NULL)
  255. out=btmp;
  256. else
  257. BIO_push(out,btmp);
  258. btmp=NULL;
  259. }
  260. if (bio == NULL)
  261. {
  262. if (PKCS7_is_detached(p7))
  263. bio=BIO_new(BIO_s_null());
  264. else if (os && os->length > 0)
  265. bio = BIO_new_mem_buf(os->data, os->length);
  266. if(bio == NULL)
  267. {
  268. bio=BIO_new(BIO_s_mem());
  269. BIO_set_mem_eof_return(bio,0);
  270. }
  271. }
  272. BIO_push(out,bio);
  273. bio=NULL;
  274. if (0)
  275. {
  276. err:
  277. if (out != NULL)
  278. BIO_free_all(out);
  279. if (btmp != NULL)
  280. BIO_free_all(btmp);
  281. out=NULL;
  282. }
  283. return(out);
  284. }
  285. static int pkcs7_cmp_ri(PKCS7_RECIP_INFO *ri, X509 *pcert)
  286. {
  287. int ret;
  288. ret = X509_NAME_cmp(ri->issuer_and_serial->issuer,
  289. pcert->cert_info->issuer);
  290. if (ret)
  291. return ret;
  292. return M_ASN1_INTEGER_cmp(pcert->cert_info->serialNumber,
  293. ri->issuer_and_serial->serial);
  294. }
  295. /* int */
  296. BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert)
  297. {
  298. int i,j;
  299. BIO *out=NULL,*btmp=NULL,*etmp=NULL,*bio=NULL;
  300. unsigned char *tmp=NULL;
  301. X509_ALGOR *xa;
  302. ASN1_OCTET_STRING *data_body=NULL;
  303. const EVP_MD *evp_md;
  304. const EVP_CIPHER *evp_cipher=NULL;
  305. EVP_CIPHER_CTX *evp_ctx=NULL;
  306. X509_ALGOR *enc_alg=NULL;
  307. STACK_OF(X509_ALGOR) *md_sk=NULL;
  308. STACK_OF(PKCS7_RECIP_INFO) *rsk=NULL;
  309. X509_ALGOR *xalg=NULL;
  310. PKCS7_RECIP_INFO *ri=NULL;
  311. i=OBJ_obj2nid(p7->type);
  312. p7->state=PKCS7_S_HEADER;
  313. switch (i)
  314. {
  315. case NID_pkcs7_signed:
  316. data_body=PKCS7_get_octet_string(p7->d.sign->contents);
  317. md_sk=p7->d.sign->md_algs;
  318. break;
  319. case NID_pkcs7_signedAndEnveloped:
  320. rsk=p7->d.signed_and_enveloped->recipientinfo;
  321. md_sk=p7->d.signed_and_enveloped->md_algs;
  322. data_body=p7->d.signed_and_enveloped->enc_data->enc_data;
  323. enc_alg=p7->d.signed_and_enveloped->enc_data->algorithm;
  324. evp_cipher=EVP_get_cipherbyobj(enc_alg->algorithm);
  325. if (evp_cipher == NULL)
  326. {
  327. PKCS7err(PKCS7_F_PKCS7_DATADECODE,PKCS7_R_UNSUPPORTED_CIPHER_TYPE);
  328. goto err;
  329. }
  330. xalg=p7->d.signed_and_enveloped->enc_data->algorithm;
  331. break;
  332. case NID_pkcs7_enveloped:
  333. rsk=p7->d.enveloped->recipientinfo;
  334. enc_alg=p7->d.enveloped->enc_data->algorithm;
  335. data_body=p7->d.enveloped->enc_data->enc_data;
  336. evp_cipher=EVP_get_cipherbyobj(enc_alg->algorithm);
  337. if (evp_cipher == NULL)
  338. {
  339. PKCS7err(PKCS7_F_PKCS7_DATADECODE,PKCS7_R_UNSUPPORTED_CIPHER_TYPE);
  340. goto err;
  341. }
  342. xalg=p7->d.enveloped->enc_data->algorithm;
  343. break;
  344. default:
  345. PKCS7err(PKCS7_F_PKCS7_DATADECODE,PKCS7_R_UNSUPPORTED_CONTENT_TYPE);
  346.         goto err;
  347. }
  348. /* We will be checking the signature */
  349. if (md_sk != NULL)
  350. {
  351. for (i=0; i<sk_X509_ALGOR_num(md_sk); i++)
  352. {
  353. xa=sk_X509_ALGOR_value(md_sk,i);
  354. if ((btmp=BIO_new(BIO_f_md())) == NULL)
  355. {
  356. PKCS7err(PKCS7_F_PKCS7_DATADECODE,ERR_R_BIO_LIB);
  357. goto err;
  358. }
  359. j=OBJ_obj2nid(xa->algorithm);
  360. evp_md=EVP_get_digestbynid(j);
  361. if (evp_md == NULL)
  362. {
  363. PKCS7err(PKCS7_F_PKCS7_DATADECODE,PKCS7_R_UNKNOWN_DIGEST_TYPE);
  364. goto err;
  365. }
  366. BIO_set_md(btmp,evp_md);
  367. if (out == NULL)
  368. out=btmp;
  369. else
  370. BIO_push(out,btmp);
  371. btmp=NULL;
  372. }
  373. }
  374. if (evp_cipher != NULL)
  375. {
  376. #if 0
  377. unsigned char key[EVP_MAX_KEY_LENGTH];
  378. unsigned char iv[EVP_MAX_IV_LENGTH];
  379. unsigned char *p;
  380. int keylen,ivlen;
  381. int max;
  382. X509_OBJECT ret;
  383. #endif
  384. int jj;
  385. if ((etmp=BIO_new(BIO_f_cipher())) == NULL)
  386. {
  387. PKCS7err(PKCS7_F_PKCS7_DATADECODE,ERR_R_BIO_LIB);
  388. goto err;
  389. }
  390. /* It was encrypted, we need to decrypt the secret key
  391.  * with the private key */
  392. /* Find the recipientInfo which matches the passed certificate
  393.  * (if any)
  394.  */
  395. if (pcert) {
  396. for (i=0; i<sk_PKCS7_RECIP_INFO_num(rsk); i++) {
  397. ri=sk_PKCS7_RECIP_INFO_value(rsk,i);
  398. if (!pkcs7_cmp_ri(ri, pcert))
  399. break;
  400. ri=NULL;
  401. }
  402. if (ri == NULL) {
  403. PKCS7err(PKCS7_F_PKCS7_DATADECODE,
  404.       PKCS7_R_NO_RECIPIENT_MATCHES_CERTIFICATE);
  405. goto err;
  406. }
  407. }
  408. jj=EVP_PKEY_size(pkey);
  409. tmp=(unsigned char *)OPENSSL_malloc(jj+10);
  410. if (tmp == NULL)
  411. {
  412. PKCS7err(PKCS7_F_PKCS7_DATADECODE,ERR_R_MALLOC_FAILURE);
  413. goto err;
  414. }
  415. /* If we haven't got a certificate try each ri in turn */
  416. if (pcert == NULL)
  417. {
  418. for (i=0; i<sk_PKCS7_RECIP_INFO_num(rsk); i++)
  419. {
  420. ri=sk_PKCS7_RECIP_INFO_value(rsk,i);
  421. jj=EVP_PKEY_decrypt(tmp,
  422. M_ASN1_STRING_data(ri->enc_key),
  423. M_ASN1_STRING_length(ri->enc_key),
  424. pkey);
  425. if (jj > 0)
  426. break;
  427. ERR_clear_error();
  428. ri = NULL;
  429. }
  430. if (ri == NULL)
  431. {
  432. PKCS7err(PKCS7_F_PKCS7_DATADECODE,
  433.       PKCS7_R_NO_RECIPIENT_MATCHES_KEY);
  434. goto err;
  435. }
  436. }
  437. else
  438. {
  439. jj=EVP_PKEY_decrypt(tmp,
  440. M_ASN1_STRING_data(ri->enc_key),
  441. M_ASN1_STRING_length(ri->enc_key), pkey);
  442. if (jj <= 0)
  443. {
  444. PKCS7err(PKCS7_F_PKCS7_DATADECODE,
  445. ERR_R_EVP_LIB);
  446. goto err;
  447. }
  448. }
  449. evp_ctx=NULL;
  450. BIO_get_cipher_ctx(etmp,&evp_ctx);
  451. if (EVP_CipherInit_ex(evp_ctx,evp_cipher,NULL,NULL,NULL,0) <= 0)
  452. goto err;
  453. if (EVP_CIPHER_asn1_to_param(evp_ctx,enc_alg->parameter) < 0)
  454. goto err;
  455. if (jj != EVP_CIPHER_CTX_key_length(evp_ctx)) {
  456. /* Some S/MIME clients don't use the same key
  457.  * and effective key length. The key length is
  458.  * determined by the size of the decrypted RSA key.
  459.  */
  460. if(!EVP_CIPHER_CTX_set_key_length(evp_ctx, jj))
  461. {
  462. PKCS7err(PKCS7_F_PKCS7_DATADECODE,
  463. PKCS7_R_DECRYPTED_KEY_IS_WRONG_LENGTH);
  464. goto err;
  465. }
  466. if (EVP_CipherInit_ex(evp_ctx,NULL,NULL,tmp,NULL,0) <= 0)
  467. goto err;
  468. OPENSSL_cleanse(tmp,jj);
  469. if (out == NULL)
  470. out=etmp;
  471. else
  472. BIO_push(out,etmp);
  473. etmp=NULL;
  474. }
  475. #if 1
  476. if (PKCS7_is_detached(p7) || (in_bio != NULL))
  477. {
  478. bio=in_bio;
  479. }
  480. else 
  481. {
  482. #if 0
  483. bio=BIO_new(BIO_s_mem());
  484. /* We need to set this so that when we have read all
  485.  * the data, the encrypt BIO, if present, will read
  486.  * EOF and encode the last few bytes */
  487. BIO_set_mem_eof_return(bio,0);
  488. if (data_body->length > 0)
  489. BIO_write(bio,(char *)data_body->data,data_body->length);
  490. #else
  491. if (data_body->length > 0)
  492.       bio = BIO_new_mem_buf(data_body->data,data_body->length);
  493. else {
  494. bio=BIO_new(BIO_s_mem());
  495. BIO_set_mem_eof_return(bio,0);
  496. }
  497. #endif
  498. }
  499. BIO_push(out,bio);
  500. bio=NULL;
  501. #endif
  502. if (0)
  503. {
  504. err:
  505. if (out != NULL) BIO_free_all(out);
  506. if (btmp != NULL) BIO_free_all(btmp);
  507. if (etmp != NULL) BIO_free_all(etmp);
  508. if (bio != NULL) BIO_free_all(bio);
  509. out=NULL;
  510. }
  511. if (tmp != NULL)
  512. OPENSSL_free(tmp);
  513. return(out);
  514. }
  515. static BIO *PKCS7_find_digest(EVP_MD_CTX **pmd, BIO *bio, int nid)
  516. {
  517. for (;;)
  518. {
  519. bio=BIO_find_type(bio,BIO_TYPE_MD);
  520. if (bio == NULL)
  521. {
  522. PKCS7err(PKCS7_F_PKCS7_FIND_DIGEST,PKCS7_R_UNABLE_TO_FIND_MESSAGE_DIGEST);
  523. return NULL;
  524. }
  525. BIO_get_md_ctx(bio,pmd);
  526. if (*pmd == NULL)
  527. {
  528. PKCS7err(PKCS7_F_PKCS7_FIND_DIGEST,ERR_R_INTERNAL_ERROR);
  529. return NULL;
  530. }
  531. if (EVP_MD_CTX_type(*pmd) == nid)
  532. return bio;
  533. bio=BIO_next(bio);
  534. }
  535. return NULL;
  536. }
  537. int PKCS7_dataFinal(PKCS7 *p7, BIO *bio)
  538. {
  539. int ret=0;
  540. int i,j;
  541. BIO *btmp;
  542. BUF_MEM *buf_mem=NULL;
  543. BUF_MEM *buf=NULL;
  544. PKCS7_SIGNER_INFO *si;
  545. EVP_MD_CTX *mdc,ctx_tmp;
  546. STACK_OF(X509_ATTRIBUTE) *sk;
  547. STACK_OF(PKCS7_SIGNER_INFO) *si_sk=NULL;
  548. ASN1_OCTET_STRING *os=NULL;
  549. EVP_MD_CTX_init(&ctx_tmp);
  550. i=OBJ_obj2nid(p7->type);
  551. p7->state=PKCS7_S_HEADER;
  552. switch (i)
  553. {
  554. case NID_pkcs7_signedAndEnveloped:
  555. /* XXXXXXXXXXXXXXXX */
  556. si_sk=p7->d.signed_and_enveloped->signer_info;
  557. if (!(os=M_ASN1_OCTET_STRING_new()))
  558. {
  559. PKCS7err(PKCS7_F_PKCS7_DATAFINAL,ERR_R_MALLOC_FAILURE);
  560. goto err;
  561. }
  562. p7->d.signed_and_enveloped->enc_data->enc_data=os;
  563. break;
  564. case NID_pkcs7_enveloped:
  565. /* XXXXXXXXXXXXXXXX */
  566. if (!(os=M_ASN1_OCTET_STRING_new()))
  567. {
  568. PKCS7err(PKCS7_F_PKCS7_DATAFINAL,ERR_R_MALLOC_FAILURE);
  569. goto err;
  570. }
  571. p7->d.enveloped->enc_data->enc_data=os;
  572. break;
  573. case NID_pkcs7_signed:
  574. si_sk=p7->d.sign->signer_info;
  575. os=PKCS7_get_octet_string(p7->d.sign->contents);
  576. /* If detached data then the content is excluded */
  577. if(PKCS7_type_is_data(p7->d.sign->contents) && p7->detached) {
  578. M_ASN1_OCTET_STRING_free(os);
  579. p7->d.sign->contents->d.data = NULL;
  580. }
  581. break;
  582. case NID_pkcs7_digest:
  583. os=PKCS7_get_octet_string(p7->d.digest->contents);
  584. /* If detached data then the content is excluded */
  585. if(PKCS7_type_is_data(p7->d.digest->contents) && p7->detached)
  586. {
  587. M_ASN1_OCTET_STRING_free(os);
  588. p7->d.digest->contents->d.data = NULL;
  589. }
  590. break;
  591. }
  592. if (si_sk != NULL)
  593. {
  594. if ((buf=BUF_MEM_new()) == NULL)
  595. {
  596. PKCS7err(PKCS7_F_PKCS7_DATAFINAL,ERR_R_BIO_LIB);
  597. goto err;
  598. }
  599. for (i=0; i<sk_PKCS7_SIGNER_INFO_num(si_sk); i++)
  600. {
  601. si=sk_PKCS7_SIGNER_INFO_value(si_sk,i);
  602. if (si->pkey == NULL) continue;
  603. j=OBJ_obj2nid(si->digest_alg->algorithm);
  604. btmp=bio;
  605. btmp = PKCS7_find_digest(&mdc, btmp, j);
  606. if (btmp == NULL)
  607. goto err;
  608. /* We now have the EVP_MD_CTX, lets do the
  609.  * signing. */
  610. EVP_MD_CTX_copy_ex(&ctx_tmp,mdc);
  611. if (!BUF_MEM_grow_clean(buf,EVP_PKEY_size(si->pkey)))
  612. {
  613. PKCS7err(PKCS7_F_PKCS7_DATAFINAL,ERR_R_BIO_LIB);
  614. goto err;
  615. }
  616. sk=si->auth_attr;
  617. /* If there are attributes, we add the digest
  618.  * attribute and only sign the attributes */
  619. if ((sk != NULL) && (sk_X509_ATTRIBUTE_num(sk) != 0))
  620. {
  621. unsigned char md_data[EVP_MAX_MD_SIZE], *abuf=NULL;
  622. unsigned int md_len, alen;
  623. ASN1_OCTET_STRING *digest;
  624. ASN1_UTCTIME *sign_time;
  625. const EVP_MD *md_tmp;
  626. /* Add signing time if not already present */
  627. if (!PKCS7_get_signed_attribute(si,
  628. NID_pkcs9_signingTime))
  629. {
  630. if (!(sign_time=X509_gmtime_adj(NULL,0)))
  631. {
  632. PKCS7err(PKCS7_F_PKCS7_DATAFINAL,
  633. ERR_R_MALLOC_FAILURE);
  634. goto err;
  635. }
  636. PKCS7_add_signed_attribute(si,
  637. NID_pkcs9_signingTime,
  638. V_ASN1_UTCTIME,sign_time);
  639. }
  640. /* Add digest */
  641. md_tmp=EVP_MD_CTX_md(&ctx_tmp);
  642. EVP_DigestFinal_ex(&ctx_tmp,md_data,&md_len);
  643. if (!(digest=M_ASN1_OCTET_STRING_new()))
  644. {
  645. PKCS7err(PKCS7_F_PKCS7_DATAFINAL,
  646. ERR_R_MALLOC_FAILURE);
  647. goto err;
  648. }
  649. if (!M_ASN1_OCTET_STRING_set(digest,md_data,
  650. md_len))
  651. {
  652. PKCS7err(PKCS7_F_PKCS7_DATAFINAL,
  653. ERR_R_MALLOC_FAILURE);
  654. goto err;
  655. }
  656. PKCS7_add_signed_attribute(si,
  657. NID_pkcs9_messageDigest,
  658. V_ASN1_OCTET_STRING,digest);
  659. /* Now sign the attributes */
  660. EVP_SignInit_ex(&ctx_tmp,md_tmp,NULL);
  661. alen = ASN1_item_i2d((ASN1_VALUE *)sk,&abuf,
  662. ASN1_ITEM_rptr(PKCS7_ATTR_SIGN));
  663. if(!abuf) goto err;
  664. EVP_SignUpdate(&ctx_tmp,abuf,alen);
  665. OPENSSL_free(abuf);
  666. }
  667. #ifndef OPENSSL_NO_DSA
  668. if (si->pkey->type == EVP_PKEY_DSA)
  669. ctx_tmp.digest=EVP_dss1();
  670. #endif
  671. #ifndef OPENSSL_NO_ECDSA
  672.   if (si->pkey->type == EVP_PKEY_EC)
  673.   ctx_tmp.digest=EVP_ecdsa();
  674. #endif
  675. if (!EVP_SignFinal(&ctx_tmp,(unsigned char *)buf->data,
  676. (unsigned int *)&buf->length,si->pkey))
  677. {
  678. PKCS7err(PKCS7_F_PKCS7_DATAFINAL,ERR_R_EVP_LIB);
  679. goto err;
  680. }
  681. if (!ASN1_STRING_set(si->enc_digest,
  682. (unsigned char *)buf->data,buf->length))
  683. {
  684. PKCS7err(PKCS7_F_PKCS7_DATAFINAL,ERR_R_ASN1_LIB);
  685. goto err;
  686. }
  687. }
  688. }
  689. else if (i == NID_pkcs7_digest)
  690. {
  691. unsigned char md_data[EVP_MAX_MD_SIZE];
  692. unsigned int md_len;
  693. if (!PKCS7_find_digest(&mdc, bio,
  694. OBJ_obj2nid(p7->d.digest->md->algorithm)))
  695. goto err;
  696. EVP_DigestFinal_ex(mdc,md_data,&md_len);
  697. M_ASN1_OCTET_STRING_set(p7->d.digest->digest, md_data, md_len);
  698. }
  699. if (!PKCS7_is_detached(p7))
  700. {
  701. btmp=BIO_find_type(bio,BIO_TYPE_MEM);
  702. if (btmp == NULL)
  703. {
  704. PKCS7err(PKCS7_F_PKCS7_DATAFINAL,PKCS7_R_UNABLE_TO_FIND_MEM_BIO);
  705. goto err;
  706. }
  707. BIO_get_mem_ptr(btmp,&buf_mem);
  708. /* Mark the BIO read only then we can use its copy of the data
  709.  * instead of making an extra copy.
  710.  */
  711. BIO_set_flags(btmp, BIO_FLAGS_MEM_RDONLY);
  712. BIO_set_mem_eof_return(btmp, 0);
  713. os->data = (unsigned char *)buf_mem->data;
  714. os->length = buf_mem->length;
  715. #if 0
  716. M_ASN1_OCTET_STRING_set(os,
  717. (unsigned char *)buf_mem->data,buf_mem->length);
  718. #endif
  719. }
  720. ret=1;
  721. err:
  722. EVP_MD_CTX_cleanup(&ctx_tmp);
  723. if (buf != NULL) BUF_MEM_free(buf);
  724. return(ret);
  725. }
  726. int PKCS7_dataVerify(X509_STORE *cert_store, X509_STORE_CTX *ctx, BIO *bio,
  727.      PKCS7 *p7, PKCS7_SIGNER_INFO *si)
  728. {
  729. PKCS7_ISSUER_AND_SERIAL *ias;
  730. int ret=0,i;
  731. STACK_OF(X509) *cert;
  732. X509 *x509;
  733. if (PKCS7_type_is_signed(p7))
  734. {
  735. cert=p7->d.sign->cert;
  736. }
  737. else if (PKCS7_type_is_signedAndEnveloped(p7))
  738. {
  739. cert=p7->d.signed_and_enveloped->cert;
  740. }
  741. else
  742. {
  743. PKCS7err(PKCS7_F_PKCS7_DATAVERIFY,PKCS7_R_WRONG_PKCS7_TYPE);
  744. goto err;
  745. }
  746. /* XXXXXXXXXXXXXXXXXXXXXXX */
  747. ias=si->issuer_and_serial;
  748. x509=X509_find_by_issuer_and_serial(cert,ias->issuer,ias->serial);
  749. /* were we able to find the cert in passed to us */
  750. if (x509 == NULL)
  751. {
  752. PKCS7err(PKCS7_F_PKCS7_DATAVERIFY,PKCS7_R_UNABLE_TO_FIND_CERTIFICATE);
  753. goto err;
  754. }
  755. /* Lets verify */
  756. if(!X509_STORE_CTX_init(ctx,cert_store,x509,cert))
  757. {
  758. PKCS7err(PKCS7_F_PKCS7_DATAVERIFY,ERR_R_X509_LIB);
  759. goto err;
  760. }
  761. X509_STORE_CTX_set_purpose(ctx, X509_PURPOSE_SMIME_SIGN);
  762. i=X509_verify_cert(ctx);
  763. if (i <= 0) 
  764. {
  765. PKCS7err(PKCS7_F_PKCS7_DATAVERIFY,ERR_R_X509_LIB);
  766. X509_STORE_CTX_cleanup(ctx);
  767. goto err;
  768. }
  769. X509_STORE_CTX_cleanup(ctx);
  770. return PKCS7_signatureVerify(bio, p7, si, x509);
  771. err:
  772. return ret;
  773. }
  774. int PKCS7_signatureVerify(BIO *bio, PKCS7 *p7, PKCS7_SIGNER_INFO *si,
  775. X509 *x509)
  776. {
  777. ASN1_OCTET_STRING *os;
  778. EVP_MD_CTX mdc_tmp,*mdc;
  779. int ret=0,i;
  780. int md_type;
  781. STACK_OF(X509_ATTRIBUTE) *sk;
  782. BIO *btmp;
  783. EVP_PKEY *pkey;
  784. EVP_MD_CTX_init(&mdc_tmp);
  785. if (!PKCS7_type_is_signed(p7) && 
  786. !PKCS7_type_is_signedAndEnveloped(p7)) {
  787. PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY,
  788. PKCS7_R_WRONG_PKCS7_TYPE);
  789. goto err;
  790. }
  791. md_type=OBJ_obj2nid(si->digest_alg->algorithm);
  792. btmp=bio;
  793. for (;;)
  794. {
  795. if ((btmp == NULL) ||
  796. ((btmp=BIO_find_type(btmp,BIO_TYPE_MD)) == NULL))
  797. {
  798. PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY,
  799. PKCS7_R_UNABLE_TO_FIND_MESSAGE_DIGEST);
  800. goto err;
  801. }
  802. BIO_get_md_ctx(btmp,&mdc);
  803. if (mdc == NULL)
  804. {
  805. PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY,
  806. ERR_R_INTERNAL_ERROR);
  807. goto err;
  808. }
  809. if (EVP_MD_CTX_type(mdc) == md_type)
  810. break;
  811. /* Workaround for some broken clients that put the signature
  812.  * OID instead of the digest OID in digest_alg->algorithm
  813.  */
  814. if (EVP_MD_pkey_type(EVP_MD_CTX_md(mdc)) == md_type)
  815. break;
  816. btmp=BIO_next(btmp);
  817. }
  818. /* mdc is the digest ctx that we want, unless there are attributes,
  819.  * in which case the digest is the signed attributes */
  820. EVP_MD_CTX_copy_ex(&mdc_tmp,mdc);
  821. sk=si->auth_attr;
  822. if ((sk != NULL) && (sk_X509_ATTRIBUTE_num(sk) != 0))
  823. {
  824. unsigned char md_dat[EVP_MAX_MD_SIZE], *abuf = NULL;
  825.                 unsigned int md_len, alen;
  826. ASN1_OCTET_STRING *message_digest;
  827. EVP_DigestFinal_ex(&mdc_tmp,md_dat,&md_len);
  828. message_digest=PKCS7_digest_from_attributes(sk);
  829. if (!message_digest)
  830. {
  831. PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY,
  832. PKCS7_R_UNABLE_TO_FIND_MESSAGE_DIGEST);
  833. goto err;
  834. }
  835. if ((message_digest->length != (int)md_len) ||
  836. (memcmp(message_digest->data,md_dat,md_len)))
  837. {
  838. #if 0
  839. {
  840. int ii;
  841. for (ii=0; ii<message_digest->length; ii++)
  842. printf("%02X",message_digest->data[ii]); printf(" sentn");
  843. for (ii=0; ii<md_len; ii++) printf("%02X",md_dat[ii]); printf(" calcn");
  844. }
  845. #endif
  846. PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY,
  847. PKCS7_R_DIGEST_FAILURE);
  848. ret= -1;
  849. goto err;
  850. }
  851. EVP_VerifyInit_ex(&mdc_tmp,EVP_get_digestbynid(md_type), NULL);
  852. alen = ASN1_item_i2d((ASN1_VALUE *)sk, &abuf,
  853. ASN1_ITEM_rptr(PKCS7_ATTR_VERIFY));
  854. EVP_VerifyUpdate(&mdc_tmp, abuf, alen);
  855. OPENSSL_free(abuf);
  856. }
  857. os=si->enc_digest;
  858. pkey = X509_get_pubkey(x509);
  859. if (!pkey)
  860. {
  861. ret = -1;
  862. goto err;
  863. }
  864. #ifndef OPENSSL_NO_DSA
  865. if(pkey->type == EVP_PKEY_DSA) mdc_tmp.digest=EVP_dss1();
  866. #endif
  867. #ifndef OPENSSL_NO_ECDSA
  868. if (pkey->type == EVP_PKEY_EC) mdc_tmp.digest=EVP_ecdsa();
  869. #endif
  870. i=EVP_VerifyFinal(&mdc_tmp,os->data,os->length, pkey);
  871. EVP_PKEY_free(pkey);
  872. if (i <= 0)
  873. {
  874. PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY,
  875. PKCS7_R_SIGNATURE_FAILURE);
  876. ret= -1;
  877. goto err;
  878. }
  879. else
  880. ret=1;
  881. err:
  882. EVP_MD_CTX_cleanup(&mdc_tmp);
  883. return(ret);
  884. }
  885. PKCS7_ISSUER_AND_SERIAL *PKCS7_get_issuer_and_serial(PKCS7 *p7, int idx)
  886. {
  887. STACK_OF(PKCS7_RECIP_INFO) *rsk;
  888. PKCS7_RECIP_INFO *ri;
  889. int i;
  890. i=OBJ_obj2nid(p7->type);
  891. if (i != NID_pkcs7_signedAndEnveloped) return(NULL);
  892. rsk=p7->d.signed_and_enveloped->recipientinfo;
  893. ri=sk_PKCS7_RECIP_INFO_value(rsk,0);
  894. if (sk_PKCS7_RECIP_INFO_num(rsk) <= idx) return(NULL);
  895. ri=sk_PKCS7_RECIP_INFO_value(rsk,idx);
  896. return(ri->issuer_and_serial);
  897. }
  898. ASN1_TYPE *PKCS7_get_signed_attribute(PKCS7_SIGNER_INFO *si, int nid)
  899. {
  900. return(get_attribute(si->auth_attr,nid));
  901. }
  902. ASN1_TYPE *PKCS7_get_attribute(PKCS7_SIGNER_INFO *si, int nid)
  903. {
  904. return(get_attribute(si->unauth_attr,nid));
  905. }
  906. static ASN1_TYPE *get_attribute(STACK_OF(X509_ATTRIBUTE) *sk, int nid)
  907. {
  908. int i;
  909. X509_ATTRIBUTE *xa;
  910. ASN1_OBJECT *o;
  911. o=OBJ_nid2obj(nid);
  912. if (!o || !sk) return(NULL);
  913. for (i=0; i<sk_X509_ATTRIBUTE_num(sk); i++)
  914. {
  915. xa=sk_X509_ATTRIBUTE_value(sk,i);
  916. if (OBJ_cmp(xa->object,o) == 0)
  917. {
  918. if (!xa->single && sk_ASN1_TYPE_num(xa->value.set))
  919. return(sk_ASN1_TYPE_value(xa->value.set,0));
  920. else
  921. return(NULL);
  922. }
  923. }
  924. return(NULL);
  925. }
  926. ASN1_OCTET_STRING *PKCS7_digest_from_attributes(STACK_OF(X509_ATTRIBUTE) *sk)
  927. {
  928. ASN1_TYPE *astype;
  929. if(!(astype = get_attribute(sk, NID_pkcs9_messageDigest))) return NULL;
  930. return astype->value.octet_string;
  931. }
  932. int PKCS7_set_signed_attributes(PKCS7_SIGNER_INFO *p7si,
  933. STACK_OF(X509_ATTRIBUTE) *sk)
  934. {
  935. int i;
  936. if (p7si->auth_attr != NULL)
  937. sk_X509_ATTRIBUTE_pop_free(p7si->auth_attr,X509_ATTRIBUTE_free);
  938. p7si->auth_attr=sk_X509_ATTRIBUTE_dup(sk);
  939. for (i=0; i<sk_X509_ATTRIBUTE_num(sk); i++)
  940. {
  941. if ((sk_X509_ATTRIBUTE_set(p7si->auth_attr,i,
  942. X509_ATTRIBUTE_dup(sk_X509_ATTRIBUTE_value(sk,i))))
  943.     == NULL)
  944. return(0);
  945. }
  946. return(1);
  947. }
  948. int PKCS7_set_attributes(PKCS7_SIGNER_INFO *p7si, STACK_OF(X509_ATTRIBUTE) *sk)
  949. {
  950. int i;
  951. if (p7si->unauth_attr != NULL)
  952. sk_X509_ATTRIBUTE_pop_free(p7si->unauth_attr,
  953.    X509_ATTRIBUTE_free);
  954. p7si->unauth_attr=sk_X509_ATTRIBUTE_dup(sk);
  955. for (i=0; i<sk_X509_ATTRIBUTE_num(sk); i++)
  956. {
  957. if ((sk_X509_ATTRIBUTE_set(p7si->unauth_attr,i,
  958.                         X509_ATTRIBUTE_dup(sk_X509_ATTRIBUTE_value(sk,i))))
  959.     == NULL)
  960. return(0);
  961. }
  962. return(1);
  963. }
  964. int PKCS7_add_signed_attribute(PKCS7_SIGNER_INFO *p7si, int nid, int atrtype,
  965.      void *value)
  966. {
  967. return(add_attribute(&(p7si->auth_attr),nid,atrtype,value));
  968. }
  969. int PKCS7_add_attribute(PKCS7_SIGNER_INFO *p7si, int nid, int atrtype,
  970.      void *value)
  971. {
  972. return(add_attribute(&(p7si->unauth_attr),nid,atrtype,value));
  973. }
  974. static int add_attribute(STACK_OF(X509_ATTRIBUTE) **sk, int nid, int atrtype,
  975.  void *value)
  976. {
  977. X509_ATTRIBUTE *attr=NULL;
  978. if (*sk == NULL)
  979. {
  980. *sk = sk_X509_ATTRIBUTE_new_null();
  981. new_attrib:
  982. attr=X509_ATTRIBUTE_create(nid,atrtype,value);
  983. sk_X509_ATTRIBUTE_push(*sk,attr);
  984. }
  985. else
  986. {
  987. int i;
  988. for (i=0; i<sk_X509_ATTRIBUTE_num(*sk); i++)
  989. {
  990. attr=sk_X509_ATTRIBUTE_value(*sk,i);
  991. if (OBJ_obj2nid(attr->object) == nid)
  992. {
  993. X509_ATTRIBUTE_free(attr);
  994. attr=X509_ATTRIBUTE_create(nid,atrtype,value);
  995. sk_X509_ATTRIBUTE_set(*sk,i,attr);
  996. goto end;
  997. }
  998. }
  999. goto new_attrib;
  1000. }
  1001. end:
  1002. return(1);
  1003. }