Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
[crypto] Allow client certificate to be changed without a rebuild
Signed-off-by: Michael Brown <mcb30@ipxe.org>
  • Loading branch information
mcb30 committed Apr 24, 2012
1 parent 0e59417 commit 63d9cc2
Show file tree
Hide file tree
Showing 2 changed files with 98 additions and 9 deletions.
101 changes: 92 additions & 9 deletions src/crypto/clientcert.c
Expand Up @@ -19,6 +19,10 @@
FILE_LICENCE ( GPL2_OR_LATER );

#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <ipxe/dhcp.h>
#include <ipxe/settings.h>
#include <ipxe/clientcert.h>

/** @file
Expand Down Expand Up @@ -55,12 +59,6 @@ __asm__ ( ".section \".rodata\", \"a\", @progbits\n\t"
".equ client_certificate_len, ( . - client_certificate_data )\n\t"
".previous\n\t" );

/** Client certificate */
struct client_certificate client_certificate = {
.data = client_certificate_data,
.len = ( ( size_t ) client_certificate_len ),
};

/* Raw client private key data */
extern char client_private_key_data[];
extern char client_private_key_len[];
Expand All @@ -73,8 +71,93 @@ __asm__ ( ".section \".rodata\", \"a\", @progbits\n\t"
".equ client_private_key_len, ( . - client_private_key_data )\n\t"
".previous\n\t" );

/** Client certificate */
struct client_certificate client_certificate;

/** Client private key */
struct client_private_key client_private_key = {
.data = client_private_key_data,
.len = ( ( size_t ) client_private_key_len ),
struct client_private_key client_private_key;

/** Client certificate setting */
struct setting cert_setting __setting ( SETTING_CRYPTO ) = {
.name = "cert",
.description = "Client certificate",
.tag = DHCP_EB_CERT,
.type = &setting_type_hex,
};

/** Client private key setting */
struct setting key_setting __setting ( SETTING_CRYPTO ) = {
.name = "key",
.description = "Client private key",
.tag = DHCP_EB_KEY,
.type = &setting_type_hex,
};

/**
* Apply client certificate store configuration settings
*
* @ret rc Return status code
*/
static int clientcert_apply_settings ( void ) {
static void *cert;
static void *key;
int len;
int rc;

/* Restore default client certificate */
client_certificate.data = client_certificate_data;
client_certificate.len = ( ( size_t ) client_certificate_len );

/* Fetch new client certificate, if any */
free ( cert );
len = fetch_setting_copy ( NULL, &cert_setting, &cert );
if ( len < 0 ) {
rc = len;
DBGC ( &client_certificate, "CLIENTCERT cannot fetch client "
"certificate: %s\n", strerror ( rc ) );
return rc;
}
if ( cert ) {
client_certificate.data = cert;
client_certificate.len = len;
}

/* Restore default client private key */
client_private_key.data = client_private_key_data;
client_private_key.len = ( ( size_t ) client_private_key_len );

/* Fetch new client private key, if any */
free ( key );
len = fetch_setting_copy ( NULL, &key_setting, &key );
if ( len < 0 ) {
rc = len;
DBGC ( &client_certificate, "CLIENTCERT cannot fetch client "
"private key: %s\n", strerror ( rc ) );
return rc;
}
if ( key ) {
client_private_key.data = key;
client_private_key.len = len;
}

/* Debug */
if ( have_client_certificate() ) {
DBGC ( &client_certificate, "CLIENTCERT using %s "
"certificate:\n", ( cert ? "external" : "built-in" ) );
DBGC_HDA ( &client_certificate, 0, client_certificate.data,
client_certificate.len );
DBGC ( &client_certificate, "CLIENTCERT using %s private "
"key:\n", ( key ? "external" : "built-in" ) );
DBGC_HDA ( &client_certificate, 0, client_private_key.data,
client_private_key.len );
} else {
DBGC ( &client_certificate, "CLIENTCERT has no certificate\n" );
}

return 0;
}

/** Client certificate store settings applicator */
struct settings_applicator clientcert_applicator __settings_applicator = {
.apply = clientcert_apply_settings,
};
6 changes: 6 additions & 0 deletions src/include/ipxe/dhcp.h
Expand Up @@ -358,6 +358,12 @@ struct dhcp_client_uuid {
/** Trusted root certficate fingerprints */
#define DHCP_EB_TRUST DHCP_ENCAP_OPT ( DHCP_EB_ENCAP, 0x5a )

/** Client certficate */
#define DHCP_EB_CERT DHCP_ENCAP_OPT ( DHCP_EB_ENCAP, 0x5b )

/** Client private key */
#define DHCP_EB_KEY DHCP_ENCAP_OPT ( DHCP_EB_ENCAP, 0x5c )

/** Skip PXE DHCP protocol extensions such as ProxyDHCP
*
* If set to a non-zero value, iPXE will not wait for ProxyDHCP offers
Expand Down

0 comments on commit 63d9cc2

Please sign in to comment.