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

其他游戏

开发平台:

Visual C++

  1. /* crypto/pkcs7/pk7_lib.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/objects.h>
  61. #include <openssl/x509.h>
  62. long PKCS7_ctrl(PKCS7 *p7, int cmd, long larg, char *parg)
  63. {
  64. int nid;
  65. long ret;
  66. nid=OBJ_obj2nid(p7->type);
  67. switch (cmd)
  68. {
  69. case PKCS7_OP_SET_DETACHED_SIGNATURE:
  70. if (nid == NID_pkcs7_signed)
  71. {
  72. ret=p7->detached=(int)larg;
  73. if (ret && PKCS7_type_is_data(p7->d.sign->contents))
  74. {
  75. ASN1_OCTET_STRING *os;
  76. os=p7->d.sign->contents->d.data;
  77. ASN1_OCTET_STRING_free(os);
  78. p7->d.sign->contents->d.data = NULL;
  79. }
  80. }
  81. else
  82. {
  83. PKCS7err(PKCS7_F_PKCS7_CTRL,PKCS7_R_OPERATION_NOT_SUPPORTED_ON_THIS_TYPE);
  84. ret=0;
  85. }
  86. break;
  87. case PKCS7_OP_GET_DETACHED_SIGNATURE:
  88. if (nid == NID_pkcs7_signed)
  89. {
  90. if(!p7->d.sign  || !p7->d.sign->contents->d.ptr)
  91. ret = 1;
  92. else ret = 0;
  93. p7->detached = ret;
  94. }
  95. else
  96. {
  97. PKCS7err(PKCS7_F_PKCS7_CTRL,PKCS7_R_OPERATION_NOT_SUPPORTED_ON_THIS_TYPE);
  98. ret=0;
  99. }
  100. break;
  101. default:
  102. PKCS7err(PKCS7_F_PKCS7_CTRL,PKCS7_R_UNKNOWN_OPERATION);
  103. ret=0;
  104. }
  105. return(ret);
  106. }
  107. int PKCS7_content_new(PKCS7 *p7, int type)
  108. {
  109. PKCS7 *ret=NULL;
  110. if ((ret=PKCS7_new()) == NULL) goto err;
  111. if (!PKCS7_set_type(ret,type)) goto err;
  112. if (!PKCS7_set_content(p7,ret)) goto err;
  113. return(1);
  114. err:
  115. if (ret != NULL) PKCS7_free(ret);
  116. return(0);
  117. }
  118. int PKCS7_set_content(PKCS7 *p7, PKCS7 *p7_data)
  119. {
  120. int i;
  121. i=OBJ_obj2nid(p7->type);
  122. switch (i)
  123. {
  124. case NID_pkcs7_signed:
  125. if (p7->d.sign->contents != NULL)
  126. PKCS7_free(p7->d.sign->contents);
  127. p7->d.sign->contents=p7_data;
  128. break;
  129. case NID_pkcs7_digest:
  130. if (p7->d.digest->contents != NULL)
  131. PKCS7_free(p7->d.digest->contents);
  132. p7->d.digest->contents=p7_data;
  133. break;
  134. case NID_pkcs7_data:
  135. case NID_pkcs7_enveloped:
  136. case NID_pkcs7_signedAndEnveloped:
  137. case NID_pkcs7_encrypted:
  138. default:
  139. PKCS7err(PKCS7_F_PKCS7_SET_CONTENT,PKCS7_R_UNSUPPORTED_CONTENT_TYPE);
  140. goto err;
  141. }
  142. return(1);
  143. err:
  144. return(0);
  145. }
  146. int PKCS7_set_type(PKCS7 *p7, int type)
  147. {
  148. ASN1_OBJECT *obj;
  149. /*PKCS7_content_free(p7);*/
  150. obj=OBJ_nid2obj(type); /* will not fail */
  151. switch (type)
  152. {
  153. case NID_pkcs7_signed:
  154. p7->type=obj;
  155. if ((p7->d.sign=PKCS7_SIGNED_new()) == NULL)
  156. goto err;
  157. if (!ASN1_INTEGER_set(p7->d.sign->version,1))
  158. {
  159. PKCS7_SIGNED_free(p7->d.sign);
  160. p7->d.sign=NULL;
  161. goto err;
  162. }
  163. break;
  164. case NID_pkcs7_data:
  165. p7->type=obj;
  166. if ((p7->d.data=M_ASN1_OCTET_STRING_new()) == NULL)
  167. goto err;
  168. break;
  169. case NID_pkcs7_signedAndEnveloped:
  170. p7->type=obj;
  171. if ((p7->d.signed_and_enveloped=PKCS7_SIGN_ENVELOPE_new())
  172. == NULL) goto err;
  173. ASN1_INTEGER_set(p7->d.signed_and_enveloped->version,1);
  174. if (!ASN1_INTEGER_set(p7->d.signed_and_enveloped->version,1))
  175. goto err;
  176. p7->d.signed_and_enveloped->enc_data->content_type
  177. = OBJ_nid2obj(NID_pkcs7_data);
  178. break;
  179. case NID_pkcs7_enveloped:
  180. p7->type=obj;
  181. if ((p7->d.enveloped=PKCS7_ENVELOPE_new())
  182. == NULL) goto err;
  183. if (!ASN1_INTEGER_set(p7->d.enveloped->version,0))
  184. goto err;
  185. p7->d.enveloped->enc_data->content_type
  186. = OBJ_nid2obj(NID_pkcs7_data);
  187. break;
  188. case NID_pkcs7_encrypted:
  189. p7->type=obj;
  190. if ((p7->d.encrypted=PKCS7_ENCRYPT_new())
  191. == NULL) goto err;
  192. if (!ASN1_INTEGER_set(p7->d.encrypted->version,0))
  193. goto err;
  194. p7->d.encrypted->enc_data->content_type
  195. = OBJ_nid2obj(NID_pkcs7_data);
  196. break;
  197. case NID_pkcs7_digest:
  198. p7->type=obj;
  199. if ((p7->d.digest=PKCS7_DIGEST_new())
  200. == NULL) goto err;
  201. if (!ASN1_INTEGER_set(p7->d.digest->version,0))
  202. goto err;
  203. break;
  204. default:
  205. PKCS7err(PKCS7_F_PKCS7_SET_TYPE,PKCS7_R_UNSUPPORTED_CONTENT_TYPE);
  206. goto err;
  207. }
  208. return(1);
  209. err:
  210. return(0);
  211. }
  212. int PKCS7_set0_type_other(PKCS7 *p7, int type, ASN1_TYPE *other)
  213. {
  214. p7->type = OBJ_nid2obj(type);
  215. p7->d.other = other;
  216. return 1;
  217. }
  218. int PKCS7_add_signer(PKCS7 *p7, PKCS7_SIGNER_INFO *psi)
  219. {
  220. int i,j,nid;
  221. X509_ALGOR *alg;
  222. STACK_OF(PKCS7_SIGNER_INFO) *signer_sk;
  223. STACK_OF(X509_ALGOR) *md_sk;
  224. i=OBJ_obj2nid(p7->type);
  225. switch (i)
  226. {
  227. case NID_pkcs7_signed:
  228. signer_sk= p7->d.sign->signer_info;
  229. md_sk= p7->d.sign->md_algs;
  230. break;
  231. case NID_pkcs7_signedAndEnveloped:
  232. signer_sk= p7->d.signed_and_enveloped->signer_info;
  233. md_sk= p7->d.signed_and_enveloped->md_algs;
  234. break;
  235. default:
  236. PKCS7err(PKCS7_F_PKCS7_ADD_SIGNER,PKCS7_R_WRONG_CONTENT_TYPE);
  237. return(0);
  238. }
  239. nid=OBJ_obj2nid(psi->digest_alg->algorithm);
  240. /* If the digest is not currently listed, add it */
  241. j=0;
  242. for (i=0; i<sk_X509_ALGOR_num(md_sk); i++)
  243. {
  244. alg=sk_X509_ALGOR_value(md_sk,i);
  245. if (OBJ_obj2nid(alg->algorithm) == nid)
  246. {
  247. j=1;
  248. break;
  249. }
  250. }
  251. if (!j) /* we need to add another algorithm */
  252. {
  253. if(!(alg=X509_ALGOR_new())
  254. || !(alg->parameter = ASN1_TYPE_new())) {
  255. PKCS7err(PKCS7_F_PKCS7_ADD_SIGNER,ERR_R_MALLOC_FAILURE);
  256. return(0);
  257. }
  258. alg->algorithm=OBJ_nid2obj(nid);
  259. alg->parameter->type = V_ASN1_NULL;
  260. sk_X509_ALGOR_push(md_sk,alg);
  261. }
  262. sk_PKCS7_SIGNER_INFO_push(signer_sk,psi);
  263. return(1);
  264. }
  265. int PKCS7_add_certificate(PKCS7 *p7, X509 *x509)
  266. {
  267. int i;
  268. STACK_OF(X509) **sk;
  269. i=OBJ_obj2nid(p7->type);
  270. switch (i)
  271. {
  272. case NID_pkcs7_signed:
  273. sk= &(p7->d.sign->cert);
  274. break;
  275. case NID_pkcs7_signedAndEnveloped:
  276. sk= &(p7->d.signed_and_enveloped->cert);
  277. break;
  278. default:
  279. PKCS7err(PKCS7_F_PKCS7_ADD_CERTIFICATE,PKCS7_R_WRONG_CONTENT_TYPE);
  280. return(0);
  281. }
  282. if (*sk == NULL)
  283. *sk=sk_X509_new_null();
  284. CRYPTO_add(&x509->references,1,CRYPTO_LOCK_X509);
  285. sk_X509_push(*sk,x509);
  286. return(1);
  287. }
  288. int PKCS7_add_crl(PKCS7 *p7, X509_CRL *crl)
  289. {
  290. int i;
  291. STACK_OF(X509_CRL) **sk;
  292. i=OBJ_obj2nid(p7->type);
  293. switch (i)
  294. {
  295. case NID_pkcs7_signed:
  296. sk= &(p7->d.sign->crl);
  297. break;
  298. case NID_pkcs7_signedAndEnveloped:
  299. sk= &(p7->d.signed_and_enveloped->crl);
  300. break;
  301. default:
  302. PKCS7err(PKCS7_F_PKCS7_ADD_CRL,PKCS7_R_WRONG_CONTENT_TYPE);
  303. return(0);
  304. }
  305. if (*sk == NULL)
  306. *sk=sk_X509_CRL_new_null();
  307. CRYPTO_add(&crl->references,1,CRYPTO_LOCK_X509_CRL);
  308. sk_X509_CRL_push(*sk,crl);
  309. return(1);
  310. }
  311. int PKCS7_SIGNER_INFO_set(PKCS7_SIGNER_INFO *p7i, X509 *x509, EVP_PKEY *pkey,
  312.      const EVP_MD *dgst)
  313. {
  314. int nid;
  315. char is_dsa;
  316. if (pkey->type == EVP_PKEY_DSA || pkey->type == EVP_PKEY_EC)
  317. is_dsa = 1;
  318. else
  319. is_dsa = 0;
  320. /* We now need to add another PKCS7_SIGNER_INFO entry */
  321. if (!ASN1_INTEGER_set(p7i->version,1))
  322. goto err;
  323. if (!X509_NAME_set(&p7i->issuer_and_serial->issuer,
  324. X509_get_issuer_name(x509)))
  325. goto err;
  326. /* because ASN1_INTEGER_set is used to set a 'long' we will do
  327.  * things the ugly way. */
  328. M_ASN1_INTEGER_free(p7i->issuer_and_serial->serial);
  329. if (!(p7i->issuer_and_serial->serial=
  330. M_ASN1_INTEGER_dup(X509_get_serialNumber(x509))))
  331. goto err;
  332. /* lets keep the pkey around for a while */
  333. CRYPTO_add(&pkey->references,1,CRYPTO_LOCK_EVP_PKEY);
  334. p7i->pkey=pkey;
  335. /* Set the algorithms */
  336. if (is_dsa) p7i->digest_alg->algorithm=OBJ_nid2obj(NID_sha1);
  337. else
  338. p7i->digest_alg->algorithm=OBJ_nid2obj(EVP_MD_type(dgst));
  339. if (p7i->digest_alg->parameter != NULL)
  340. ASN1_TYPE_free(p7i->digest_alg->parameter);
  341. if ((p7i->digest_alg->parameter=ASN1_TYPE_new()) == NULL)
  342. goto err;
  343. p7i->digest_alg->parameter->type=V_ASN1_NULL;
  344. if (p7i->digest_enc_alg->parameter != NULL)
  345. ASN1_TYPE_free(p7i->digest_enc_alg->parameter);
  346. nid = EVP_PKEY_type(pkey->type);
  347. if (nid == EVP_PKEY_RSA)
  348. {
  349. p7i->digest_enc_alg->algorithm=OBJ_nid2obj(NID_rsaEncryption);
  350. if (!(p7i->digest_enc_alg->parameter=ASN1_TYPE_new()))
  351. goto err;
  352. p7i->digest_enc_alg->parameter->type=V_ASN1_NULL;
  353. }
  354. else if (nid == EVP_PKEY_DSA)
  355. {
  356. #if 1
  357. /* use 'dsaEncryption' OID for compatibility with other software
  358.  * (PKCS #7 v1.5 does specify how to handle DSA) ... */
  359. p7i->digest_enc_alg->algorithm=OBJ_nid2obj(NID_dsa);
  360. #else
  361. /* ... although the 'dsaWithSHA1' OID (as required by RFC 2630 for CMS)
  362.  * would make more sense. */
  363. p7i->digest_enc_alg->algorithm=OBJ_nid2obj(NID_dsaWithSHA1);
  364. #endif
  365. p7i->digest_enc_alg->parameter = NULL; /* special case for DSA: omit 'parameter'! */
  366. }
  367. else if (nid == EVP_PKEY_EC)
  368. {
  369. p7i->digest_enc_alg->algorithm=OBJ_nid2obj(NID_ecdsa_with_SHA1);
  370. if (!(p7i->digest_enc_alg->parameter=ASN1_TYPE_new()))
  371. goto err;
  372. p7i->digest_enc_alg->parameter->type=V_ASN1_NULL;
  373. }
  374. else
  375. return(0);
  376. return(1);
  377. err:
  378. return(0);
  379. }
  380. PKCS7_SIGNER_INFO *PKCS7_add_signature(PKCS7 *p7, X509 *x509, EVP_PKEY *pkey,
  381.      const EVP_MD *dgst)
  382. {
  383. PKCS7_SIGNER_INFO *si;
  384. if ((si=PKCS7_SIGNER_INFO_new()) == NULL) goto err;
  385. if (!PKCS7_SIGNER_INFO_set(si,x509,pkey,dgst)) goto err;
  386. if (!PKCS7_add_signer(p7,si)) goto err;
  387. return(si);
  388. err:
  389. return(NULL);
  390. }
  391. int PKCS7_set_digest(PKCS7 *p7, const EVP_MD *md)
  392. {
  393. if (PKCS7_type_is_digest(p7))
  394. {
  395. if(!(p7->d.digest->md->parameter = ASN1_TYPE_new()))
  396. {
  397. PKCS7err(PKCS7_F_PKCS7_SET_DIGEST,ERR_R_MALLOC_FAILURE);
  398. return 0;
  399. }
  400. p7->d.digest->md->parameter->type = V_ASN1_NULL;
  401. p7->d.digest->md->algorithm = OBJ_nid2obj(EVP_MD_nid(md));
  402. return 1;
  403. }
  404. PKCS7err(PKCS7_F_PKCS7_SET_DIGEST,PKCS7_R_WRONG_CONTENT_TYPE);
  405. return 1;
  406. }
  407. STACK_OF(PKCS7_SIGNER_INFO) *PKCS7_get_signer_info(PKCS7 *p7)
  408. {
  409. if (PKCS7_type_is_signed(p7))
  410. {
  411. return(p7->d.sign->signer_info);
  412. }
  413. else if (PKCS7_type_is_signedAndEnveloped(p7))
  414. {
  415. return(p7->d.signed_and_enveloped->signer_info);
  416. }
  417. else
  418. return(NULL);
  419. }
  420. PKCS7_RECIP_INFO *PKCS7_add_recipient(PKCS7 *p7, X509 *x509)
  421. {
  422. PKCS7_RECIP_INFO *ri;
  423. if ((ri=PKCS7_RECIP_INFO_new()) == NULL) goto err;
  424. if (!PKCS7_RECIP_INFO_set(ri,x509)) goto err;
  425. if (!PKCS7_add_recipient_info(p7,ri)) goto err;
  426. return(ri);
  427. err:
  428. return(NULL);
  429. }
  430. int PKCS7_add_recipient_info(PKCS7 *p7, PKCS7_RECIP_INFO *ri)
  431. {
  432. int i;
  433. STACK_OF(PKCS7_RECIP_INFO) *sk;
  434. i=OBJ_obj2nid(p7->type);
  435. switch (i)
  436. {
  437. case NID_pkcs7_signedAndEnveloped:
  438. sk= p7->d.signed_and_enveloped->recipientinfo;
  439. break;
  440. case NID_pkcs7_enveloped:
  441. sk= p7->d.enveloped->recipientinfo;
  442. break;
  443. default:
  444. PKCS7err(PKCS7_F_PKCS7_ADD_RECIPIENT_INFO,PKCS7_R_WRONG_CONTENT_TYPE);
  445. return(0);
  446. }
  447. sk_PKCS7_RECIP_INFO_push(sk,ri);
  448. return(1);
  449. }
  450. int PKCS7_RECIP_INFO_set(PKCS7_RECIP_INFO *p7i, X509 *x509)
  451. {
  452. if (!ASN1_INTEGER_set(p7i->version,0))
  453. return 0;
  454. if (!X509_NAME_set(&p7i->issuer_and_serial->issuer,
  455. X509_get_issuer_name(x509)))
  456. return 0;
  457. M_ASN1_INTEGER_free(p7i->issuer_and_serial->serial);
  458. if (!(p7i->issuer_and_serial->serial=
  459. M_ASN1_INTEGER_dup(X509_get_serialNumber(x509))))
  460. return 0;
  461. X509_ALGOR_free(p7i->key_enc_algor);
  462. if (!(p7i->key_enc_algor= X509_ALGOR_dup(x509->cert_info->key->algor)))
  463. return 0;
  464. CRYPTO_add(&x509->references,1,CRYPTO_LOCK_X509);
  465. p7i->cert=x509;
  466. return(1);
  467. }
  468. X509 *PKCS7_cert_from_signer_info(PKCS7 *p7, PKCS7_SIGNER_INFO *si)
  469. {
  470. if (PKCS7_type_is_signed(p7))
  471. return(X509_find_by_issuer_and_serial(p7->d.sign->cert,
  472. si->issuer_and_serial->issuer,
  473. si->issuer_and_serial->serial));
  474. else
  475. return(NULL);
  476. }
  477. int PKCS7_set_cipher(PKCS7 *p7, const EVP_CIPHER *cipher)
  478. {
  479. int i;
  480. ASN1_OBJECT *objtmp;
  481. PKCS7_ENC_CONTENT *ec;
  482. i=OBJ_obj2nid(p7->type);
  483. switch (i)
  484. {
  485. case NID_pkcs7_signedAndEnveloped:
  486. ec=p7->d.signed_and_enveloped->enc_data;
  487. break;
  488. case NID_pkcs7_enveloped:
  489. ec=p7->d.enveloped->enc_data;
  490. break;
  491. default:
  492. PKCS7err(PKCS7_F_PKCS7_SET_CIPHER,PKCS7_R_WRONG_CONTENT_TYPE);
  493. return(0);
  494. }
  495. /* Check cipher OID exists and has data in it*/
  496. i = EVP_CIPHER_type(cipher);
  497. if(i == NID_undef) {
  498. PKCS7err(PKCS7_F_PKCS7_SET_CIPHER,PKCS7_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER);
  499. return(0);
  500. }
  501. objtmp = OBJ_nid2obj(i);
  502. ec->cipher = cipher;
  503. return 1;
  504. }