iPXE
privkey.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
24FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
25FILE_SECBOOT ( PERMITTED );
26
27#include <stdint.h>
28#include <stdlib.h>
29#include <string.h>
30#include <ipxe/dhcp.h>
31#include <ipxe/settings.h>
32#include <ipxe/x509.h>
33#include <ipxe/privkey.h>
34
35/** @file
36 *
37 * Private key
38 *
39 * Life would in theory be easier if we could use a single file to
40 * hold both the certificate and corresponding private key.
41 * Unfortunately, the only common format which supports this is
42 * PKCS#12 (aka PFX), which is too ugly to be allowed anywhere near my
43 * codebase. See, for reference and amusement:
44 *
45 * http://www.cs.auckland.ac.nz/~pgut001/pubs/pfx.html
46 */
47
48/* Allow private key to be overridden if not explicitly specified */
49#ifdef PRIVATE_KEY
50#define ALLOW_KEY_OVERRIDE 0
51#else
52#define ALLOW_KEY_OVERRIDE 1
53#endif
54
55/* Raw private key data */
56extern char private_key_data[];
57extern size_t ABS_SYMBOL ( private_key_len );
58__asm__ ( ".section \".rodata\", \"a\", " PROGBITS "\n\t"
59 "\nprivate_key_data:\n\t"
60#ifdef PRIVATE_KEY
61 ".incbin \"" PRIVATE_KEY "\"\n\t"
62#endif /* PRIVATE_KEY */
63 ".size private_key_data, ( . - private_key_data )\n\t"
64 ".equ private_key_len, ( . - private_key_data )\n\t"
65 ".previous\n\t" );
66
67/** Private key */
69 .refcnt = REF_INIT ( ref_no_free ),
70 .builder = {
71 .data = private_key_data,
72 .len = ABS_VALUE_INIT ( private_key_len ),
73 },
74};
75
76/** Default private key */
78 .data = private_key_data,
79 .len = ( ( size_t ) private_key_len ),
80};
81
82/** Private key setting */
83static struct setting privkey_setting __setting ( SETTING_CRYPTO, privkey ) = {
84 .name = "privkey",
85 .description = "Private key",
86 .tag = DHCP_EB_KEY,
87 .type = &setting_type_hex,
88};
89
90/**
91 * Free private key
92 *
93 * @v refcnt Reference counter
94 */
95void privkey_free ( struct refcnt *refcnt ) {
96 struct private_key *key =
98
99 free ( key->builder.data );
100 free ( key );
101}
102
103/**
104 * Apply private key configuration settings
105 *
106 * @ret rc Return status code
107 */
108static int privkey_apply_settings ( void ) {
109 static void *key_data = NULL;
110 int len;
111
112 /* Allow private key to be overridden only if not explicitly
113 * specified at build time.
114 */
115 if ( ALLOW_KEY_OVERRIDE ) {
116
117 /* Restore default private key */
119 sizeof ( private_key.builder ) );
120
121 /* Fetch new private key, if any */
122 free ( key_data );
123 if ( ( len = fetch_raw_setting_copy ( NULL, &privkey_setting,
124 &key_data ) ) >= 0 ) {
125 private_key.builder.data = key_data;
127 }
128 }
129
130 /* Debug */
131 if ( private_key.builder.len ) {
132 DBGC ( &private_key, "PRIVKEY using %s private key:\n",
133 ( key_data ? "external" : "built-in" ) );
136 } else {
137 DBGC ( &private_key, "PRIVKEY has no private key\n" );
138 }
139
140 return 0;
141}
142
143/** Private key settings applicator */
144struct settings_applicator privkey_applicator __settings_applicator = {
145 .apply = privkey_apply_settings,
146};
#define NULL
NULL pointer (VOID *)
Definition Base.h:322
union @162305117151260234136356364136041353210355154177 key
Sense key.
Definition scsi.h:3
__SIZE_TYPE__ size_t
Definition stdint.h:6
ring len
Length.
Definition dwmac.h:226
#define ABS_SYMBOL(name)
Declare an absolute symbol (e.g.
Definition compiler.h:655
#define ABS_VALUE_INIT(name)
Get value of an absolute symbol for use in a static initializer.
Definition compiler.h:668
#define DBGC(...)
Definition compiler.h:505
#define DBGC_HDA(...)
Definition compiler.h:506
#define DHCP_EB_KEY
Client private key.
Definition dhcp.h:423
#define FILE_LICENCE(_licence)
Declare a particular licence as applying to a file.
Definition compiler.h:896
#define FILE_SECBOOT(_status)
Declare a file's UEFI Secure Boot permission status.
Definition compiler.h:926
#define SETTING_CRYPTO
Cryptography settings.
Definition settings.h:80
#define PROGBITS
Definition compiler.h:61
Dynamic Host Configuration Protocol.
Configuration settings.
#define __setting(setting_order, name)
Declare a configuration setting.
Definition settings.h:57
#define __settings_applicator
Declare a settings applicator.
Definition settings.h:265
String functions.
void * memcpy(void *dest, const void *src, size_t len) __nonnull
static struct asn1_cursor default_private_key
Default private key.
Definition privkey.c:77
static int privkey_apply_settings(void)
Apply private key configuration settings.
Definition privkey.c:108
void privkey_free(struct refcnt *refcnt)
Free private key.
Definition privkey.c:95
#define ALLOW_KEY_OVERRIDE
Definition privkey.c:52
__asm__(".section \".rodata\", \"a\", " PROGBITS "\n\t" "\nprivate_key_data:\n\t" ".size private_key_data, ( . - private_key_data )\n\t" ".equ private_key_len, ( . - private_key_data )\n\t" ".previous\n\t")
char private_key_data[]
Private key.
void ref_no_free(struct refcnt *refcnt __unused)
Do not free reference-counted object.
Definition refcnt.c:102
static void(* free)(struct refcnt *refcnt))
Definition refcnt.h:55
#define REF_INIT(free_fn)
Initialise a static reference counter.
Definition refcnt.h:78
int fetch_raw_setting_copy(struct settings *settings, const struct setting *setting, void **data)
Fetch value of setting.
Definition settings.c:822
#define container_of(ptr, type, field)
Get containing structure.
Definition stddef.h:36
void * data
Data.
Definition asn1.h:36
size_t len
Length of data.
Definition asn1.h:38
An ASN.1 object cursor.
Definition asn1.h:21
A private key.
Definition privkey.h:17
struct asn1_builder builder
ASN.1 object builder.
Definition privkey.h:21
A reference counter.
Definition refcnt.h:27
A setting.
Definition settings.h:24
A settings applicator.
Definition settings.h:252
X.509 certificates.