mirror of
https://github.com/ipxe/ipxe
synced 2025-12-16 01:21:10 +03:00
[crypto] Add support for iPAddress subject alternative names
Originally-implemented-by: Jarrod Johnson <jarrod.b.johnson@gmail.com> Signed-off-by: Michael Brown <mcb30@ipxe.org>
This commit is contained in:
@@ -33,6 +33,8 @@ FILE_LICENCE ( GPL2_OR_LATER );
|
||||
#include <ipxe/rsa.h>
|
||||
#include <ipxe/rootcert.h>
|
||||
#include <ipxe/certstore.h>
|
||||
#include <ipxe/socket.h>
|
||||
#include <ipxe/in.h>
|
||||
#include <ipxe/x509.h>
|
||||
#include <config/crypto.h>
|
||||
|
||||
@@ -1417,6 +1419,57 @@ static int x509_check_dnsname ( struct x509_certificate *cert,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check X.509 certificate alternative iPAddress
|
||||
*
|
||||
* @v cert X.509 certificate
|
||||
* @v raw ASN.1 cursor
|
||||
* @v name Name
|
||||
* @ret rc Return status code
|
||||
*/
|
||||
static int x509_check_ipaddress ( struct x509_certificate *cert,
|
||||
const struct asn1_cursor *raw,
|
||||
const char *name ) {
|
||||
struct sockaddr sa;
|
||||
sa_family_t family;
|
||||
const void *address;
|
||||
int rc;
|
||||
|
||||
/* Determine address family */
|
||||
if ( raw->len == sizeof ( struct in_addr ) ) {
|
||||
struct sockaddr_in *sin = ( ( struct sockaddr_in * ) &sa );
|
||||
family = AF_INET;
|
||||
address = &sin->sin_addr;
|
||||
} else if ( raw->len == sizeof ( struct in6_addr ) ) {
|
||||
struct sockaddr_in6 *sin6 = ( ( struct sockaddr_in6 * ) &sa );
|
||||
family = AF_INET6;
|
||||
address = &sin6->sin6_addr;
|
||||
} else {
|
||||
DBGC ( cert, "X509 %p \"%s\" has iPAddress with unexpected "
|
||||
"length %zd\n", cert, x509_name ( cert ), raw->len );
|
||||
DBGC_HDA ( cert, 0, raw->data, raw->len );
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Attempt to convert name to a socket address */
|
||||
if ( ( rc = sock_aton ( name, &sa ) ) != 0 ) {
|
||||
DBGC2 ( cert, "X509 %p \"%s\" cannot parse \"%s\" as "
|
||||
"iPAddress: %s\n", cert, x509_name ( cert ), name,
|
||||
strerror ( rc ) );
|
||||
return rc;
|
||||
}
|
||||
if ( sa.sa_family != family )
|
||||
return -ENOENT;
|
||||
|
||||
/* Compare addresses */
|
||||
if ( memcmp ( address, raw->data, raw->len ) != 0 )
|
||||
return -ENOENT;
|
||||
|
||||
DBGC2 ( cert, "X509 %p \"%s\" found iPAddress match for \"%s\"\n",
|
||||
cert, x509_name ( cert ), sock_ntoa ( &sa ) );
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check X.509 certificate alternative name
|
||||
*
|
||||
@@ -1440,6 +1493,8 @@ static int x509_check_alt_name ( struct x509_certificate *cert,
|
||||
switch ( type ) {
|
||||
case X509_GENERAL_NAME_DNS :
|
||||
return x509_check_dnsname ( cert, &alt_name, name );
|
||||
case X509_GENERAL_NAME_IP :
|
||||
return x509_check_ipaddress ( cert, &alt_name, name );
|
||||
default:
|
||||
DBGC2 ( cert, "X509 %p \"%s\" unknown name of type %#02x:\n",
|
||||
cert, x509_name ( cert ), type );
|
||||
|
||||
Reference in New Issue
Block a user