2
0

pk7_doit.c 37 KB

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