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