From af49713640bf6f077be391b15643d543842804c2 Mon Sep 17 00:00:00 2001 From: Jarrod Johnson Date: Wed, 9 Jul 2014 15:41:06 -0400 Subject: [PATCH] Add support for iPAddress in subjectaltname --- src/crypto/x509.c | 43 +++++++++++++++++++++++++++++++++++++++++ src/include/ipxe/x509.h | 1 + 2 files changed, 44 insertions(+) diff --git a/src/crypto/x509.c b/src/crypto/x509.c index 0502efa2..c933fa99 100644 --- a/src/crypto/x509.c +++ b/src/crypto/x509.c @@ -33,6 +33,8 @@ FILE_LICENCE ( GPL2_OR_LATER ); #include #include #include +#include +#include #include #include @@ -1417,6 +1419,45 @@ 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 ) { + size_t len = raw->len; + struct sockaddr sa; + if ( sock_aton ( name, &sa ) != 0 ) { + DBGC2( cert, "Name \"%s\" did not resemble a numeric address, skipping", name ); + return -ENOENT; + } + if ( sa.sa_family == AF_INET ) { + struct sockaddr_in *sin = ( ( struct sockaddr_in * ) &sa ); + if ( len != 4 ) { + DBGC2( cert, "\"%s\" is IPv4, but certificate iPAddress is not IPv4", name ); + return -ENOENT; + } + if ( memcmp ( raw->data, & ( sin->sin_addr.s_addr ), len ) == 0 ) { + return 0; + } + } else if ( sa.sa_family == AF_INET6 ) { + struct sockaddr_in6 *sin6 = ( ( struct sockaddr_in6 * ) &sa ); + if ( len != 16 ) { + DBGC2( cert, "\"%s\" is IPv6, but certificate iPAddress is not IPv6", name ); + return -ENOENT; + } + if ( memcmp ( raw->data, sin6->sin6_addr.s6_addr16, 16 ) == 0) { + return 0; + } + } + return -ENOENT; +} + /** * Check X.509 certificate alternative name * @@ -1440,6 +1481,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 ); diff --git a/src/include/ipxe/x509.h b/src/include/ipxe/x509.h index 055a4460..802480e5 100644 --- a/src/include/ipxe/x509.h +++ b/src/include/ipxe/x509.h @@ -146,6 +146,7 @@ struct x509_subject_alt_name { enum x509_general_name_types { X509_GENERAL_NAME_DNS = ASN1_IMPLICIT_TAG ( 2 ), X509_GENERAL_NAME_URI = ASN1_IMPLICIT_TAG ( 6 ), + X509_GENERAL_NAME_IP = ASN1_IMPLICIT_TAG ( 7 ), }; /** An X.509 certificate extensions set */