mirror of
				https://github.com/xcat2/xNBA.git
				synced 2025-11-04 05:12:33 +00:00 
			
		
		
		
	[crypto] Allow client certificate to be changed without a rebuild
Signed-off-by: Michael Brown <mcb30@ipxe.org>
This commit is contained in:
		@@ -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
 | 
			
		||||
@@ -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[];
 | 
			
		||||
@@ -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,
 | 
			
		||||
};
 | 
			
		||||
 
 | 
			
		||||
@@ -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
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user