[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:
Michael Brown
2014-07-11 16:55:14 +01:00
parent 5365340e77
commit 8484e97f7c
3 changed files with 105 additions and 40 deletions

View File

@@ -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 );