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/malloc.h>
41 #include <ipxe/uaccess.h>
42 #include <ipxe/cms.h>
43 
44 /* Disambiguate the various error causes */
45 #define EACCES_NON_SIGNING \
46  __einfo_error ( EINFO_EACCES_NON_SIGNING )
47 #define EINFO_EACCES_NON_SIGNING \
48  __einfo_uniqify ( EINFO_EACCES, 0x01, "Not a signing certificate" )
49 #define EACCES_NON_CODE_SIGNING \
50  __einfo_error ( EINFO_EACCES_NON_CODE_SIGNING )
51 #define EINFO_EACCES_NON_CODE_SIGNING \
52  __einfo_uniqify ( EINFO_EACCES, 0x02, "Not a code-signing certificate" )
53 #define EACCES_WRONG_NAME \
54  __einfo_error ( EINFO_EACCES_WRONG_NAME )
55 #define EINFO_EACCES_WRONG_NAME \
56  __einfo_uniqify ( EINFO_EACCES, 0x04, "Incorrect certificate name" )
57 #define EACCES_NO_SIGNATURES \
58  __einfo_error ( EINFO_EACCES_NO_SIGNATURES )
59 #define EINFO_EACCES_NO_SIGNATURES \
60  __einfo_uniqify ( EINFO_EACCES, 0x05, "No signatures present" )
61 #define EINVAL_DIGEST \
62  __einfo_error ( EINFO_EINVAL_DIGEST )
63 #define EINFO_EINVAL_DIGEST \
64  __einfo_uniqify ( EINFO_EINVAL, 0x01, "Not a digest algorithm" )
65 #define EINVAL_PUBKEY \
66  __einfo_error ( EINFO_EINVAL_PUBKEY )
67 #define EINFO_EINVAL_PUBKEY \
68  __einfo_uniqify ( EINFO_EINVAL, 0x02, "Not a public-key algorithm" )
69 #define ENOTSUP_SIGNEDDATA \
70  __einfo_error ( EINFO_ENOTSUP_SIGNEDDATA )
71 #define EINFO_ENOTSUP_SIGNEDDATA \
72  __einfo_uniqify ( EINFO_ENOTSUP, 0x01, "Not a digital signature" )
73 
74 /** "pkcs7-signedData" object identifier */
76 
77 /** "pkcs7-signedData" object identifier cursor */
80 
81 /**
82  * Parse CMS signature content type
83  *
84  * @v sig CMS signature
85  * @v raw ASN.1 cursor
86  * @ret rc Return status code
87  */
89  const struct asn1_cursor *raw ) {
90  struct asn1_cursor cursor;
91 
92  /* Enter contentType */
93  memcpy ( &cursor, raw, sizeof ( cursor ) );
94  asn1_enter ( &cursor, ASN1_OID );
95 
96  /* Check OID is pkcs7-signedData */
97  if ( asn1_compare ( &cursor, &oid_signeddata_cursor ) != 0 ) {
98  DBGC ( sig, "CMS %p does not contain signedData:\n", sig );
99  DBGC_HDA ( sig, 0, raw->data, raw->len );
100  return -ENOTSUP_SIGNEDDATA;
101  }
102 
103  DBGC ( sig, "CMS %p contains signedData\n", sig );
104  return 0;
105 }
106 
107 /**
108  * Parse CMS signature certificate list
109  *
110  * @v sig CMS signature
111  * @v raw ASN.1 cursor
112  * @ret rc Return status code
113  */
115  const struct asn1_cursor *raw ) {
116  struct asn1_cursor cursor;
117  struct x509_certificate *cert;
118  int rc;
119 
120  /* Enter certificates */
121  memcpy ( &cursor, raw, sizeof ( cursor ) );
122  asn1_enter ( &cursor, ASN1_EXPLICIT_TAG ( 0 ) );
123 
124  /* Add each certificate */
125  while ( cursor.len ) {
126 
127  /* Add certificate to chain */
128  if ( ( rc = x509_append_raw ( sig->certificates, cursor.data,
129  cursor.len ) ) != 0 ) {
130  DBGC ( sig, "CMS %p could not append certificate: %s\n",
131  sig, strerror ( rc) );
132  DBGC_HDA ( sig, 0, cursor.data, cursor.len );
133  return rc;
134  }
135  cert = x509_last ( sig->certificates );
136  DBGC ( sig, "CMS %p found certificate %s\n",
137  sig, x509_name ( cert ) );
138 
139  /* Move to next certificate */
140  asn1_skip_any ( &cursor );
141  }
142 
143  return 0;
144 }
145 
146 /**
147  * Identify CMS signature certificate by issuer and serial number
148  *
149  * @v sig CMS signature
150  * @v issuer Issuer
151  * @v serial Serial number
152  * @ret cert X.509 certificate, or NULL if not found
153  */
154 static struct x509_certificate *
156  const struct asn1_cursor *issuer,
157  const struct asn1_cursor *serial ) {
158  struct x509_link *link;
159  struct x509_certificate *cert;
160 
161  /* Scan through certificate list */
162  list_for_each_entry ( link, &sig->certificates->links, list ) {
163 
164  /* Check issuer and serial number */
165  cert = link->cert;
166  if ( ( asn1_compare ( issuer, &cert->issuer.raw ) == 0 ) &&
167  ( asn1_compare ( serial, &cert->serial.raw ) == 0 ) )
168  return cert;
169  }
170 
171  return NULL;
172 }
173 
174 /**
175  * Parse CMS signature signer identifier
176  *
177  * @v sig CMS signature
178  * @v info Signer information to fill in
179  * @v raw ASN.1 cursor
180  * @ret rc Return status code
181  */
183  struct cms_signer_info *info,
184  const struct asn1_cursor *raw ) {
185  struct asn1_cursor cursor;
186  struct asn1_cursor serial;
187  struct asn1_cursor issuer;
188  struct x509_certificate *cert;
189  int rc;
190 
191  /* Enter issuerAndSerialNumber */
192  memcpy ( &cursor, raw, sizeof ( cursor ) );
193  asn1_enter ( &cursor, ASN1_SEQUENCE );
194 
195  /* Identify issuer */
196  memcpy ( &issuer, &cursor, sizeof ( issuer ) );
197  if ( ( rc = asn1_shrink ( &issuer, ASN1_SEQUENCE ) ) != 0 ) {
198  DBGC ( sig, "CMS %p/%p could not locate issuer: %s\n",
199  sig, info, strerror ( rc ) );
200  DBGC_HDA ( sig, 0, raw->data, raw->len );
201  return rc;
202  }
203  DBGC ( sig, "CMS %p/%p issuer is:\n", sig, info );
204  DBGC_HDA ( sig, 0, issuer.data, issuer.len );
205  asn1_skip_any ( &cursor );
206 
207  /* Identify serialNumber */
208  memcpy ( &serial, &cursor, sizeof ( serial ) );
209  if ( ( rc = asn1_shrink ( &serial, ASN1_INTEGER ) ) != 0 ) {
210  DBGC ( sig, "CMS %p/%p could not locate serialNumber: %s\n",
211  sig, info, strerror ( rc ) );
212  DBGC_HDA ( sig, 0, raw->data, raw->len );
213  return rc;
214  }
215  DBGC ( sig, "CMS %p/%p serial number is:\n", sig, info );
216  DBGC_HDA ( sig, 0, serial.data, serial.len );
217 
218  /* Identify certificate */
219  cert = cms_find_issuer_serial ( sig, &issuer, &serial );
220  if ( ! cert ) {
221  DBGC ( sig, "CMS %p/%p could not identify signer's "
222  "certificate\n", sig, info );
223  return -ENOENT;
224  }
225 
226  /* Append certificate to chain */
227  if ( ( rc = x509_append ( info->chain, cert ) ) != 0 ) {
228  DBGC ( sig, "CMS %p/%p could not append certificate: %s\n",
229  sig, info, strerror ( rc ) );
230  return rc;
231  }
232 
233  /* Append remaining certificates to chain */
234  if ( ( rc = x509_auto_append ( info->chain,
235  sig->certificates ) ) != 0 ) {
236  DBGC ( sig, "CMS %p/%p could not append certificates: %s\n",
237  sig, info, strerror ( rc ) );
238  return rc;
239  }
240 
241  return 0;
242 }
243 
244 /**
245  * Parse CMS signature digest algorithm
246  *
247  * @v sig CMS signature
248  * @v info Signer information to fill in
249  * @v raw ASN.1 cursor
250  * @ret rc Return status code
251  */
253  struct cms_signer_info *info,
254  const struct asn1_cursor *raw ) {
255  struct asn1_algorithm *algorithm;
256  int rc;
257 
258  /* Identify algorithm */
259  if ( ( rc = asn1_digest_algorithm ( raw, &algorithm ) ) != 0 ) {
260  DBGC ( sig, "CMS %p/%p could not identify digest algorithm: "
261  "%s\n", sig, info, strerror ( rc ) );
262  DBGC_HDA ( sig, 0, raw->data, raw->len );
263  return rc;
264  }
265 
266  /* Record digest algorithm */
267  info->digest = algorithm->digest;
268  DBGC ( sig, "CMS %p/%p digest algorithm is %s\n",
269  sig, info, algorithm->name );
270 
271  return 0;
272 }
273 
274 /**
275  * Parse CMS signature algorithm
276  *
277  * @v sig CMS signature
278  * @v info Signer information to fill in
279  * @v raw ASN.1 cursor
280  * @ret rc Return status code
281  */
283  struct cms_signer_info *info,
284  const struct asn1_cursor *raw ) {
285  struct asn1_algorithm *algorithm;
286  int rc;
287 
288  /* Identify algorithm */
289  if ( ( rc = asn1_pubkey_algorithm ( raw, &algorithm ) ) != 0 ) {
290  DBGC ( sig, "CMS %p/%p could not identify public-key "
291  "algorithm: %s\n", sig, info, strerror ( rc ) );
292  DBGC_HDA ( sig, 0, raw->data, raw->len );
293  return rc;
294  }
295 
296  /* Record signature algorithm */
297  info->pubkey = algorithm->pubkey;
298  DBGC ( sig, "CMS %p/%p public-key algorithm is %s\n",
299  sig, info, algorithm->name );
300 
301  return 0;
302 }
303 
304 /**
305  * Parse CMS signature value
306  *
307  * @v sig CMS signature
308  * @v info Signer information to fill in
309  * @v raw ASN.1 cursor
310  * @ret rc Return status code
311  */
313  struct cms_signer_info *info,
314  const struct asn1_cursor *raw ) {
315  struct asn1_cursor cursor;
316  int rc;
317 
318  /* Enter signature */
319  memcpy ( &cursor, raw, sizeof ( cursor ) );
320  if ( ( rc = asn1_enter ( &cursor, ASN1_OCTET_STRING ) ) != 0 ) {
321  DBGC ( sig, "CMS %p/%p could not locate signature:\n",
322  sig, info );
323  DBGC_HDA ( sig, 0, raw->data, raw->len );
324  return rc;
325  }
326 
327  /* Record signature */
328  info->signature_len = cursor.len;
329  info->signature = malloc ( info->signature_len );
330  if ( ! info->signature )
331  return -ENOMEM;
332  memcpy ( info->signature, cursor.data, info->signature_len );
333  DBGC ( sig, "CMS %p/%p signature value is:\n", sig, info );
334  DBGC_HDA ( sig, 0, info->signature, info->signature_len );
335 
336  return 0;
337 }
338 
339 /**
340  * Parse CMS signature signer information
341  *
342  * @v sig CMS signature
343  * @v info Signer information to fill in
344  * @v raw ASN.1 cursor
345  * @ret rc Return status code
346  */
348  struct cms_signer_info *info,
349  const struct asn1_cursor *raw ) {
350  struct asn1_cursor cursor;
351  int rc;
352 
353  /* Enter signerInfo */
354  memcpy ( &cursor, raw, sizeof ( cursor ) );
355  asn1_enter ( &cursor, ASN1_SEQUENCE );
356 
357  /* Skip version */
358  asn1_skip ( &cursor, ASN1_INTEGER );
359 
360  /* Parse sid */
361  if ( ( rc = cms_parse_signer_identifier ( sig, info, &cursor ) ) != 0 )
362  return rc;
363  asn1_skip_any ( &cursor );
364 
365  /* Parse digestAlgorithm */
366  if ( ( rc = cms_parse_digest_algorithm ( sig, info, &cursor ) ) != 0 )
367  return rc;
368  asn1_skip_any ( &cursor );
369 
370  /* Skip signedAttrs, if present */
371  asn1_skip_if_exists ( &cursor, ASN1_EXPLICIT_TAG ( 0 ) );
372 
373  /* Parse signatureAlgorithm */
374  if ( ( rc = cms_parse_signature_algorithm ( sig, info, &cursor ) ) != 0)
375  return rc;
376  asn1_skip_any ( &cursor );
377 
378  /* Parse signature */
379  if ( ( rc = cms_parse_signature_value ( sig, info, &cursor ) ) != 0 )
380  return rc;
381 
382  return 0;
383 }
384 
385 /**
386  * Parse CMS signature from ASN.1 data
387  *
388  * @v sig CMS signature
389  * @v raw ASN.1 cursor
390  * @ret rc Return status code
391  */
392 static int cms_parse ( struct cms_signature *sig,
393  const struct asn1_cursor *raw ) {
394  struct asn1_cursor cursor;
395  struct cms_signer_info *info;
396  int rc;
397 
398  /* Enter contentInfo */
399  memcpy ( &cursor, raw, sizeof ( cursor ) );
400  asn1_enter ( &cursor, ASN1_SEQUENCE );
401 
402  /* Parse contentType */
403 
404  if ( ( rc = cms_parse_content_type ( sig, &cursor ) ) != 0 )
405  return rc;
406  asn1_skip_any ( &cursor );
407 
408  /* Enter content */
409  asn1_enter ( &cursor, ASN1_EXPLICIT_TAG ( 0 ) );
410 
411  /* Enter signedData */
412  asn1_enter ( &cursor, ASN1_SEQUENCE );
413 
414  /* Skip version */
415  asn1_skip ( &cursor, ASN1_INTEGER );
416 
417  /* Skip digestAlgorithms */
418  asn1_skip ( &cursor, ASN1_SET );
419 
420  /* Skip encapContentInfo */
421  asn1_skip ( &cursor, ASN1_SEQUENCE );
422 
423  /* Parse certificates */
424  if ( ( rc = cms_parse_certificates ( sig, &cursor ) ) != 0 )
425  return rc;
426  asn1_skip_any ( &cursor );
427 
428  /* Skip crls, if present */
429  asn1_skip_if_exists ( &cursor, ASN1_EXPLICIT_TAG ( 1 ) );
430 
431  /* Enter signerInfos */
432  asn1_enter ( &cursor, ASN1_SET );
433 
434  /* Add each signerInfo. Errors are handled by ensuring that
435  * cms_put() will always be able to free any allocated memory.
436  */
437  while ( cursor.len ) {
438 
439  /* Allocate signer information block */
440  info = zalloc ( sizeof ( *info ) );
441  if ( ! info )
442  return -ENOMEM;
443  list_add ( &info->list, &sig->info );
444 
445  /* Allocate certificate chain */
446  info->chain = x509_alloc_chain();
447  if ( ! info->chain )
448  return -ENOMEM;
449 
450  /* Parse signerInfo */
451  if ( ( rc = cms_parse_signer_info ( sig, info,
452  &cursor ) ) != 0 )
453  return rc;
454  asn1_skip_any ( &cursor );
455  }
456 
457  return 0;
458 }
459 
460 /**
461  * Free CMS signature
462  *
463  * @v refcnt Reference count
464  */
465 static void cms_free ( struct refcnt *refcnt ) {
466  struct cms_signature *sig =
468  struct cms_signer_info *info;
469  struct cms_signer_info *tmp;
470 
471  list_for_each_entry_safe ( info, tmp, &sig->info, list ) {
472  list_del ( &info->list );
473  x509_chain_put ( info->chain );
474  free ( info->signature );
475  free ( info );
476  }
477  x509_chain_put ( sig->certificates );
478  free ( sig );
479 }
480 
481 /**
482  * Create CMS signature
483  *
484  * @v data Raw signature data
485  * @v len Length of raw data
486  * @ret sig CMS signature
487  * @ret rc Return status code
488  *
489  * On success, the caller holds a reference to the CMS signature, and
490  * is responsible for ultimately calling cms_put().
491  */
492 int cms_signature ( const void *data, size_t len, struct cms_signature **sig ) {
493  struct asn1_cursor cursor;
494  int rc;
495 
496  /* Allocate and initialise signature */
497  *sig = zalloc ( sizeof ( **sig ) );
498  if ( ! *sig ) {
499  rc = -ENOMEM;
500  goto err_alloc;
501  }
502  ref_init ( &(*sig)->refcnt, cms_free );
503  INIT_LIST_HEAD ( &(*sig)->info );
504 
505  /* Allocate certificate list */
506  (*sig)->certificates = x509_alloc_chain();
507  if ( ! (*sig)->certificates ) {
508  rc = -ENOMEM;
509  goto err_alloc_chain;
510  }
511 
512  /* Initialise cursor */
513  cursor.data = data;
514  cursor.len = len;
515  asn1_shrink_any ( &cursor );
516 
517  /* Parse signature */
518  if ( ( rc = cms_parse ( *sig, &cursor ) ) != 0 )
519  goto err_parse;
520 
521  return 0;
522 
523  err_parse:
524  err_alloc_chain:
525  cms_put ( *sig );
526  err_alloc:
527  return rc;
528 }
529 
530 /**
531  * Calculate digest of CMS-signed data
532  *
533  * @v sig CMS signature
534  * @v info Signer information
535  * @v data Signed data
536  * @v len Length of signed data
537  * @v out Digest output
538  */
539 static void cms_digest ( struct cms_signature *sig,
540  struct cms_signer_info *info,
541  userptr_t data, size_t len, void *out ) {
542  struct digest_algorithm *digest = info->digest;
543  uint8_t ctx[ digest->ctxsize ];
544  uint8_t block[ digest->blocksize ];
545  size_t offset = 0;
546  size_t frag_len;
547 
548  /* Initialise digest */
549  digest_init ( digest, ctx );
550 
551  /* Process data one block at a time */
552  while ( len ) {
553  frag_len = len;
554  if ( frag_len > sizeof ( block ) )
555  frag_len = sizeof ( block );
556  copy_from_user ( block, data, offset, frag_len );
557  digest_update ( digest, ctx, block, frag_len );
558  offset += frag_len;
559  len -= frag_len;
560  }
561 
562  /* Finalise digest */
563  digest_final ( digest, ctx, out );
564 
565  DBGC ( sig, "CMS %p/%p digest value:\n", sig, info );
566  DBGC_HDA ( sig, 0, out, digest->digestsize );
567 }
568 
569 /**
570  * Verify digest of CMS-signed data
571  *
572  * @v sig CMS signature
573  * @v info Signer information
574  * @v cert Corresponding certificate
575  * @v data Signed data
576  * @v len Length of signed data
577  * @ret rc Return status code
578  */
579 static int cms_verify_digest ( struct cms_signature *sig,
580  struct cms_signer_info *info,
581  struct x509_certificate *cert,
582  userptr_t data, size_t len ) {
583  struct digest_algorithm *digest = info->digest;
584  struct pubkey_algorithm *pubkey = info->pubkey;
585  struct x509_public_key *public_key = &cert->subject.public_key;
586  uint8_t digest_out[ digest->digestsize ];
587  uint8_t ctx[ pubkey->ctxsize ];
588  int rc;
589 
590  /* Generate digest */
591  cms_digest ( sig, info, data, len, digest_out );
592 
593  /* Initialise public-key algorithm */
594  if ( ( rc = pubkey_init ( pubkey, ctx, public_key->raw.data,
595  public_key->raw.len ) ) != 0 ) {
596  DBGC ( sig, "CMS %p/%p could not initialise public key: %s\n",
597  sig, info, strerror ( rc ) );
598  goto err_init;
599  }
600 
601  /* Verify digest */
602  if ( ( rc = pubkey_verify ( pubkey, ctx, digest, digest_out,
603  info->signature,
604  info->signature_len ) ) != 0 ) {
605  DBGC ( sig, "CMS %p/%p signature verification failed: %s\n",
606  sig, info, strerror ( rc ) );
607  goto err_verify;
608  }
609 
610  err_verify:
611  pubkey_final ( pubkey, ctx );
612  err_init:
613  return rc;
614 }
615 
616 /**
617  * Verify CMS signature signer information
618  *
619  * @v sig CMS signature
620  * @v info Signer information
621  * @v data Signed data
622  * @v len Length of signed data
623  * @v time Time at which to validate certificates
624  * @v store Certificate store, or NULL to use default
625  * @v root Root certificate list, or NULL to use default
626  * @ret rc Return status code
627  */
629  struct cms_signer_info *info,
630  userptr_t data, size_t len,
631  time_t time, struct x509_chain *store,
632  struct x509_root *root ) {
633  struct x509_certificate *cert;
634  int rc;
635 
636  /* Validate certificate chain */
637  if ( ( rc = x509_validate_chain ( info->chain, time, store,
638  root ) ) != 0 ) {
639  DBGC ( sig, "CMS %p/%p could not validate chain: %s\n",
640  sig, info, strerror ( rc ) );
641  return rc;
642  }
643 
644  /* Extract code-signing certificate */
645  cert = x509_first ( info->chain );
646  assert ( cert != NULL );
647 
648  /* Check that certificate can create digital signatures */
649  if ( ! ( cert->extensions.usage.bits & X509_DIGITAL_SIGNATURE ) ) {
650  DBGC ( sig, "CMS %p/%p certificate cannot create signatures\n",
651  sig, info );
652  return -EACCES_NON_SIGNING;
653  }
654 
655  /* Check that certificate can sign code */
656  if ( ! ( cert->extensions.ext_usage.bits & X509_CODE_SIGNING ) ) {
657  DBGC ( sig, "CMS %p/%p certificate is not code-signing\n",
658  sig, info );
659  return -EACCES_NON_CODE_SIGNING;
660  }
661 
662  /* Verify digest */
663  if ( ( rc = cms_verify_digest ( sig, info, cert, data, len ) ) != 0 )
664  return rc;
665 
666  return 0;
667 }
668 
669 /**
670  * Verify CMS signature
671  *
672  * @v sig CMS signature
673  * @v data Signed data
674  * @v len Length of signed data
675  * @v name Required common name, or NULL to check all signatures
676  * @v time Time at which to validate certificates
677  * @v store Certificate store, or NULL to use default
678  * @v root Root certificate list, or NULL to use default
679  * @ret rc Return status code
680  */
681 int cms_verify ( struct cms_signature *sig, userptr_t data, size_t len,
682  const char *name, time_t time, struct x509_chain *store,
683  struct x509_root *root ) {
684  struct cms_signer_info *info;
685  struct x509_certificate *cert;
686  int count = 0;
687  int rc;
688 
689  /* Verify using all signerInfos */
690  list_for_each_entry ( info, &sig->info, list ) {
691  cert = x509_first ( info->chain );
692  if ( name && ( x509_check_name ( cert, name ) != 0 ) )
693  continue;
694  if ( ( rc = cms_verify_signer_info ( sig, info, data, len, time,
695  store, root ) ) != 0 )
696  return rc;
697  count++;
698  }
699 
700  /* Check that we have verified at least one signature */
701  if ( count == 0 ) {
702  if ( name ) {
703  DBGC ( sig, "CMS %p had no signatures matching name "
704  "%s\n", sig, name );
705  return -EACCES_WRONG_NAME;
706  } else {
707  DBGC ( sig, "CMS %p had no signatures\n", sig );
708  return -EACCES_NO_SIGNATURES;
709  }
710  }
711 
712  return 0;
713 }
static struct x509_certificate * cms_find_issuer_serial(struct cms_signature *sig, const struct asn1_cursor *issuer, const struct asn1_cursor *serial)
Identify CMS signature certificate by issuer and serial number.
Definition: cms.c:155
static void x509_chain_put(struct x509_chain *chain)
Drop reference to X.509 certificate chain.
Definition: x509.h:269
An ASN.1 OID-identified algorithm.
Definition: asn1.h:298
struct asn1_cursor raw
Raw public key information.
Definition: x509.h:50
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:177
const char * name
Definition: ath9k_hw.c:1984
struct x509_extended_key_usage ext_usage
Extended key usage.
Definition: x509.h:161
struct asn1_cursor raw
Raw issuer.
Definition: x509.h:30
#define EACCES_NO_SIGNATURES
Definition: cms.c:57
u32 info
Definition: ar9003_mac.h:67
int asn1_compare(const struct asn1_cursor *cursor1, const struct asn1_cursor *cursor2)
Compare two ASN.1 objects.
Definition: asn1.c:443
static int cms_parse_content_type(struct cms_signature *sig, const struct asn1_cursor *raw)
Parse CMS signature content type.
Definition: cms.c:88
#define EACCES_WRONG_NAME
Definition: cms.c:53
static void cms_digest(struct cms_signature *sig, struct cms_signer_info *info, userptr_t data, size_t len, void *out)
Calculate digest of CMS-signed data.
Definition: cms.c:539
u8 sig
Definition: CIB_PRM.h:43
int asn1_enter(struct asn1_cursor *cursor, unsigned int type)
Enter ASN.1 object.
Definition: asn1.c:160
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:114
#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:1519
static int cms_verify_digest(struct cms_signature *sig, struct cms_signer_info *info, struct x509_certificate *cert, userptr_t data, size_t len)
Verify digest of CMS-signed data.
Definition: cms.c:579
static void digest_final(struct digest_algorithm *digest, void *ctx, void *out)
Definition: crypto.h:182
struct x509_issuer issuer
Issuer.
Definition: x509.h:208
uint16_t block
Definition: tftp.h:12
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:1625
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:337
static int cms_parse_certificates(struct cms_signature *sig, const struct asn1_cursor *raw)
Parse CMS signature certificate list.
Definition: cms.c:114
const void * data
Start of data.
Definition: asn1.h:21
#define DBGC(...)
Definition: compiler.h:505
static void cms_put(struct cms_signature *sig)
Drop reference to CMS signature.
Definition: cms.h:66
int asn1_digest_algorithm(const struct asn1_cursor *cursor, struct asn1_algorithm **algorithm)
Parse ASN.1 OID-identified digest algorithm.
Definition: asn1.c:539
int x509_append(struct x509_chain *chain, struct x509_certificate *cert)
Append X.509 certificate to X.509 certificate chain.
Definition: x509.c:1600
#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:1577
static int cms_parse_signer_identifier(struct cms_signature *sig, struct cms_signer_info *info, const struct asn1_cursor *raw)
Parse CMS signature signer identifier.
Definition: cms.c:182
struct asn1_cursor raw
Raw serial number.
Definition: x509.h:24
FILE_LICENCE(GPL2_OR_LATER_OR_UBDL)
struct golan_eq_context ctx
Definition: CIB_PRM.h:28
int cms_signature(const void *data, size_t len, struct cms_signature **sig)
Create CMS signature.
Definition: cms.c:492
struct md4_digest digest
Digest of data already processed.
Definition: md4.h:12
int asn1_skip_any(struct asn1_cursor *cursor)
Skip ASN.1 object of any type.
Definition: asn1.c:276
Access to external ("user") memory.
#define ASN1_SET
ASN.1 set.
Definition: asn1.h:88
size_t ctxsize
Context size.
Definition: crypto.h:98
Dynamic memory allocation.
size_t len
Length of data.
Definition: asn1.h:23
A reference counter.
Definition: refcnt.h:26
#define ENOTSUP_SIGNEDDATA
Definition: cms.c:69
static int cms_parse_signature_algorithm(struct cms_signature *sig, struct cms_signer_info *info, const struct asn1_cursor *raw)
Parse CMS signature algorithm.
Definition: cms.c:282
#define list_del(list)
Delete an entry from a list.
Definition: list.h:119
An X.509 certificate chain.
Definition: x509.h:177
#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:240
void * memcpy(void *dest, const void *src, size_t len) __nonnull
static int pubkey_verify(struct pubkey_algorithm *pubkey, void *ctx, struct digest_algorithm *digest, const void *value, const void *signature, size_t signature_len)
Definition: crypto.h:247
static int cms_parse(struct cms_signature *sig, const struct asn1_cursor *raw)
Parse CMS signature from ASN.1 data.
Definition: cms.c:392
#define ASN1_OID_SIGNEDDATA
ASN.1 OID for pkcs-signedData (1.2.840.113549.1.7.2)
Definition: asn1.h:252
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
#define container_of(ptr, type, field)
Get containing structure.
Definition: stddef.h:35
ASN.1 encoding.
CMS signer information.
Definition: cms.h:20
#define list_for_each_entry(pos, head, member)
Iterate over entries in a list.
Definition: list.h:420
#define DBGC_HDA(...)
Definition: compiler.h:506
static userptr_t size_t offset
Offset of the first segment within the content.
Definition: deflate.h:259
#define ASN1_OID_CURSOR(oid_value)
Define an ASN.1 cursor containing an OID.
Definition: asn1.h:292
__be32 out[4]
Definition: CIB_PRM.h:36
u32 link
Link to next descriptor.
Definition: ar9003_mac.h:68
#define EACCES_NON_SIGNING
Definition: cms.c:45
An X.509 certificate public key.
Definition: x509.h:48
static struct asn1_cursor oid_signeddata_cursor
"pkcs7-signedData" object identifier cursor
Definition: cms.c:78
#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:447
struct x509_public_key public_key
Public key information.
Definition: x509.h:64
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:1724
static int cms_parse_digest_algorithm(struct cms_signature *sig, struct cms_signer_info *info, const struct asn1_cursor *raw)
Parse CMS signature digest algorithm.
Definition: cms.c:252
static void digest_init(struct digest_algorithm *digest, void *ctx)
Definition: crypto.h:172
static struct x509_certificate * x509_last(struct x509_chain *chain)
Get last certificate in X.509 certificate chain.
Definition: x509.h:294
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
An X.509 certificate.
Definition: x509.h:185
static void(* free)(struct refcnt *refcnt))
Definition: refcnt.h:54
struct x509_serial serial
Serial number.
Definition: x509.h:202
void * zalloc(size_t size)
Allocate cleared memory.
Definition: malloc.c:624
struct x509_subject subject
Subject.
Definition: x509.h:212
int asn1_pubkey_algorithm(const struct asn1_cursor *cursor, struct asn1_algorithm **algorithm)
Parse ASN.1 OID-identified public-key algorithm.
Definition: asn1.c:513
uint8_t * tmp
Definition: entropy.h:156
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:286
unsigned char uint8_t
Definition: stdint.h:10
static int cms_parse_signer_info(struct cms_signature *sig, struct cms_signer_info *info, const struct asn1_cursor *raw)
Parse CMS signature signer information.
Definition: cms.c:347
X.509 certificates.
#define ASN1_SEQUENCE
ASN.1 sequence.
Definition: asn1.h:85
struct list_head list
List of signer information blocks.
Definition: cms.h:22
void * malloc(size_t size)
Allocate memory.
Definition: malloc.c:583
#define ASN1_INTEGER
ASN.1 integer.
Definition: asn1.h:61
#define EACCES_NON_CODE_SIGNING
Definition: cms.c:49
An X.509 root certificate store.
Definition: x509.h:344
u16 algorithm
Authentication algorithm (Open System or Shared Key)
Definition: ieee80211.h:1030
Date and time.
static void cms_free(struct refcnt *refcnt)
Free CMS signature.
Definition: cms.c:465
#define INIT_LIST_HEAD(list)
Initialise a list head.
Definition: list.h:45
const char * x509_name(struct x509_certificate *cert)
Get X.509 certificate display name.
Definition: x509.c:131
#define ASN1_OID
ASN.1 object identifier.
Definition: asn1.h:73
static int cms_parse_signature_value(struct cms_signature *sig, struct cms_signer_info *info, const struct asn1_cursor *raw)
Parse CMS signature value.
Definition: cms.c:312
uint32_t len
Length.
Definition: ena.h:14
int asn1_skip_if_exists(struct asn1_cursor *cursor, unsigned int type)
Skip ASN.1 object if present.
Definition: asn1.c:187
int x509_auto_append(struct x509_chain *chain, struct x509_chain *certs)
Append X.509 certificates to X.509 certificate chain.
Definition: x509.c:1684
unsigned int bits
Usage bits.
Definition: x509.h:95
static struct x509_certificate * x509_first(struct x509_chain *chain)
Get first certificate in X.509 certificate chain.
Definition: x509.h:280
int asn1_skip(struct asn1_cursor *cursor, unsigned int type)
Skip ASN.1 object.
Definition: asn1.c:218
uint16_t count
Number of entries.
Definition: ena.h:22
A message digest algorithm.
Definition: crypto.h:16
int cms_verify(struct cms_signature *sig, userptr_t data, size_t len, const char *name, time_t time, struct x509_chain *store, struct x509_root *root)
Verify CMS signature.
Definition: cms.c:681
struct x509_link store
Link in certificate store.
Definition: x509.h:190
A CMS signature.
Definition: cms.h:39
__be32 raw[7]
Definition: CIB_PRM.h:28
static void pubkey_final(struct pubkey_algorithm *pubkey, void *ctx)
Definition: crypto.h:254
static uint8_t oid_signeddata[]
"pkcs7-signedData" object identifier
Definition: cms.c:75
static int cms_verify_signer_info(struct cms_signature *sig, struct cms_signer_info *info, userptr_t data, size_t len, time_t time, struct x509_chain *store, struct x509_root *root)
Verify CMS signature signer information.
Definition: cms.c:628
struct arbelprm_port_state_change_st data
Message.
Definition: arbel.h:12
#define ASN1_EXPLICIT_TAG(number)
ASN.1 explicit tag.
Definition: asn1.h:94
struct x509_key_usage usage
Key usage.
Definition: x509.h:159
int64_t time_t
Seconds since the Epoch.
Definition: time.h:18
#define ASN1_OCTET_STRING
ASN.1 octet string.
Definition: asn1.h:67
uint64_t time
Current time.
Definition: ntlm.h:20
Cryptographic Message Syntax (PKCS #7)
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362
String functions.
An ASN.1 object cursor.
Definition: asn1.h:19
A public key algorithm.
Definition: crypto.h:94
struct x509_extensions extensions
Extensions.
Definition: x509.h:216
unsigned long userptr_t
A pointer to a user buffer.
Definition: uaccess.h:33
static int pubkey_init(struct pubkey_algorithm *pubkey, void *ctx, const void *key, size_t key_len)
Definition: crypto.h:221