1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
|
/*
* Copyright (C) 2007 Michael Brown <mbrown@fensystems.co.uk>.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
*/
FILE_LICENCE ( GPL2_OR_LATER );
#include <stdlib.h>
#include <ipxe/crypto.h>
#include <ipxe/sha256.h>
#include <ipxe/x509.h>
#include <ipxe/settings.h>
#include <ipxe/dhcp.h>
#include <ipxe/init.h>
#include <ipxe/rootcert.h>
/** @file
*
* Root certificate store
*
*/
/** Length of a root certificate fingerprint */
#define FINGERPRINT_LEN SHA256_DIGEST_SIZE
/* Allow trusted certificates to be overridden if not explicitly specified */
#ifdef TRUSTED
#define ALLOW_TRUST_OVERRIDE 0
#else
#define ALLOW_TRUST_OVERRIDE 1
#endif
/* Use iPXE root CA if no trusted certificates are explicitly specified */
#ifndef TRUSTED
#define TRUSTED \
/* iPXE root CA */ \
0x9f, 0xaf, 0x71, 0x7b, 0x7f, 0x8c, 0xa2, 0xf9, 0x3c, 0x25, \
0x6c, 0x79, 0xf8, 0xac, 0x55, 0x91, 0x89, 0x5d, 0x66, 0xd1, \
0xff, 0x3b, 0xee, 0x63, 0x97, 0xa7, 0x0d, 0x29, 0xc6, 0x5e, \
0xed, 0x1a,
#endif
/** Root certificate fingerprints */
static const uint8_t fingerprints[] = { TRUSTED };
/** Root certificate fingerprint setting */
static struct setting trust_setting __setting ( SETTING_CRYPTO ) = {
.name = "trust",
.description = "Trusted root certificate fingerprints",
.tag = DHCP_EB_TRUST,
.type = &setting_type_hex,
};
/** Root certificates */
struct x509_root root_certificates = {
.digest = &sha256_algorithm,
.count = ( sizeof ( fingerprints ) / FINGERPRINT_LEN ),
.fingerprints = fingerprints,
};
/**
* Initialise root certificate
*
* The list of trusted root certificates can be specified at build
* time using the TRUST= build parameter. If no certificates are
* specified, then the default iPXE root CA certificate is trusted.
*
* If no certificates were explicitly specified, then we allow the
* list of trusted root certificate fingerprints to be overridden
* using the "trust" setting, but only at the point of iPXE
* initialisation. This prevents untrusted sources of settings
* (e.g. DHCP) from subverting the chain of trust, while allowing
* trustworthy sources (e.g. VMware GuestInfo or non-volatile stored
* options) to specify the trusted root certificate without requiring
* a rebuild.
*/
static void rootcert_init ( void ) {
void *external = NULL;
int len;
int rc;
/* Allow trusted root certificates to be overridden only if
* not explicitly specified at build time.
*/
if ( ALLOW_TRUST_OVERRIDE ) {
/* Fetch copy of "trust" setting, if it exists. This
* memory will never be freed.
*/
len = fetch_setting_copy ( NULL, &trust_setting, &external );
if ( len < 0 ) {
rc = len;
DBGC ( &root_certificates, "ROOTCERT cannot fetch "
"trusted root certificate fingerprints: %s\n",
strerror ( rc ) );
/* No way to prevent startup; fail safe by
* trusting no certificates.
*/
root_certificates.count = 0;
return;
}
/* Use certificates from "trust" setting, if present */
if ( external ) {
root_certificates.fingerprints = external;
root_certificates.count = ( len / FINGERPRINT_LEN );
}
}
DBGC ( &root_certificates, "ROOTCERT using %d %s certificate(s):\n",
root_certificates.count, ( external ? "external" : "built-in" ));
DBGC_HDA ( &root_certificates, 0, root_certificates.fingerprints,
( root_certificates.count * FINGERPRINT_LEN ) );
}
/** Root certificate initialiser */
struct init_fn rootcert_init_fn __init_fn ( INIT_LATE ) = {
.initialise = rootcert_init,
};
|