OpenSSL  1.0.1c
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Macros
cms_lib.c
Go to the documentation of this file.
1 /* crypto/cms/cms_lib.c */
2 /* Written by Dr Stephen N Henson ([email protected]) for the OpenSSL
3  * project.
4  */
5 /* ====================================================================
6  * Copyright (c) 2008 The OpenSSL Project. All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  *
12  * 1. Redistributions of source code must retain the above copyright
13  * notice, this list of conditions and the following disclaimer.
14  *
15  * 2. Redistributions in binary form must reproduce the above copyright
16  * notice, this list of conditions and the following disclaimer in
17  * the documentation and/or other materials provided with the
18  * distribution.
19  *
20  * 3. All advertising materials mentioning features or use of this
21  * software must display the following acknowledgment:
22  * "This product includes software developed by the OpenSSL Project
23  * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
24  *
25  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
26  * endorse or promote products derived from this software without
27  * prior written permission. For written permission, please contact
29  *
30  * 5. Products derived from this software may not be called "OpenSSL"
31  * nor may "OpenSSL" appear in their names without prior written
32  * permission of the OpenSSL Project.
33  *
34  * 6. Redistributions of any form whatsoever must retain the following
35  * acknowledgment:
36  * "This product includes software developed by the OpenSSL Project
37  * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
38  *
39  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
40  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
43  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50  * OF THE POSSIBILITY OF SUCH DAMAGE.
51  * ====================================================================
52  */
53 
54 #include <openssl/asn1t.h>
55 #include <openssl/x509.h>
56 #include <openssl/err.h>
57 #include <openssl/pem.h>
58 #include <openssl/bio.h>
59 #include <openssl/asn1.h>
60 #include "cms.h"
61 #include "cms_lcl.h"
62 
65 
70 
72  {
73  return cms->contentType;
74  }
75 
77  {
78  CMS_ContentInfo *cms;
79  cms = CMS_ContentInfo_new();
80  if (cms)
81  {
83  /* Never detached */
84  CMS_set_detached(cms, 0);
85  }
86  return cms;
87  }
88 
90  {
92  if (!pos)
93  return NULL;
94  /* If content detached data goes nowhere: create NULL BIO */
95  if (!*pos)
96  return BIO_new(BIO_s_null());
97  /* If content not detached and created return memory BIO
98  */
99  if (!*pos || ((*pos)->flags == ASN1_STRING_FLAG_CONT))
100  return BIO_new(BIO_s_mem());
101  /* Else content was read in: return read only BIO for it */
102  return BIO_new_mem_buf((*pos)->data, (*pos)->length);
103  }
104 
106  {
107  BIO *cmsbio, *cont;
108  if (icont)
109  cont = icont;
110  else
111  cont = cms_content_bio(cms);
112  if (!cont)
113  {
115  return NULL;
116  }
117  switch (OBJ_obj2nid(cms->contentType))
118  {
119 
120  case NID_pkcs7_data:
121  return cont;
122 
123  case NID_pkcs7_signed:
124  cmsbio = cms_SignedData_init_bio(cms);
125  break;
126 
127  case NID_pkcs7_digest:
128  cmsbio = cms_DigestedData_init_bio(cms);
129  break;
130 #ifdef ZLIB
132  cmsbio = cms_CompressedData_init_bio(cms);
133  break;
134 #endif
135 
136  case NID_pkcs7_encrypted:
137  cmsbio = cms_EncryptedData_init_bio(cms);
138  break;
139 
140  case NID_pkcs7_enveloped:
141  cmsbio = cms_EnvelopedData_init_bio(cms);
142  break;
143 
144  default:
146  return NULL;
147  }
148 
149  if (cmsbio)
150  return BIO_push(cmsbio, cont);
151 
152  if (!icont)
153  BIO_free(cont);
154  return NULL;
155 
156  }
157 
159  {
160  ASN1_OCTET_STRING **pos = CMS_get0_content(cms);
161  if (!pos)
162  return 0;
163  /* If ebmedded content find memory BIO and set content */
164  if (*pos && ((*pos)->flags & ASN1_STRING_FLAG_CONT))
165  {
166  BIO *mbio;
167  unsigned char *cont;
168  long contlen;
169  mbio = BIO_find_type(cmsbio, BIO_TYPE_MEM);
170  if (!mbio)
171  {
173  return 0;
174  }
175  contlen = BIO_get_mem_data(mbio, &cont);
176  /* Set bio as read only so its content can't be clobbered */
178  BIO_set_mem_eof_return(mbio, 0);
179  ASN1_STRING_set0(*pos, cont, contlen);
180  (*pos)->flags &= ~ASN1_STRING_FLAG_CONT;
181  }
182 
183  switch (OBJ_obj2nid(cms->contentType))
184  {
185 
186  case NID_pkcs7_data:
187  case NID_pkcs7_enveloped:
188  case NID_pkcs7_encrypted:
190  /* Nothing to do */
191  return 1;
192 
193  case NID_pkcs7_signed:
194  return cms_SignedData_final(cms, cmsbio);
195 
196  case NID_pkcs7_digest:
197  return cms_DigestedData_do_final(cms, cmsbio, 0);
198 
199  default:
201  return 0;
202  }
203  }
204 
205 /* Return an OCTET STRING pointer to content. This allows it to
206  * be accessed or set later.
207  */
208 
210  {
211  switch (OBJ_obj2nid(cms->contentType))
212  {
213 
214  case NID_pkcs7_data:
215  return &cms->d.data;
216 
217  case NID_pkcs7_signed:
218  return &cms->d.signedData->encapContentInfo->eContent;
219 
220  case NID_pkcs7_enveloped:
222 
223  case NID_pkcs7_digest:
224  return &cms->d.digestedData->encapContentInfo->eContent;
225 
226  case NID_pkcs7_encrypted:
228 
231 
233  return &cms->d.compressedData->encapContentInfo->eContent;
234 
235  default:
236  if (cms->d.other->type == V_ASN1_OCTET_STRING)
237  return &cms->d.other->value.octet_string;
239  return NULL;
240 
241  }
242  }
243 
244 /* Return an ASN1_OBJECT pointer to content type. This allows it to
245  * be accessed or set later.
246  */
247 
248 static ASN1_OBJECT **cms_get0_econtent_type(CMS_ContentInfo *cms)
249  {
250  switch (OBJ_obj2nid(cms->contentType))
251  {
252 
253  case NID_pkcs7_signed:
254  return &cms->d.signedData->encapContentInfo->eContentType;
255 
256  case NID_pkcs7_enveloped:
258 
259  case NID_pkcs7_digest:
261 
262  case NID_pkcs7_encrypted:
264 
267 
270 
271  default:
274  return NULL;
275 
276  }
277  }
278 
280  {
281  ASN1_OBJECT **petype;
282  petype = cms_get0_econtent_type(cms);
283  if (petype)
284  return *petype;
285  return NULL;
286  }
287 
289  {
290  ASN1_OBJECT **petype, *etype;
291  petype = cms_get0_econtent_type(cms);
292  if (!petype)
293  return 0;
294  if (!oid)
295  return 1;
296  etype = OBJ_dup(oid);
297  if (!etype)
298  return 0;
299  ASN1_OBJECT_free(*petype);
300  *petype = etype;
301  return 1;
302  }
303 
305  {
306  ASN1_OCTET_STRING **pos;
307  pos = CMS_get0_content(cms);
308  if (!pos)
309  return -1;
310  if (*pos)
311  return 0;
312  return 1;
313  }
314 
315 int CMS_set_detached(CMS_ContentInfo *cms, int detached)
316  {
317  ASN1_OCTET_STRING **pos;
318  pos = CMS_get0_content(cms);
319  if (!pos)
320  return 0;
321  if (detached)
322  {
323  if (*pos)
324  {
325  ASN1_OCTET_STRING_free(*pos);
326  *pos = NULL;
327  }
328  return 1;
329  }
330  if (!*pos)
331  *pos = ASN1_OCTET_STRING_new();
332  if (*pos)
333  {
334  /* NB: special flag to show content is created and not
335  * read in.
336  */
337  (*pos)->flags |= ASN1_STRING_FLAG_CONT;
338  return 1;
339  }
341  return 0;
342  }
343 
344 /* Set up an X509_ALGOR DigestAlgorithmIdentifier from an EVP_MD */
345 
347  {
348  int param_type;
349 
351  param_type = V_ASN1_UNDEF;
352  else
353  param_type = V_ASN1_NULL;
354 
355  X509_ALGOR_set0(alg, OBJ_nid2obj(EVP_MD_type(md)), param_type, NULL);
356 
357  }
358 
359 /* Create a digest BIO from an X509_ALGOR structure */
360 
362  {
363  BIO *mdbio = NULL;
364  ASN1_OBJECT *digestoid;
365  const EVP_MD *digest;
366  X509_ALGOR_get0(&digestoid, NULL, NULL, digestAlgorithm);
367  digest = EVP_get_digestbyobj(digestoid);
368  if (!digest)
369  {
372  goto err;
373  }
374  mdbio = BIO_new(BIO_f_md());
375  if (!mdbio || !BIO_set_md(mdbio, digest))
376  {
379  goto err;
380  }
381  return mdbio;
382  err:
383  if (mdbio)
384  BIO_free(mdbio);
385  return NULL;
386  }
387 
388 /* Locate a message digest content from a BIO chain based on SignerInfo */
389 
391  X509_ALGOR *mdalg)
392  {
393  int nid;
394  ASN1_OBJECT *mdoid;
395  X509_ALGOR_get0(&mdoid, NULL, NULL, mdalg);
396  nid = OBJ_obj2nid(mdoid);
397  /* Look for digest type to match signature */
398  for (;;)
399  {
400  EVP_MD_CTX *mtmp;
401  chain = BIO_find_type(chain, BIO_TYPE_MD);
402  if (chain == NULL)
403  {
406  return 0;
407  }
408  BIO_get_md_ctx(chain, &mtmp);
409  if (EVP_MD_CTX_type(mtmp) == nid
410  /* Workaround for broken implementations that use signature
411  * algorithm OID instead of digest.
412  */
413  || EVP_MD_pkey_type(EVP_MD_CTX_md(mtmp)) == nid)
414  {
415  return EVP_MD_CTX_copy_ex(mctx, mtmp);
416  }
417  chain = BIO_next(chain);
418  }
419  }
420 
421 static STACK_OF(CMS_CertificateChoices) **cms_get0_certificate_choices(CMS_ContentInfo *cms)
422  {
423  switch (OBJ_obj2nid(cms->contentType))
424  {
425 
426  case NID_pkcs7_signed:
427  return &cms->d.signedData->certificates;
428 
429  case NID_pkcs7_enveloped:
430  return &cms->d.envelopedData->originatorInfo->certificates;
431 
432  default:
435  return NULL;
436 
437  }
438  }
439 
441  {
444  pcerts = cms_get0_certificate_choices(cms);
445  if (!pcerts)
446  return NULL;
447  if (!*pcerts)
449  if (!*pcerts)
450  return NULL;
452  if (!cch)
453  return NULL;
454  if (!sk_CMS_CertificateChoices_push(*pcerts, cch))
455  {
457  return NULL;
458  }
459  return cch;
460  }
461 
463  {
466  int i;
467  pcerts = cms_get0_certificate_choices(cms);
468  if (!pcerts)
469  return 0;
470  if (!pcerts)
471  return 0;
472  for (i = 0; i < sk_CMS_CertificateChoices_num(*pcerts); i++)
473  {
474  cch = sk_CMS_CertificateChoices_value(*pcerts, i);
475  if (cch->type == CMS_CERTCHOICE_CERT)
476  {
477  if (!X509_cmp(cch->d.certificate, cert))
478  {
481  return 0;
482  }
483  }
484  }
485  cch = CMS_add0_CertificateChoices(cms);
486  if (!cch)
487  return 0;
488  cch->type = CMS_CERTCHOICE_CERT;
489  cch->d.certificate = cert;
490  return 1;
491  }
492 
494  {
495  int r;
496  r = CMS_add0_cert(cms, cert);
497  if (r > 0)
499  return r;
500  }
501 
502 static STACK_OF(CMS_RevocationInfoChoice) **cms_get0_revocation_choices(CMS_ContentInfo *cms)
503  {
504  switch (OBJ_obj2nid(cms->contentType))
505  {
506 
507  case NID_pkcs7_signed:
508  return &cms->d.signedData->crls;
509 
510  case NID_pkcs7_enveloped:
511  return &cms->d.envelopedData->originatorInfo->crls;
512 
513  default:
516  return NULL;
517 
518  }
519  }
520 
522  {
525  pcrls = cms_get0_revocation_choices(cms);
526  if (!pcrls)
527  return NULL;
528  if (!*pcrls)
530  if (!*pcrls)
531  return NULL;
533  if (!rch)
534  return NULL;
535  if (!sk_CMS_RevocationInfoChoice_push(*pcrls, rch))
536  {
538  return NULL;
539  }
540  return rch;
541  }
542 
544  {
547  if (!rch)
548  return 0;
549  rch->type = CMS_REVCHOICE_CRL;
550  rch->d.crl = crl;
551  return 1;
552  }
553 
555  {
556  int r;
557  r = CMS_add0_crl(cms, crl);
558  if (r > 0)
560  return r;
561  }
562 
563 STACK_OF(X509) *CMS_get1_certs(CMS_ContentInfo *cms)
564  {
565  STACK_OF(X509) *certs = NULL;
568  int i;
569  pcerts = cms_get0_certificate_choices(cms);
570  if (!pcerts)
571  return NULL;
572  for (i = 0; i < sk_CMS_CertificateChoices_num(*pcerts); i++)
573  {
574  cch = sk_CMS_CertificateChoices_value(*pcerts, i);
575  if (cch->type == 0)
576  {
577  if (!certs)
578  {
579  certs = sk_X509_new_null();
580  if (!certs)
581  return NULL;
582  }
583  if (!sk_X509_push(certs, cch->d.certificate))
584  {
585  sk_X509_pop_free(certs, X509_free);
586  return NULL;
587  }
589  1, CRYPTO_LOCK_X509);
590  }
591  }
592  return certs;
593 
594  }
595 
596 STACK_OF(X509_CRL) *CMS_get1_crls(CMS_ContentInfo *cms)
597  {
598  STACK_OF(X509_CRL) *crls = NULL;
601  int i;
602  pcrls = cms_get0_revocation_choices(cms);
603  if (!pcrls)
604  return NULL;
605  for (i = 0; i < sk_CMS_RevocationInfoChoice_num(*pcrls); i++)
606  {
607  rch = sk_CMS_RevocationInfoChoice_value(*pcrls, i);
608  if (rch->type == 0)
609  {
610  if (!crls)
611  {
612  crls = sk_X509_CRL_new_null();
613  if (!crls)
614  return NULL;
615  }
616  if (!sk_X509_CRL_push(crls, rch->d.crl))
617  {
618  sk_X509_CRL_pop_free(crls, X509_CRL_free);
619  return NULL;
620  }
621  CRYPTO_add(&rch->d.crl->references,
623  }
624  }
625  return crls;
626  }