iPXE
cms.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2012 Michael Brown <mbrown@fensystems.co.uk>.
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License as
6  * published by the Free Software Foundation; either version 2 of the
7  * License, or any later version.
8  *
9  * This program is distributed in the hope that it will be useful, but
10  * WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17  * 02110-1301, USA.
18  *
19  * You can also choose to distribute this program under the terms of
20  * the Unmodified Binary Distribution Licence (as given in the file
21  * COPYING.UBDL), provided that you have satisfied its requirements.
22  */
23 
24 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
25 
26 /** @file
27  *
28  * Cryptographic Message Syntax (PKCS #7)
29  *
30  * The format of CMS messages is defined in RFC 5652.
31  *
32  */
33 
34 #include <stdint.h>
35 #include <string.h>
36 #include <time.h>
37 #include <errno.h>
38 #include <ipxe/asn1.h>
39 #include <ipxe/x509.h>
40 #include <ipxe/image.h>
41 #include <ipxe/malloc.h>
42 #include <ipxe/privkey.h>
43 #include <ipxe/cms.h>
44 
45 /* Disambiguate the various error causes */
46 #define EACCES_NON_SIGNING \
47  __einfo_error ( EINFO_EACCES_NON_SIGNING )
48 #define EINFO_EACCES_NON_SIGNING \
49  __einfo_uniqify ( EINFO_EACCES, 0x01, "Not a signing certificate" )
50 #define EACCES_NON_CODE_SIGNING \
51  __einfo_error ( EINFO_EACCES_NON_CODE_SIGNING )
52 #define EINFO_EACCES_NON_CODE_SIGNING \
53  __einfo_uniqify ( EINFO_EACCES, 0x02, "Not a code-signing certificate" )
54 #define EACCES_WRONG_NAME \
55  __einfo_error ( EINFO_EACCES_WRONG_NAME )
56 #define EINFO_EACCES_WRONG_NAME \
57  __einfo_uniqify ( EINFO_EACCES, 0x04, "Incorrect certificate name" )
58 #define EACCES_NO_SIGNATURES \
59  __einfo_error ( EINFO_EACCES_NO_SIGNATURES )
60 #define EINFO_EACCES_NO_SIGNATURES \
61  __einfo_uniqify ( EINFO_EACCES, 0x05, "No signatures present" )
62 #define EACCES_NO_RECIPIENTS \
63  __einfo_error ( EINFO_EACCES_NO_RECIPIENTS )
64 #define EINFO_EACCES_NO_RECIPIENTS \
65  __einfo_uniqify ( EINFO_EACCES, 0x06, "No usable recipients" )
66 #define EACCES_LEN \
67  __einfo_error ( EINFO_EACCES_LEN )
68 #define EINFO_EACCES_LEN \
69  __einfo_uniqify ( EINFO_EACCES, 0x07, "Bad file length" )
70 #define EACCES_PAD \
71  __einfo_error ( EINFO_EACCES_PAD )
72 #define EINFO_EACCES_PAD \
73  __einfo_uniqify ( EINFO_EACCES, 0x08, "Bad block padding" )
74 #define EACCES_MAC \
75  __einfo_error ( EINFO_EACCES_MAC )
76 #define EINFO_EACCES_MAC \
77  __einfo_uniqify ( EINFO_EACCES, 0x09, "Invalid MAC" )
78 #define ENOTSUP_TYPE \
79  __einfo_error ( EINFO_ENOTSUP_TYPE )
80 #define EINFO_ENOTSUP_TYPE \
81  __einfo_uniqify ( EINFO_ENOTSUP, 0x01, "Unrecognised message type" )
82 
83 static int cms_parse_signed ( struct cms_message *cms,
84  const struct asn1_cursor *raw );
85 static int cms_parse_enveloped ( struct cms_message *cms,
86  const struct asn1_cursor *raw );
87 
88 /** "id-signedData" object identifier */
90 
91 /** "id-envelopedData" object identifier */
93 
94 /** "id-authEnvelopedData" object identifier */
96 
97 /** CMS message types */
98 static struct cms_type cms_types[] = {
99  {
100  .name = "signed",
101  .oid = ASN1_CURSOR ( oid_signeddata ),
102  .parse = cms_parse_signed,
103  },
104  {
105  .name = "enveloped",
106  .oid = ASN1_CURSOR ( oid_envelopeddata ),
107  .parse = cms_parse_enveloped,
108  },
109  {
110  .name = "authEnveloped",
112  .parse = cms_parse_enveloped,
113  }
114 };
115 
116 /**
117  * Parse CMS message content type
118  *
119  * @v cms CMS message
120  * @v raw ASN.1 cursor
121  * @ret rc Return status code
122  */
123 static int cms_parse_content_type ( struct cms_message *cms,
124  const struct asn1_cursor *raw ) {
125  struct asn1_cursor cursor;
126  struct cms_type *type;
127  unsigned int i;
128 
129  /* Enter contentType */
130  memcpy ( &cursor, raw, sizeof ( cursor ) );
131  asn1_enter ( &cursor, ASN1_OID );
132 
133  /* Check for a recognised OID */
134  for ( i = 0 ; i < ( sizeof ( cms_types ) /
135  sizeof ( cms_types[0] ) ) ; i++ ) {
136  type = &cms_types[i];
137  if ( asn1_compare ( &cursor, &type->oid ) == 0 ) {
138  cms->type = type;
139  DBGC ( cms, "CMS %p contains %sData\n",
140  cms, type->name );
141  return 0;
142  }
143  }
144 
145  DBGC ( cms, "CMS %p is not a recognised message type:\n", cms );
146  DBGC_HDA ( cms, 0, raw->data, raw->len );
147  return -ENOTSUP_TYPE;
148 }
149 
150 /**
151  * Parse CMS message certificate list
152  *
153  * @v cms CMS message
154  * @v raw ASN.1 cursor
155  * @ret rc Return status code
156  */
157 static int cms_parse_certificates ( struct cms_message *cms,
158  const struct asn1_cursor *raw ) {
159  struct asn1_cursor cursor;
160  struct x509_certificate *cert;
161  int rc;
162 
163  /* Enter certificates */
164  memcpy ( &cursor, raw, sizeof ( cursor ) );
165  asn1_enter ( &cursor, ASN1_EXPLICIT_TAG ( 0 ) );
166 
167  /* Add each certificate */
168  while ( cursor.len ) {
169 
170  /* Add certificate to chain */
171  if ( ( rc = x509_append_raw ( cms->certificates, cursor.data,
172  cursor.len ) ) != 0 ) {
173  DBGC ( cms, "CMS %p could not append certificate: %s\n",
174  cms, strerror ( rc) );
175  DBGC_HDA ( cms, 0, cursor.data, cursor.len );
176  return rc;
177  }
178  cert = x509_last ( cms->certificates );
179  DBGC ( cms, "CMS %p found certificate %s\n",
180  cms, x509_name ( cert ) );
181 
182  /* Move to next certificate */
183  asn1_skip_any ( &cursor );
184  }
185 
186  return 0;
187 }
188 
189 /**
190  * Parse CMS message participant identifier
191  *
192  * @v cms CMS message
193  * @v part Participant information to fill in
194  * @v raw ASN.1 cursor
195  * @ret rc Return status code
196  */
197 static int cms_parse_identifier ( struct cms_message *cms,
198  struct cms_participant *part,
199  const struct asn1_cursor *raw ) {
200  struct asn1_cursor cursor;
201  struct asn1_cursor serial;
202  struct asn1_cursor issuer;
203  struct x509_certificate *cert;
204  int rc;
205 
206  /* Enter issuerAndSerialNumber */
207  memcpy ( &cursor, raw, sizeof ( cursor ) );
208  asn1_enter ( &cursor, ASN1_SEQUENCE );
209 
210  /* Identify issuer */
211  memcpy ( &issuer, &cursor, sizeof ( issuer ) );
212  if ( ( rc = asn1_shrink ( &issuer, ASN1_SEQUENCE ) ) != 0 ) {
213  DBGC ( cms, "CMS %p/%p could not locate issuer: %s\n",
214  cms, part, strerror ( rc ) );
215  DBGC_HDA ( cms, 0, raw->data, raw->len );
216  return rc;
217  }
218  DBGC ( cms, "CMS %p/%p issuer is:\n", cms, part );
219  DBGC_HDA ( cms, 0, issuer.data, issuer.len );
220  asn1_skip_any ( &cursor );
221 
222  /* Identify serialNumber */
223  memcpy ( &serial, &cursor, sizeof ( serial ) );
224  if ( ( rc = asn1_shrink ( &serial, ASN1_INTEGER ) ) != 0 ) {
225  DBGC ( cms, "CMS %p/%p could not locate serialNumber: %s\n",
226  cms, part, strerror ( rc ) );
227  DBGC_HDA ( cms, 0, raw->data, raw->len );
228  return rc;
229  }
230  DBGC ( cms, "CMS %p/%p serial number is:\n", cms, part );
231  DBGC_HDA ( cms, 0, serial.data, serial.len );
232 
233  /* Identify certificate */
235  if ( ! cert ) {
236  DBGC ( cms, "CMS %p/%p could not identify certificate\n",
237  cms, part );
238  return ( cms_is_signature ( cms ) ? -ENOENT : 0 );
239  }
240 
241  /* Append certificate to chain */
242  if ( ( rc = x509_append ( part->chain, cert ) ) != 0 ) {
243  DBGC ( cms, "CMS %p/%p could not append certificate: %s\n",
244  cms, part, strerror ( rc ) );
245  return rc;
246  }
247 
248  /* Append remaining certificates to chain */
249  if ( ( rc = x509_auto_append ( part->chain,
250  cms->certificates ) ) != 0 ) {
251  DBGC ( cms, "CMS %p/%p could not append certificates: %s\n",
252  cms, part, strerror ( rc ) );
253  return rc;
254  }
255 
256  return 0;
257 }
258 
259 /**
260  * Parse CMS message digest algorithm
261  *
262  * @v cms CMS message
263  * @v part Participant information to fill in
264  * @v raw ASN.1 cursor
265  * @ret rc Return status code
266  */
267 static int cms_parse_digest_algorithm ( struct cms_message *cms,
268  struct cms_participant *part,
269  const struct asn1_cursor *raw ) {
270  struct asn1_algorithm *algorithm;
271  int rc;
272 
273  /* Identify algorithm */
274  if ( ( rc = asn1_digest_algorithm ( raw, &algorithm ) ) != 0 ) {
275  DBGC ( cms, "CMS %p/%p could not identify digest algorithm: "
276  "%s\n", cms, part, strerror ( rc ) );
277  DBGC_HDA ( cms, 0, raw->data, raw->len );
278  return rc;
279  }
280 
281  /* Record digest algorithm */
282  part->digest = algorithm->digest;
283  DBGC ( cms, "CMS %p/%p digest algorithm is %s\n",
284  cms, part, algorithm->name );
285 
286  return 0;
287 }
288 
289 /**
290  * Parse CMS message public-key algorithm
291  *
292  * @v cms CMS message
293  * @v part Participant information to fill in
294  * @v raw ASN.1 cursor
295  * @ret rc Return status code
296  */
297 static int cms_parse_pubkey_algorithm ( struct cms_message *cms,
298  struct cms_participant *part,
299  const struct asn1_cursor *raw ) {
300  struct asn1_algorithm *algorithm;
301  int rc;
302 
303  /* Identify algorithm */
304  if ( ( rc = asn1_pubkey_algorithm ( raw, &algorithm ) ) != 0 ) {
305  DBGC ( cms, "CMS %p/%p could not identify public-key "
306  "algorithm: %s\n", cms, part, strerror ( rc ) );
307  DBGC_HDA ( cms, 0, raw->data, raw->len );
308  return rc;
309  }
310 
311  /* Record public-key algorithm */
312  part->pubkey = algorithm->pubkey;
313  DBGC ( cms, "CMS %p/%p public-key algorithm is %s\n",
314  cms, part, algorithm->name );
315 
316  return 0;
317 }
318 
319 /**
320  * Parse CMS message cipher algorithm
321  *
322  * @v cms CMS message
323  * @v raw ASN.1 cursor
324  * @ret rc Return status code
325  */
326 static int cms_parse_cipher_algorithm ( struct cms_message *cms,
327  const struct asn1_cursor *raw ) {
328  struct asn1_algorithm *algorithm;
329  int rc;
330 
331  /* Identify algorithm */
332  if ( ( rc = asn1_cipher_algorithm ( raw, &algorithm,
333  &cms->iv ) ) != 0 ) {
334  DBGC ( cms, "CMS %p could not identify cipher algorithm: %s\n",
335  cms, strerror ( rc ) );
336  DBGC_HDA ( cms, 0, raw->data, raw->len );
337  return rc;
338  }
339 
340  /* Record cipher */
341  cms->cipher = algorithm->cipher;
342  DBGC ( cms, "CMS %p cipher algorithm is %s\n", cms, algorithm->name );
343 
344  return 0;
345 }
346 
347 /**
348  * Parse CMS message signature or key value
349  *
350  * @v cms CMS message
351  * @v part Participant information to fill in
352  * @v raw ASN.1 cursor
353  * @ret rc Return status code
354  */
355 static int cms_parse_value ( struct cms_message *cms,
356  struct cms_participant *part,
357  const struct asn1_cursor *raw ) {
358  int rc;
359 
360  /* Enter signature or encryptedKey */
361  memcpy ( &part->value, raw, sizeof ( part->value ) );
362  if ( ( rc = asn1_enter ( &part->value, ASN1_OCTET_STRING ) ) != 0 ) {
363  DBGC ( cms, "CMS %p/%p could not locate value:\n",
364  cms, part );
365  DBGC_HDA ( cms, 0, raw->data, raw->len );
366  return rc;
367  }
368  DBGC ( cms, "CMS %p/%p value is:\n", cms, part );
369  DBGC_HDA ( cms, 0, part->value.data, part->value.len );
370 
371  return 0;
372 }
373 
374 /**
375  * Parse CMS message participant information
376  *
377  * @v cms CMS message
378  * @v part Participant information to fill in
379  * @v raw ASN.1 cursor
380  * @ret rc Return status code
381  */
382 static int cms_parse_participant ( struct cms_message *cms,
383  struct cms_participant *part,
384  const struct asn1_cursor *raw ) {
385  struct asn1_cursor cursor;
386  int rc;
387 
388  /* Enter signerInfo or ktri */
389  memcpy ( &cursor, raw, sizeof ( cursor ) );
390  asn1_enter ( &cursor, ASN1_SEQUENCE );
391 
392  /* Skip version */
393  asn1_skip ( &cursor, ASN1_INTEGER );
394 
395  /* Parse sid or rid */
396  if ( ( rc = cms_parse_identifier ( cms, part, &cursor ) ) != 0 )
397  return rc;
398  asn1_skip_any ( &cursor );
399 
400  /* Parse signature-only objects */
401  if ( cms_is_signature ( cms ) ) {
402 
403  /* Parse digestAlgorithm */
404  if ( ( rc = cms_parse_digest_algorithm ( cms, part,
405  &cursor ) ) != 0 )
406  return rc;
407  asn1_skip_any ( &cursor );
408 
409  /* Skip signedAttrs, if present */
410  asn1_skip_if_exists ( &cursor, ASN1_EXPLICIT_TAG ( 0 ) );
411  }
412 
413  /* Parse signatureAlgorithm or contentEncryptionAlgorithm */
414  if ( ( rc = cms_parse_pubkey_algorithm ( cms, part, &cursor ) ) != 0 )
415  return rc;
416  asn1_skip_any ( &cursor );
417 
418  /* Parse signature or encryptedKey */
419  if ( ( rc = cms_parse_value ( cms, part, &cursor ) ) != 0 )
420  return rc;
421 
422  return 0;
423 }
424 
425 /**
426  * Parse CMS message participants information
427  *
428  * @v cms CMS message
429  * @v raw ASN.1 cursor
430  * @ret rc Return status code
431  */
432 static int cms_parse_participants ( struct cms_message *cms,
433  const struct asn1_cursor *raw ) {
434  struct asn1_cursor cursor;
435  struct cms_participant *part;
436  int rc;
437 
438  /* Enter signerInfos or recipientInfos */
439  memcpy ( &cursor, raw, sizeof ( cursor ) );
440  asn1_enter ( &cursor, ASN1_SET );
441 
442  /* Add each signerInfo or recipientInfo. Errors are handled
443  * by ensuring that cms_put() will always be able to free any
444  * allocated memory.
445  */
446  while ( cursor.len ) {
447 
448  /* Allocate participant information block */
449  part = zalloc ( sizeof ( *part ) );
450  if ( ! part )
451  return -ENOMEM;
452  list_add ( &part->list, &cms->participants );
453  part->digest = &digest_null;
454  part->pubkey = &pubkey_null;
455 
456  /* Allocate certificate chain */
457  part->chain = x509_alloc_chain();
458  if ( ! part->chain )
459  return -ENOMEM;
460 
461  /* Parse signerInfo or recipientInfo */
462  if ( ( rc = cms_parse_participant ( cms, part,
463  &cursor ) ) != 0 )
464  return rc;
465  asn1_skip_any ( &cursor );
466  }
467 
468  return 0;
469 }
470 
471 /**
472  * Parse CMS message encrypted content information
473  *
474  * @v cms CMS message
475  * @v raw ASN.1 cursor
476  * @ret rc Return status code
477  */
478 static int cms_parse_encrypted ( struct cms_message *cms,
479  const struct asn1_cursor *raw ) {
480  struct asn1_cursor cursor;
481  int rc;
482 
483  /* Enter encryptedContentInfo */
484  memcpy ( &cursor, raw, sizeof ( cursor ) );
485  asn1_enter ( &cursor, ASN1_SEQUENCE );
486 
487  /* Skip contentType */
488  asn1_skip ( &cursor, ASN1_OID );
489 
490  /* Parse contentEncryptionAlgorithm */
491  if ( ( rc = cms_parse_cipher_algorithm ( cms, &cursor ) ) != 0 )
492  return rc;
493 
494  return 0;
495 }
496 
497 /**
498  * Parse CMS message MAC
499  *
500  * @v cms CMS message
501  * @v raw ASN.1 cursor
502  * @ret rc Return status code
503  */
504 static int cms_parse_mac ( struct cms_message *cms,
505  const struct asn1_cursor *raw ) {
506  int rc;
507 
508  /* Enter mac */
509  memcpy ( &cms->mac, raw, sizeof ( cms->mac ) );
510  if ( ( rc = asn1_enter ( &cms->mac, ASN1_OCTET_STRING ) ) != 0 ) {
511  DBGC ( cms, "CMS %p could not locate mac: %s\n",
512  cms, strerror ( rc ) );
513  DBGC_HDA ( cms, 0, raw->data, raw->len );
514  return rc;
515  }
516  DBGC ( cms, "CMS %p mac is:\n", cms );
517  DBGC_HDA ( cms, 0, cms->mac.data, cms->mac.len );
518 
519  return 0;
520 }
521 
522 /**
523  * Parse CMS signed data
524  *
525  * @v cms CMS message
526  * @v raw ASN.1 cursor
527  * @ret rc Return status code
528  */
529 static int cms_parse_signed ( struct cms_message *cms,
530  const struct asn1_cursor *raw ) {
531  struct asn1_cursor cursor;
532  int rc;
533 
534  /* Allocate certificate list */
536  if ( ! cms->certificates )
537  return -ENOMEM;
538 
539  /* Enter signedData */
540  memcpy ( &cursor, raw, sizeof ( cursor ) );
541  asn1_enter ( &cursor, ASN1_SEQUENCE );
542 
543  /* Skip version */
544  asn1_skip ( &cursor, ASN1_INTEGER );
545 
546  /* Skip digestAlgorithms */
547  asn1_skip ( &cursor, ASN1_SET );
548 
549  /* Skip encapContentInfo */
550  asn1_skip ( &cursor, ASN1_SEQUENCE );
551 
552  /* Parse certificates */
553  if ( ( rc = cms_parse_certificates ( cms, &cursor ) ) != 0 )
554  return rc;
555  asn1_skip_any ( &cursor );
556 
557  /* Skip crls, if present */
558  asn1_skip_if_exists ( &cursor, ASN1_EXPLICIT_TAG ( 1 ) );
559 
560  /* Parse signerInfos */
561  if ( ( rc = cms_parse_participants ( cms, &cursor ) ) != 0 )
562  return rc;
563 
564  return 0;
565 }
566 
567 /**
568  * Parse CMS enveloped data
569  *
570  * @v cms CMS message
571  * @v raw ASN.1 cursor
572  * @ret rc Return status code
573  */
574 static int cms_parse_enveloped ( struct cms_message *cms,
575  const struct asn1_cursor *raw ) {
576  struct asn1_cursor cursor;
577  int rc;
578 
579  /* Enter envelopedData or authEnvelopedData */
580  memcpy ( &cursor, raw, sizeof ( cursor ) );
581  asn1_enter ( &cursor, ASN1_SEQUENCE );
582 
583  /* Skip version */
584  asn1_skip ( &cursor, ASN1_INTEGER );
585 
586  /* Skip originatorInfo, if present */
587  asn1_skip_if_exists ( &cursor, ASN1_IMPLICIT_TAG ( 0 ) );
588 
589  /* Parse recipientInfos */
590  if ( ( rc = cms_parse_participants ( cms, &cursor ) ) != 0 )
591  return rc;
592  asn1_skip_any ( &cursor );
593 
594  /* Parse encryptedContentInfo or authEncryptedContentInfo */
595  if ( ( rc = cms_parse_encrypted ( cms, &cursor ) ) != 0 )
596  return rc;
597  asn1_skip_any ( &cursor );
598  assert ( cms->cipher != NULL );
599 
600  /* Skip unprotectedAttrs or authAttrs, if present */
601  asn1_skip_if_exists ( &cursor, ASN1_IMPLICIT_TAG ( 1 ) );
602 
603  /* Parse mac, if present */
604  if ( ( cms->cipher->authsize != 0 ) &&
605  ( ( rc = cms_parse_mac ( cms, &cursor ) ) != 0 ) )
606  return rc;
607 
608  return 0;
609 }
610 
611 /**
612  * Parse CMS message from ASN.1 data
613  *
614  * @v cms CMS message
615  * @ret rc Return status code
616  */
617 static int cms_parse ( struct cms_message *cms ) {
618  struct asn1_cursor cursor;
619  int rc;
620 
621  /* Enter contentInfo */
622  memcpy ( &cursor, cms->raw, sizeof ( cursor ) );
623  asn1_enter ( &cursor, ASN1_SEQUENCE );
624 
625  /* Parse contentType */
626  if ( ( rc = cms_parse_content_type ( cms, &cursor ) ) != 0 )
627  return rc;
628  asn1_skip_any ( &cursor );
629 
630  /* Enter content */
631  asn1_enter ( &cursor, ASN1_EXPLICIT_TAG ( 0 ) );
632 
633  /* Parse type-specific content */
634  if ( ( rc = cms->type->parse ( cms, &cursor ) ) != 0 )
635  return rc;
636 
637  return 0;
638 }
639 
640 /**
641  * Free CMS message
642  *
643  * @v refcnt Reference count
644  */
645 static void cms_free ( struct refcnt *refcnt ) {
646  struct cms_message *cms =
647  container_of ( refcnt, struct cms_message, refcnt );
648  struct cms_participant *part;
649  struct cms_participant *tmp;
650 
651  list_for_each_entry_safe ( part, tmp, &cms->participants, list ) {
652  list_del ( &part->list );
653  x509_chain_put ( part->chain );
654  free ( part );
655  }
656  x509_chain_put ( cms->certificates );
657  free ( cms->raw );
658  free ( cms );
659 }
660 
661 /**
662  * Create CMS message
663  *
664  * @v image Image
665  * @ret sig CMS message
666  * @ret rc Return status code
667  *
668  * On success, the caller holds a reference to the CMS message, and
669  * is responsible for ultimately calling cms_put().
670  */
671 int cms_message ( struct image *image, struct cms_message **cms ) {
672  int next;
673  int rc;
674 
675  /* Allocate and initialise message */
676  *cms = zalloc ( sizeof ( **cms ) );
677  if ( ! *cms ) {
678  rc = -ENOMEM;
679  goto err_alloc;
680  }
681  ref_init ( &(*cms)->refcnt, cms_free );
682  INIT_LIST_HEAD ( &(*cms)->participants );
683  (*cms)->cipher = &cipher_null;
684 
685  /* Get raw message data */
686  next = image_asn1 ( image, 0, &(*cms)->raw );
687  if ( next < 0 ) {
688  rc = next;
689  DBGC ( *cms, "CMS %p could not get raw ASN.1 data: %s\n",
690  *cms, strerror ( rc ) );
691  goto err_asn1;
692  }
693 
694  /* Use only first message in image */
695  asn1_shrink_any ( (*cms)->raw );
696 
697  /* Parse message */
698  if ( ( rc = cms_parse ( *cms ) ) != 0 )
699  goto err_parse;
700 
701  return 0;
702 
703  err_parse:
704  err_asn1:
705  cms_put ( *cms );
706  err_alloc:
707  return rc;
708 }
709 
710 /**
711  * Calculate digest of CMS-signed data
712  *
713  * @v cms CMS message
714  * @v part Participant information
715  * @v data Signed data
716  * @v len Length of signed data
717  * @v out Digest output
718  */
719 static void cms_digest ( struct cms_message *cms,
720  struct cms_participant *part,
721  const void *data, size_t len, void *out ) {
722  struct digest_algorithm *digest = part->digest;
723  uint8_t ctx[ digest->ctxsize ];
724 
725  /* Calculate digest */
726  digest_init ( digest, ctx );
727  digest_update ( digest, ctx, data, len );
728  digest_final ( digest, ctx, out );
729 
730  DBGC ( cms, "CMS %p/%p digest value:\n", cms, part );
731  DBGC_HDA ( cms, 0, out, digest->digestsize );
732 }
733 
734 /**
735  * Verify digest of CMS-signed data
736  *
737  * @v cms CMS message
738  * @v part Participant information
739  * @v cert Corresponding certificate
740  * @v data Signed data
741  * @v len Length of signed data
742  * @ret rc Return status code
743  */
744 static int cms_verify_digest ( struct cms_message *cms,
745  struct cms_participant *part,
746  struct x509_certificate *cert,
747  const void *data, size_t len ) {
748  struct digest_algorithm *digest = part->digest;
749  struct pubkey_algorithm *pubkey = part->pubkey;
750  const struct asn1_cursor *key = &cert->subject.public_key.raw;
751  const struct asn1_cursor *value = &part->value;
752  uint8_t digest_out[ digest->digestsize ];
753  int rc;
754 
755  /* Generate digest */
756  cms_digest ( cms, part, data, len, digest_out );
757 
758  /* Verify digest */
759  if ( ( rc = pubkey_verify ( pubkey, key, digest, digest_out,
760  value ) ) != 0 ) {
761  DBGC ( cms, "CMS %p/%p signature verification failed: %s\n",
762  cms, part, strerror ( rc ) );
763  return rc;
764  }
765 
766  return 0;
767 }
768 
769 /**
770  * Verify CMS message signer
771  *
772  * @v cms CMS message
773  * @v part Participant information
774  * @v data Signed data
775  * @v len Length of signed data
776  * @v time Time at which to validate certificates
777  * @v store Certificate store, or NULL to use default
778  * @v root Root certificate list, or NULL to use default
779  * @ret rc Return status code
780  */
781 static int cms_verify_signer ( struct cms_message *cms,
782  struct cms_participant *part,
783  const void *data, size_t len,
784  time_t time, struct x509_chain *store,
785  struct x509_root *root ) {
786  struct x509_certificate *cert;
787  int rc;
788 
789  /* Validate certificate chain */
790  if ( ( rc = x509_validate_chain ( part->chain, time, store,
791  root ) ) != 0 ) {
792  DBGC ( cms, "CMS %p/%p could not validate chain: %s\n",
793  cms, part, strerror ( rc ) );
794  return rc;
795  }
796 
797  /* Extract code-signing certificate */
798  cert = x509_first ( part->chain );
799  assert ( cert != NULL );
800 
801  /* Check that certificate can create digital signatures */
802  if ( ! ( cert->extensions.usage.bits & X509_DIGITAL_SIGNATURE ) ) {
803  DBGC ( cms, "CMS %p/%p certificate cannot create signatures\n",
804  cms, part );
805  return -EACCES_NON_SIGNING;
806  }
807 
808  /* Check that certificate can sign code */
809  if ( ! ( cert->extensions.ext_usage.bits & X509_CODE_SIGNING ) ) {
810  DBGC ( cms, "CMS %p/%p certificate is not code-signing\n",
811  cms, part );
812  return -EACCES_NON_CODE_SIGNING;
813  }
814 
815  /* Verify digest */
816  if ( ( rc = cms_verify_digest ( cms, part, cert, data, len ) ) != 0 )
817  return rc;
818 
819  return 0;
820 }
821 
822 /**
823  * Verify CMS signature
824  *
825  * @v cms CMS message
826  * @v image Signed image
827  * @v name Required common name, or NULL to check all signatures
828  * @v time Time at which to validate certificates
829  * @v store Certificate store, or NULL to use default
830  * @v root Root certificate list, or NULL to use default
831  * @ret rc Return status code
832  */
833 int cms_verify ( struct cms_message *cms, struct image *image,
834  const char *name, time_t time, struct x509_chain *store,
835  struct x509_root *root ) {
836  struct cms_participant *part;
837  struct x509_certificate *cert;
838  int count = 0;
839  int rc;
840 
841  /* Mark image as untrusted */
842  image_untrust ( image );
843 
844  /* Sanity check */
845  if ( ! cms_is_signature ( cms ) )
846  return -ENOTTY;
847 
848  /* Verify using all signers */
849  list_for_each_entry ( part, &cms->participants, list ) {
850  cert = x509_first ( part->chain );
851  if ( name && ( x509_check_name ( cert, name ) != 0 ) )
852  continue;
853  if ( ( rc = cms_verify_signer ( cms, part, image->data,
854  image->len, time, store,
855  root ) ) != 0 )
856  return rc;
857  count++;
858  }
859 
860  /* Check that we have verified at least one signature */
861  if ( count == 0 ) {
862  if ( name ) {
863  DBGC ( cms, "CMS %p had no signatures matching name "
864  "%s\n", cms, name );
865  return -EACCES_WRONG_NAME;
866  } else {
867  DBGC ( cms, "CMS %p had no signatures\n", cms );
868  return -EACCES_NO_SIGNATURES;
869  }
870  }
871 
872  /* Mark image as trusted */
873  image_trust ( image );
874 
875  return 0;
876 }
877 
878 /**
879  * Identify CMS recipient corresponding to private key
880  *
881  * @v cms CMS message
882  * @v private_key Private key
883  * @ret part Participant information, or NULL if not found
884  */
885 static struct cms_participant *
887  struct cms_participant *part;
888  struct x509_certificate *cert;
889 
890  /* Identify certificate (if any) for which we have a private key */
891  cert = x509_find_key ( NULL, private_key );
892  if ( ! cert )
893  return NULL;
894 
895  /* Identify corresponding recipient, if any */
896  list_for_each_entry ( part, &cms->participants, list ) {
897  if ( cert == x509_first ( part->chain ) )
898  return part;
899  }
900 
901  return NULL;
902 }
903 
904 /**
905  * Set CMS cipher key
906  *
907  * @v cms CMS message
908  * @v part Participant information
909  * @v private_key Private key
910  * @v ctx Cipher context
911  * @ret rc Return status code
912  */
913 static int cms_cipher_key ( struct cms_message *cms,
914  struct cms_participant *part,
915  struct private_key *private_key, void *ctx ) {
916  struct cipher_algorithm *cipher = cms->cipher;
917  struct pubkey_algorithm *pubkey = part->pubkey;
918  const struct asn1_cursor *key = privkey_cursor ( private_key );
919  const struct asn1_cursor *value = &part->value;
920  struct asn1_builder cipher_key = { NULL, 0 };
921  int rc;
922 
923  /* Decrypt cipher key */
924  if ( ( rc = pubkey_decrypt ( pubkey, key, value,
925  &cipher_key ) ) != 0 ) {
926  DBGC ( cms, "CMS %p/%p could not decrypt cipher key: %s\n",
927  cms, part, strerror ( rc ) );
928  DBGC_HDA ( cms, 0, value->data, value->len );
929  goto err_decrypt;
930  }
931  DBGC ( cms, "CMS %p/%p cipher key:\n", cms, part );
932  DBGC_HDA ( cms, 0, cipher_key.data, cipher_key.len );
933 
934  /* Set cipher key */
935  if ( ( rc = cipher_setkey ( cipher, ctx, cipher_key.data,
936  cipher_key.len ) ) != 0 ) {
937  DBGC ( cms, "CMS %p could not set cipher key: %s\n",
938  cms, strerror ( rc ) );
939  goto err_setkey;
940  }
941 
942  /* Set cipher initialization vector */
943  cipher_setiv ( cipher, ctx, cms->iv.data, cms->iv.len );
944  if ( cms->iv.len ) {
945  DBGC ( cms, "CMS %p cipher IV:\n", cms );
946  DBGC_HDA ( cms, 0, cms->iv.data, cms->iv.len );
947  }
948 
949  err_setkey:
950  err_decrypt:
951  free ( cipher_key.data );
952  return rc;
953 }
954 
955 /**
956  * Initialise cipher for CMS decryption
957  *
958  * @v cms CMS message
959  * @v private_key Private key
960  * @v ctx Cipher context
961  * @ret rc Return status code
962  */
963 static int cms_cipher ( struct cms_message *cms,
964  struct private_key *private_key, void *ctx ) {
965  struct cms_participant *part;
966  int rc;
967 
968  /* Identify a usable recipient */
969  part = cms_recipient ( cms, private_key );
970  if ( ! part ) {
971  DBGC ( cms, "CMS %p had no usable recipients\n", cms );
972  return -EACCES_NO_RECIPIENTS;
973  }
974 
975  /* Decrypt and set cipher key */
976  if ( ( rc = cms_cipher_key ( cms, part, private_key, ctx ) ) != 0 )
977  return rc;
978 
979  return 0;
980 }
981 
982 /**
983  * Check CMS padding
984  *
985  * @v cms CMS message
986  * @v data Final block
987  * @v len Final block length
988  * @ret len Padding length, or negative error
989  */
990 static int cms_verify_padding ( struct cms_message *cms, const void *data,
991  size_t len ) {
992  struct cipher_algorithm *cipher = cms->cipher;
993  const uint8_t *pad;
994  size_t pad_len;
995  unsigned int i;
996 
997  /* Non-block ciphers do not use padding */
998  if ( ! is_block_cipher ( cipher ) )
999  return 0;
1000 
1001  /* Block padding can never produce an empty file */
1002  if ( len == 0 ) {
1003  DBGC ( cms, "CMS %p invalid empty padding\n", cms );
1004  return -EACCES_PAD;
1005  }
1006 
1007  /* Sanity check */
1008  assert ( len >= cipher->blocksize );
1009 
1010  /* Extract and verify padding */
1011  pad = ( data + len - 1 );
1012  pad_len = *pad;
1013  if ( ( pad_len == 0 ) || ( pad_len > len ) ) {
1014  DBGC ( cms, "CMS %p invalid padding length %zd\n",
1015  cms, pad_len );
1016  return -EACCES_PAD;
1017  }
1018  for ( i = 0 ; i < pad_len ; i++ ) {
1019  if ( *(pad--) != pad_len ) {
1020  DBGC ( cms, "CMS %p invalid padding\n", cms );
1021  DBGC_HDA ( cms, 0, ( data + len - pad_len ), pad_len );
1022  return -EACCES_PAD;
1023  }
1024  }
1025 
1026  return pad_len;
1027 }
1028 
1029 /**
1030  * Decrypt CMS message
1031  *
1032  * @v cms CMS message
1033  * @v image Image to decrypt
1034  * @v name Decrypted image name, or NULL to use default
1035  * @v private_key Private key
1036  * @ret rc Return status code
1037  */
1038 int cms_decrypt ( struct cms_message *cms, struct image *image,
1039  const char *name, struct private_key *private_key ) {
1040  struct cipher_algorithm *cipher = cms->cipher;
1041  const unsigned int original_flags = image->flags;
1042  uint8_t ctx[ cipher->ctxsize ];
1043  uint8_t ctxdup[ cipher->ctxsize ];
1044  uint8_t auth[ cipher->authsize ];
1045  uint8_t final[ cipher->blocksize ];
1046  size_t final_len;
1047  size_t bulk_len;
1048  int pad_len;
1049  int rc;
1050 
1051  /* Check block size */
1052  if ( ( image->len & ( cipher->blocksize - 1 ) ) != 0 ) {
1053  DBGC ( cms, "CMS %p invalid length %zd\n", cms, image->len );
1054  rc = -EACCES_LEN;
1055  goto err_blocksize;
1056  }
1057 
1058  /* Initialise cipher */
1059  if ( ( rc = cms_cipher ( cms, private_key, ctx ) ) != 0 )
1060  goto err_cipher;
1061 
1062  /* Duplicate cipher context for potential reencryption on error */
1063  memcpy ( ctxdup, ctx, cipher->ctxsize );
1064 
1065  /* Clear trusted flag before modifying image */
1066  image_untrust ( image );
1067 
1068  /* Temporarily unregister image, if applicable */
1069  if ( original_flags & IMAGE_REGISTERED ) {
1070  image_get ( image );
1071  unregister_image ( image );
1072  }
1073 
1074  /* Decrypt all but the final block */
1075  final_len = ( ( image->len && is_block_cipher ( cipher ) ) ?
1076  cipher->blocksize : 0 );
1077  bulk_len = ( image->len - final_len );
1078  cipher_decrypt ( cipher, ctx, image->data, image->rwdata, bulk_len );
1079 
1080  /* Decrypt final block */
1081  cipher_decrypt ( cipher, ctx, ( image->data + bulk_len ), final,
1082  final_len );
1083 
1084  /* Check authentication tag, if applicable */
1085  cipher_auth ( cipher, ctx, auth );
1086  if ( ( cms->mac.len != cipher->authsize ) ||
1087  ( memcmp ( cms->mac.data, auth, cipher->authsize ) != 0 ) ) {
1088  DBGC ( cms, "CMS %p invalid authentication tag\n", cms );
1089  DBGC_HDA ( cms, 0, auth, cipher->authsize );
1090  rc = -EACCES_MAC;
1091  goto err_auth;
1092  }
1093 
1094  /* Check block padding, if applicable */
1095  if ( ( pad_len = cms_verify_padding ( cms, final, final_len ) ) < 0 ) {
1096  rc = pad_len;
1097  goto err_pad;
1098  }
1099 
1100  /* Update image name. Do this as the last possible failure, so
1101  * that we do not have to include any error-handling code path
1102  * to restore the original image name (which may itself fail).
1103  */
1104  if ( name ) {
1105  if ( ( rc = image_set_name ( image, name ) ) != 0 )
1106  goto err_set_name;
1107  } else {
1109  }
1110 
1111  /* Overwrite final fragment and strip block padding. Do this
1112  * only once no further failure paths exist, so that we do not
1113  * have to include include any error-handling code path to
1114  * reconstruct the block padding.
1115  */
1116  memcpy ( ( image->rwdata + bulk_len ), final, final_len );
1117  image->len -= pad_len;
1118 
1119  /* Clear image type and re-register image, if applicable */
1120  image->type = NULL;
1121  if ( original_flags & IMAGE_REGISTERED ) {
1122  register_image ( image );
1123  image_put ( image );
1124  }
1125 
1126  return 0;
1127 
1128  err_set_name:
1129  err_pad:
1130  err_auth:
1131  /* Reencrypt all overwritten portions. This can be done since
1132  * we have deliberately not overwritten the final block
1133  * containing the potentially invalid (and therefore
1134  * unreproducible) block padding.
1135  */
1136  cipher_encrypt ( cipher, ctxdup, image->data, image->rwdata, bulk_len );
1137  if ( original_flags & IMAGE_REGISTERED ) {
1138  register_image ( image ); /* Cannot fail on re-registration */
1139  image_put ( image );
1140  }
1141  image->flags = original_flags;
1142  err_cipher:
1143  err_blocksize:
1144  return rc;
1145 }
static void x509_chain_put(struct x509_chain *chain)
Drop reference to X.509 certificate chain.
Definition: x509.h:299
unsigned int flags
Flags.
Definition: image.h:39
const char * name
Name.
Definition: cms.h:24
struct x509_chain * certificates
List of all certificates (for signature messages)
Definition: cms.h:63
size_t blocksize
Block size.
Definition: crypto.h:60
An ASN.1 OID-identified algorithm.
Definition: asn1.h:383
struct asn1_cursor raw
Raw public key information.
Definition: x509.h:51
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
static void digest_update(struct digest_algorithm *digest, void *ctx, const void *data, size_t len)
Definition: crypto.h:201
const char * name
Definition: ath9k_hw.c:1984
struct x509_extended_key_usage ext_usage
Extended key usage.
Definition: x509.h:162
#define EACCES_NO_SIGNATURES
Definition: cms.c:58
void * data
Data.
Definition: asn1.h:35
struct asn1_cursor value
Signature or key value.
Definition: cms.h:50
int asn1_compare(const struct asn1_cursor *cursor1, const struct asn1_cursor *cursor2)
Compare two ASN.1 objects.
Definition: asn1.c:447
#define ASN1_IMPLICIT_TAG(number)
ASN.1 implicit tag.
Definition: asn1.h:95
#define EACCES_WRONG_NAME
Definition: cms.c:54
static int cms_parse_participants(struct cms_message *cms, const struct asn1_cursor *raw)
Parse CMS message participants information.
Definition: cms.c:432
int asn1_enter(struct asn1_cursor *cursor, unsigned int type)
Enter ASN.1 object.
Definition: asn1.c:181
struct stp_switch root
Root switch.
Definition: stp.h:26
#define list_add(new, head)
Add a new entry to the head of a list.
Definition: list.h:69
unsigned int bits
Usage bits.
Definition: x509.h:115
static int cms_parse_digest_algorithm(struct cms_message *cms, struct cms_participant *part, const struct asn1_cursor *raw)
Parse CMS message digest algorithm.
Definition: cms.c:267
A CMS message type.
Definition: cms.h:22
#define ref_init(refcnt, free)
Initialise a reference counter.
Definition: refcnt.h:64
Error codes.
const void * data
Read-only data.
Definition: image.h:50
int x509_check_name(struct x509_certificate *cert, const char *name)
Check X.509 certificate name.
Definition: x509.c:1563
static int cms_parse_cipher_algorithm(struct cms_message *cms, const struct asn1_cursor *raw)
Parse CMS message cipher algorithm.
Definition: cms.c:326
static int cms_cipher_key(struct cms_message *cms, struct cms_participant *part, struct private_key *private_key, void *ctx)
Set CMS cipher key.
Definition: cms.c:913
char * image_strip_suffix(struct image *image)
Strip dot suffix from image name, if present.
Definition: image.c:205
int cms_verify(struct cms_message *cms, struct image *image, const char *name, time_t time, struct x509_chain *store, struct x509_root *root)
Verify CMS signature.
Definition: cms.c:833
struct image_type * type
Image type, if known.
Definition: image.h:58
static void digest_final(struct digest_algorithm *digest, void *ctx, void *out)
Definition: crypto.h:207
uint32_t type
Operating system type.
Definition: ena.h:12
struct x509_issuer issuer
Issuer.
Definition: x509.h:240
int x509_append_raw(struct x509_chain *chain, const void *data, size_t len)
Append X.509 certificate to X.509 certificate chain.
Definition: x509.c:1673
static struct image * image_get(struct image *image)
Increment reference count on an image.
Definition: image.h:239
const void * data
Start of data.
Definition: asn1.h:22
#define DBGC(...)
Definition: compiler.h:505
int asn1_digest_algorithm(const struct asn1_cursor *cursor, struct asn1_algorithm **algorithm)
Parse ASN.1 OID-identified digest algorithm.
Definition: asn1.c:559
int x509_append(struct x509_chain *chain, struct x509_certificate *cert)
Append X.509 certificate to X.509 certificate chain.
Definition: x509.c:1637
#define ENOENT
No such file or directory.
Definition: errno.h:514
struct x509_chain * x509_alloc_chain(void)
Allocate X.509 certificate chain.
Definition: x509.c:1614
static int cms_parse_signed(struct cms_message *cms, const struct asn1_cursor *raw)
Parse CMS signed data.
Definition: cms.c:529
struct digest_algorithm * digest
Digest algorithm (for signature messages)
Definition: cms.h:45
struct pubkey_algorithm pubkey_null
Definition: crypto_null.c:122
static int cms_parse_value(struct cms_message *cms, struct cms_participant *part, const struct asn1_cursor *raw)
Parse CMS message signature or key value.
Definition: cms.c:355
int image_asn1(struct image *image, size_t offset, struct asn1_cursor **cursor)
Extract ASN.1 object from image.
Definition: asn1.c:1015
struct pubkey_algorithm * pubkey
Public-key algorithm.
Definition: cms.h:47
An executable image.
Definition: image.h:23
FILE_LICENCE(GPL2_OR_LATER_OR_UBDL)
u32 pad[9]
Padding.
Definition: ar9003_mac.h:90
struct golan_eq_context ctx
Definition: CIB_PRM.h:28
int asn1_skip_any(struct asn1_cursor *cursor)
Skip ASN.1 object of any type.
Definition: asn1.c:302
__be32 out[4]
Definition: CIB_PRM.h:36
#define ASN1_OID_ENVELOPEDDATA
ASN.1 OID for id-envelopedData (1.2.840.113549.1.7.3)
Definition: asn1.h:330
#define ASN1_SET
ASN.1 set.
Definition: asn1.h:92
A CMS message.
Definition: cms.h:54
Dynamic memory allocation.
size_t len
Length of data.
Definition: asn1.h:24
A reference counter.
Definition: refcnt.h:26
static struct asn1_cursor * privkey_cursor(struct private_key *key)
Get private key ASN.1 cursor.
Definition: privkey.h:52
Private key.
unsigned long tmp
Definition: linux_pci.h:64
#define cipher_encrypt(cipher, ctx, src, dst, len)
Definition: crypto.h:228
size_t authsize
Authentication tag size.
Definition: crypto.h:74
#define list_del(list)
Delete an entry from a list.
Definition: list.h:119
An X.509 certificate chain.
Definition: x509.h:200
#define ENOMEM
Not enough space.
Definition: errno.h:534
int asn1_shrink(struct asn1_cursor *cursor, unsigned int type)
Shrink ASN.1 cursor to fit object.
Definition: asn1.c:266
void * memcpy(void *dest, const void *src, size_t len) __nonnull
CMS participant information.
Definition: cms.h:38
static void cms_digest(struct cms_message *cms, struct cms_participant *part, const void *data, size_t len, void *out)
Calculate digest of CMS-signed data.
Definition: cms.c:719
#define ASN1_OID_SIGNEDDATA
ASN.1 OID for id-signedData (1.2.840.113549.1.7.2)
Definition: asn1.h:324
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
#define container_of(ptr, type, field)
Get containing structure.
Definition: stddef.h:35
#define ASN1_CURSOR(value)
Define an ASN.1 cursor for a static value.
Definition: asn1.h:377
#define EACCES_NO_RECIPIENTS
Definition: cms.c:62
Executable images.
ASN.1 encoding.
struct cms_type * type
Message type.
Definition: cms.h:60
#define list_for_each_entry(pos, head, member)
Iterate over entries in a list.
Definition: list.h:431
pseudo_bit_t value[0x00020]
Definition: arbel.h:13
#define DBGC_HDA(...)
Definition: compiler.h:506
ring len
Length.
Definition: dwmac.h:231
#define IMAGE_REGISTERED
Image is registered.
Definition: image.h:76
static unsigned int count
Number of entries.
Definition: dwmac.h:225
#define EACCES_NON_SIGNING
Definition: cms.c:46
int cms_message(struct image *image, struct cms_message **cms)
Create CMS message.
Definition: cms.c:671
static int cms_parse_enveloped(struct cms_message *cms, const struct asn1_cursor *raw)
Parse CMS enveloped data.
Definition: cms.c:574
static struct cms_participant * cms_recipient(struct cms_message *cms, struct private_key *private_key)
Identify CMS recipient corresponding to private key.
Definition: cms.c:886
#define list_for_each_entry_safe(pos, tmp, head, member)
Iterate over entries in a list, safe against deletion of the current entry.
Definition: list.h:458
struct x509_public_key public_key
Public key information.
Definition: x509.h:65
int x509_validate_chain(struct x509_chain *chain, time_t time, struct x509_chain *store, struct x509_root *root)
Validate X.509 certificate chain.
Definition: x509.c:1907
static void digest_init(struct digest_algorithm *digest, void *ctx)
Definition: crypto.h:196
static void image_untrust(struct image *image)
Set image as untrusted.
Definition: image.h:276
int(* parse)(struct cms_message *cms, const struct asn1_cursor *raw)
Parse content.
Definition: cms.h:33
int register_image(struct image *image)
Register executable image.
Definition: image.c:314
int x509_auto_append(struct x509_chain *chain, struct x509_chain *store)
Append X.509 certificates to X.509 certificate chain.
Definition: x509.c:1867
static struct x509_certificate * x509_last(struct x509_chain *chain)
Get last certificate in X.509 certificate chain.
Definition: x509.h:324
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
An X.509 certificate.
Definition: x509.h:215
static void(* free)(struct refcnt *refcnt))
Definition: refcnt.h:54
static int cms_parse(struct cms_message *cms)
Parse CMS message from ASN.1 data.
Definition: cms.c:617
void * zalloc(size_t size)
Allocate cleared memory.
Definition: malloc.c:661
#define EACCES_PAD
Definition: cms.c:70
struct x509_subject subject
Subject.
Definition: x509.h:244
struct cipher_algorithm * cipher
Cipher algorithm.
Definition: cms.h:68
size_t len
Length of raw file image.
Definition: image.h:55
struct digest_algorithm digest_null
Definition: crypto_null.c:48
int asn1_pubkey_algorithm(const struct asn1_cursor *cursor, struct asn1_algorithm **algorithm)
Parse ASN.1 OID-identified public-key algorithm.
Definition: asn1.c:533
struct x509_certificate * x509_find_issuer_serial(struct x509_chain *store, const struct asn1_cursor *issuer, const struct asn1_cursor *serial)
Identify X.509 certificate by issuer and serial number.
Definition: x509.c:1804
#define ENOTSUP_TYPE
Definition: cms.c:78
int image_set_name(struct image *image, const char *name)
Set image name.
Definition: image.c:180
struct asn1_cursor * raw
Raw ASN.1 data.
Definition: cms.h:58
static void cipher_setiv(struct cipher_algorithm *cipher, void *ctx, const void *iv, size_t ivlen)
Definition: crypto.h:218
An ASN.1 object builder.
Definition: asn1.h:28
uint64_t serial
Serial number.
Definition: edd.h:30
int asn1_shrink_any(struct asn1_cursor *cursor)
Shrink ASN.1 object of any type.
Definition: asn1.c:312
void(* auth)(void *ctx, void *auth)
Generate authentication tag.
Definition: crypto.h:117
static void image_put(struct image *image)
Decrement reference count on an image.
Definition: image.h:249
static int cms_is_signature(struct cms_message *cms)
Check if CMS message is a signature message.
Definition: cms.h:104
unsigned char uint8_t
Definition: stdint.h:10
static uint8_t oid_authenvelopeddata[]
"id-authEnvelopedData" object identifier
Definition: cms.c:95
static int cms_verify_digest(struct cms_message *cms, struct cms_participant *part, struct x509_certificate *cert, const void *data, size_t len)
Verify digest of CMS-signed data.
Definition: cms.c:744
static struct cms_type cms_types[]
CMS message types.
Definition: cms.c:98
static int cms_parse_certificates(struct cms_message *cms, const struct asn1_cursor *raw)
Parse CMS message certificate list.
Definition: cms.c:157
X.509 certificates.
size_t ctxsize
Context size.
Definition: crypto.h:54
#define cipher_decrypt(cipher, ctx, src, dst, len)
Definition: crypto.h:238
#define ASN1_SEQUENCE
ASN.1 sequence.
Definition: asn1.h:89
uint32_t next
Next descriptor address.
Definition: dwmac.h:22
static int cms_verify_signer(struct cms_message *cms, struct cms_participant *part, const void *data, size_t len, time_t time, struct x509_chain *store, struct x509_root *root)
Verify CMS message signer.
Definition: cms.c:781
struct cipher_algorithm cipher_null
Definition: crypto_null.c:83
#define ASN1_INTEGER
ASN.1 integer.
Definition: asn1.h:62
#define EACCES_NON_CODE_SIGNING
Definition: cms.c:50
An X.509 root certificate list.
Definition: x509.h:374
u16 algorithm
Authentication algorithm (Open System or Shared Key)
Definition: ieee80211.h:1030
Date and time.
long pad_len
Definition: bigint.h:30
static int cms_parse_encrypted(struct cms_message *cms, const struct asn1_cursor *raw)
Parse CMS message encrypted content information.
Definition: cms.c:478
static void cms_free(struct refcnt *refcnt)
Free CMS message.
Definition: cms.c:645
#define INIT_LIST_HEAD(list)
Initialise a list head.
Definition: list.h:45
void unregister_image(struct image *image)
Unregister executable image.
Definition: image.c:357
const char * x509_name(struct x509_certificate *cert)
Get X.509 certificate display name.
Definition: x509.c:146
#define ASN1_OID
ASN.1 object identifier.
Definition: asn1.h:74
static void cms_put(struct cms_message *cms)
Drop reference to CMS message.
Definition: cms.h:93
static int cms_parse_identifier(struct cms_message *cms, struct cms_participant *part, const struct asn1_cursor *raw)
Parse CMS message participant identifier.
Definition: cms.c:197
struct list_head participants
List of participant information blocks.
Definition: cms.h:65
int asn1_skip_if_exists(struct asn1_cursor *cursor, unsigned int type)
Skip ASN.1 object if present.
Definition: asn1.c:214
static int pubkey_verify(struct pubkey_algorithm *pubkey, const struct asn1_cursor *key, struct digest_algorithm *digest, const void *value, const struct asn1_cursor *signature)
Definition: crypto.h:285
size_t ctxsize
Context size.
Definition: crypto.h:22
static int cms_cipher(struct cms_message *cms, struct private_key *private_key, void *ctx)
Initialise cipher for CMS decryption.
Definition: cms.c:963
int asn1_cipher_algorithm(const struct asn1_cursor *cursor, struct asn1_algorithm **algorithm, struct asn1_cursor *params)
Parse ASN.1 OID-identified cipher algorithm.
Definition: asn1.c:586
#define ENOTTY
Inappropriate I/O control operation.
Definition: errno.h:594
unsigned int bits
Usage bits.
Definition: x509.h:96
size_t digestsize
Digest size.
Definition: crypto.h:26
struct list_head list
List of participant information blocks.
Definition: cms.h:40
static struct x509_certificate * x509_first(struct x509_chain *chain)
Get first certificate in X.509 certificate chain.
Definition: x509.h:310
int asn1_skip(struct asn1_cursor *cursor, unsigned int type)
Skip ASN.1 object.
Definition: asn1.c:243
void * rwdata
Writable data.
Definition: image.h:52
int cms_decrypt(struct cms_message *cms, struct image *image, const char *name, struct private_key *private_key)
Decrypt CMS message.
Definition: cms.c:1038
static int cms_parse_participant(struct cms_message *cms, struct cms_participant *part, const struct asn1_cursor *raw)
Parse CMS message participant information.
Definition: cms.c:382
struct x509_chain * chain
Certificate chain.
Definition: cms.h:42
static int cms_parse_pubkey_algorithm(struct cms_message *cms, struct cms_participant *part, const struct asn1_cursor *raw)
Parse CMS message public-key algorithm.
Definition: cms.c:297
A message digest algorithm.
Definition: crypto.h:18
struct asn1_cursor iv
Cipher initialization vector.
Definition: cms.h:70
struct x509_link store
Link in certificate store.
Definition: x509.h:220
uint8_t data[48]
Additional event data.
Definition: ena.h:22
#define ASN1_OID_AUTHENVELOPEDDATA
ASN.1 OID for id-authEnvelopedData (1.2.840.113549.1.9.16.1.23)
Definition: asn1.h:336
A cipher algorithm.
Definition: crypto.h:50
A private key.
Definition: privkey.h:16
__be32 raw[7]
Definition: CIB_PRM.h:28
struct x509_certificate * x509_find_key(struct x509_chain *store, struct private_key *key)
Identify X.509 certificate by corresponding public key.
Definition: x509.c:1834
static int cms_parse_mac(struct cms_message *cms, const struct asn1_cursor *raw)
Parse CMS message MAC.
Definition: cms.c:504
static uint8_t oid_signeddata[]
"id-signedData" object identifier
Definition: cms.c:89
static void cipher_auth(struct cipher_algorithm *cipher, void *ctx, void *auth)
Definition: crypto.h:244
struct asn1_cursor mac
Cipher authentication tag.
Definition: cms.h:72
#define ASN1_EXPLICIT_TAG(number)
ASN.1 explicit tag.
Definition: asn1.h:98
static void image_trust(struct image *image)
Set image as trusted.
Definition: image.h:267
static int cms_verify_padding(struct cms_message *cms, const void *data, size_t len)
Check CMS padding.
Definition: cms.c:990
struct x509_key_usage usage
Key usage.
Definition: x509.h:160
int64_t time_t
Seconds since the Epoch.
Definition: time.h:18
#define ASN1_OCTET_STRING
ASN.1 octet string.
Definition: asn1.h:68
#define EACCES_MAC
Definition: cms.c:74
int memcmp(const void *first, const void *second, size_t len)
Compare memory regions.
Definition: string.c:114
Cryptographic Message Syntax (PKCS #7)
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321
size_t len
Length of data.
Definition: asn1.h:37
String functions.
An ASN.1 object cursor.
Definition: asn1.h:20
A public key algorithm.
Definition: crypto.h:121
union @391 key
Sense key.
Definition: scsi.h:17
static int pubkey_decrypt(struct pubkey_algorithm *pubkey, const struct asn1_cursor *key, const struct asn1_cursor *ciphertext, struct asn1_builder *plaintext)
Definition: crypto.h:271
struct x509_extensions extensions
Extensions.
Definition: x509.h:248
static int cipher_setkey(struct cipher_algorithm *cipher, void *ctx, const void *key, size_t keylen)
Definition: crypto.h:212
static uint8_t oid_envelopeddata[]
"id-envelopedData" object identifier
Definition: cms.c:92
static int cms_parse_content_type(struct cms_message *cms, const struct asn1_cursor *raw)
Parse CMS message content type.
Definition: cms.c:123
#define EACCES_LEN
Definition: cms.c:66
static int is_block_cipher(struct cipher_algorithm *cipher)
Definition: crypto.h:254