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