Add qemu 2.4.0
[kvmfornfv.git] / qemu / roms / ipxe / src / usr / imgtrust.c
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
20 FILE_LICENCE ( GPL2_OR_LATER );
21
22 #include <stdlib.h>
23 #include <errno.h>
24 #include <time.h>
25 #include <syslog.h>
26 #include <ipxe/uaccess.h>
27 #include <ipxe/image.h>
28 #include <ipxe/cms.h>
29 #include <ipxe/validator.h>
30 #include <ipxe/monojob.h>
31 #include <usr/imgtrust.h>
32
33 /** @file
34  *
35  * Image trust management
36  *
37  */
38
39 /**
40  * Verify image using downloaded signature
41  *
42  * @v image             Image to verify
43  * @v signature         Image containing signature
44  * @v name              Required common name, or NULL to allow any name
45  * @ret rc              Return status code
46  */
47 int imgverify ( struct image *image, struct image *signature,
48                 const char *name ) {
49         size_t len;
50         void *data;
51         struct cms_signature *sig;
52         struct cms_signer_info *info;
53         time_t now;
54         int rc;
55
56         /* Mark image as untrusted */
57         image_untrust ( image );
58
59         /* Copy signature to internal memory */
60         len = signature->len;
61         data = malloc ( len );
62         if ( ! data ) {
63                 rc = -ENOMEM;
64                 goto err_alloc;
65         }
66         copy_from_user ( data, signature->data, 0, len );
67
68         /* Parse signature */
69         if ( ( rc = cms_signature ( data, len, &sig ) ) != 0 )
70                 goto err_parse;
71
72         /* Free internal copy of signature */
73         free ( data );
74         data = NULL;
75
76         /* Complete all certificate chains */
77         list_for_each_entry ( info, &sig->info, list ) {
78                 if ( ( rc = create_validator ( &monojob, info->chain ) ) != 0 )
79                         goto err_create_validator;
80                 if ( ( rc = monojob_wait ( NULL, 0 ) ) != 0 )
81                         goto err_validator_wait;
82         }
83
84         /* Use signature to verify image */
85         now = time ( NULL );
86         if ( ( rc = cms_verify ( sig, image->data, image->len,
87                                  name, now, NULL, NULL ) ) != 0 )
88                 goto err_verify;
89
90         /* Drop reference to signature */
91         cms_put ( sig );
92         sig = NULL;
93
94         /* Mark image as trusted */
95         image_trust ( image );
96         syslog ( LOG_NOTICE, "Image \"%s\" signature OK\n", image->name );
97
98         return 0;
99
100  err_verify:
101  err_validator_wait:
102  err_create_validator:
103         cms_put ( sig );
104  err_parse:
105         free ( data );
106  err_alloc:
107         syslog ( LOG_ERR, "Image \"%s\" signature bad: %s\n",
108                  image->name, strerror ( rc ) );
109         return rc;
110 }