mirror of
https://github.com/yuzu-emu/mbedtls.git
synced 2025-07-01 19:58:22 +00:00
x509: implement verification of IPs in SAN
This commit is contained in:
parent
47f71d49c4
commit
9855d63acb
|
@ -314,7 +314,16 @@ int mbedtls_x509_crt_verify( mbedtls_x509_crt *crt,
|
||||||
* for ECDSA) apply to all certificates: trusted root,
|
* for ECDSA) apply to all certificates: trusted root,
|
||||||
* intermediate CAs if any, and end entity certificate.
|
* intermediate CAs if any, and end entity certificate.
|
||||||
*
|
*
|
||||||
* \note TODO: IP addresses in exp_name
|
* \note If MBEDTLS_X509_SAN_IP_ADDRESS_SUPPORT is enabled, instead
|
||||||
|
* of a DNS name, exp_name can also contain the string "IP:"
|
||||||
|
* followed by an IP address. This address must be either an
|
||||||
|
* IPv4 address in dotted decimal notation, or an IPv6
|
||||||
|
* address consisting of exactly 8 groups of 4 hexadecimal
|
||||||
|
* digits separated by colons. For example, if the expected
|
||||||
|
* IPv6 is fe80::1, then exp_name must be the string
|
||||||
|
* "IP:fe80:0000:0000:0000:0000:0000:0000:0001" or its
|
||||||
|
* uppercase equivalent. If the expected IPv4 is 127.0.0.1,
|
||||||
|
* then exp_name should be "IP:127.0.0.1".
|
||||||
*
|
*
|
||||||
* \return 0 if successful or MBEDTLS_ERR_X509_CERT_VERIFY_FAILED
|
* \return 0 if successful or MBEDTLS_ERR_X509_CERT_VERIFY_FAILED
|
||||||
* in which case *flags will have one or more
|
* in which case *flags will have one or more
|
||||||
|
|
|
@ -1796,7 +1796,7 @@ static int x509_memcasecmp( const void *s1, const void *s2, size_t len )
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Return 0 if names matche as DNS names (inc. wildcard),
|
* Return 0 if names match as DNS names (inc. wildcard),
|
||||||
* -1 otherwise
|
* -1 otherwise
|
||||||
*/
|
*/
|
||||||
static int x509_check_dns_name( const char *exp_name,
|
static int x509_check_dns_name( const char *exp_name,
|
||||||
|
@ -2229,13 +2229,79 @@ int mbedtls_x509_crt_verify( mbedtls_x509_crt *crt,
|
||||||
exp_name, flags, f_vrfy, p_vrfy ) );
|
exp_name, flags, f_vrfy, p_vrfy ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_X509_SAN_IP_ADDRESS_SUPPORT)
|
||||||
/*
|
/*
|
||||||
* Verify that the certificate matches wit the expected name
|
* Return 0 if exp_name and name contain the same IP address,
|
||||||
|
* -1 otherwise.
|
||||||
|
*
|
||||||
|
* exp_name must be "IP:" followed by either an IPv4 addres in dotted-quad
|
||||||
|
* notation, or an IPv6 address with no shortcuts and all leading zeros.
|
||||||
|
*
|
||||||
|
* name contains the IP as an octet string
|
||||||
|
*/
|
||||||
|
static int x509_check_ip_address( const char *exp_name,
|
||||||
|
size_t exp_len,
|
||||||
|
const mbedtls_x509_buf *name )
|
||||||
|
{
|
||||||
|
/* Print IPv6 addresses with a leading colon for convenience, so
|
||||||
|
* we have 32 hex digits, 8 colons, plus terminating NULL */
|
||||||
|
char ip[32 + 8 + 1];
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if( name->len == 4 )
|
||||||
|
{
|
||||||
|
ret = mbedtls_snprintf( ip, sizeof( ip ), "%d.%d.%d.%d",
|
||||||
|
name->p[0], name->p[1], name->p[2], name->p[3] );
|
||||||
|
|
||||||
|
if( ret < 0 || (size_t) ret > sizeof( ip ) )
|
||||||
|
return( -1 );
|
||||||
|
|
||||||
|
if( (size_t) ret + 3 == exp_len &&
|
||||||
|
memcmp( ip, exp_name + 3, exp_len - 3 ) == 0 )
|
||||||
|
{
|
||||||
|
return( 0 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if( name->len == 16 )
|
||||||
|
{
|
||||||
|
size_t i, n;
|
||||||
|
char *p;
|
||||||
|
|
||||||
|
/* "IP:" + 32 hex digits + 7 colons */
|
||||||
|
if( exp_len != 3 + 32 + 7 )
|
||||||
|
return( -1 );
|
||||||
|
|
||||||
|
for( i = 0, n = sizeof( ip ), p = ip;
|
||||||
|
i < 16;
|
||||||
|
i += 2, n -= 5, p += 5 )
|
||||||
|
{
|
||||||
|
ret = mbedtls_snprintf( p, n, ":%02x%02x",
|
||||||
|
name->p[i], name->p[i+1] );
|
||||||
|
if( ret < 0 || (size_t) ret > n )
|
||||||
|
return( -1 );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( x509_memcasecmp( ip + 1, exp_name + 3, exp_len - 3 ) == 0 )
|
||||||
|
return( 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
return( -1 );
|
||||||
|
}
|
||||||
|
#endif /* MBEDTLS_X509_SAN_IP_ADDRESS_SUPPORT */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Verify that the certificate matches with the expected name
|
||||||
*/
|
*/
|
||||||
static int x509_crt_verify_name( const mbedtls_x509_crt *crt,
|
static int x509_crt_verify_name( const mbedtls_x509_crt *crt,
|
||||||
const char *exp_name )
|
const char *exp_name )
|
||||||
{
|
{
|
||||||
const size_t exp_len = strlen( exp_name );
|
const size_t exp_len = strlen( exp_name );
|
||||||
|
unsigned char exp_tag = X509_CRT_SAN_TAG_DNS_NAME;
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_X509_SAN_IP_ADDRESS_SUPPORT)
|
||||||
|
if( exp_len >= 3 && memcmp( exp_name, "IP:", 3 ) == 0 )
|
||||||
|
exp_tag = X509_CRT_SAN_TAG_IP_ADDRESS;
|
||||||
|
#endif
|
||||||
|
|
||||||
if( crt->ext_types & MBEDTLS_X509_EXT_SUBJECT_ALT_NAME )
|
if( crt->ext_types & MBEDTLS_X509_EXT_SUBJECT_ALT_NAME )
|
||||||
{
|
{
|
||||||
|
@ -2243,11 +2309,26 @@ static int x509_crt_verify_name( const mbedtls_x509_crt *crt,
|
||||||
|
|
||||||
for( cur = &crt->subject_alt_names; cur != NULL; cur = cur->next )
|
for( cur = &crt->subject_alt_names; cur != NULL; cur = cur->next )
|
||||||
{
|
{
|
||||||
if( x509_check_dns_name( exp_name, exp_len, &cur->buf ) == 0 )
|
if( cur->buf.tag != exp_tag )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if( exp_tag == X509_CRT_SAN_TAG_DNS_NAME &&
|
||||||
|
x509_check_dns_name( exp_name, exp_len, &cur->buf ) == 0 )
|
||||||
|
{
|
||||||
return( 0 );
|
return( 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_X509_SAN_IP_ADDRESS_SUPPORT)
|
||||||
|
if( exp_tag == X509_CRT_SAN_TAG_IP_ADDRESS &&
|
||||||
|
x509_check_ip_address( exp_name, exp_len, &cur->buf ) == 0 )
|
||||||
|
{
|
||||||
|
return( 0 );
|
||||||
}
|
}
|
||||||
else
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* Only DNS names can match the Common Name */
|
||||||
|
else if( exp_tag == X509_CRT_SAN_TAG_DNS_NAME )
|
||||||
{
|
{
|
||||||
const mbedtls_x509_name *cur;
|
const mbedtls_x509_name *cur;
|
||||||
|
|
||||||
|
|
|
@ -703,6 +703,26 @@ X509 Certificate verification #81 (multiple CRLs, none relevant)
|
||||||
depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_ECDSA_C:MBEDTLS_ECP_DP_SECP384R1_ENABLED:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_SHA256_C:MBEDTLS_RSA_C
|
depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_ECDSA_C:MBEDTLS_ECP_DP_SECP384R1_ENABLED:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_SHA256_C:MBEDTLS_RSA_C
|
||||||
x509_verify:"data_files/enco-cert-utf8str.pem":"data_files/enco-ca-prstr.pem":"data_files/crl_cat_rsa-ec.pem":"NULL":0:0:"NULL"
|
x509_verify:"data_files/enco-cert-utf8str.pem":"data_files/enco-ca-prstr.pem":"data_files/crl_cat_rsa-ec.pem":"NULL":0:0:"NULL"
|
||||||
|
|
||||||
|
X509 Certificate verification #82 (SAN with IP, IPv4, OK)
|
||||||
|
depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_ECDSA_C:MBEDTLS_ECP_DP_SECP384R1_ENABLED:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_SHA256_C:MBEDTLS_X509_SAN_IP_ADDRESS_SUPPORT
|
||||||
|
x509_verify:"data_files/server5-san-ip.crt":"data_files/test-ca2.crt":"data_files/crl-ec-sha256.pem":"IP\:192.168.0.42":0:0:"NULL"
|
||||||
|
|
||||||
|
X509 Certificate verification #83 (SAN with IP, IPv4, bad)
|
||||||
|
depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_ECDSA_C:MBEDTLS_ECP_DP_SECP384R1_ENABLED:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_SHA256_C:MBEDTLS_X509_SAN_IP_ADDRESS_SUPPORT
|
||||||
|
x509_verify:"data_files/server5-san-ip.crt":"data_files/test-ca2.crt":"data_files/crl-ec-sha256.pem":"IP\:192.168.0.24":MBEDTLS_ERR_X509_CERT_VERIFY_FAILED:MBEDTLS_X509_BADCERT_CN_MISMATCH:"NULL"
|
||||||
|
|
||||||
|
X509 Certificate verification #84 (SAN with IP, IPv6, OK)
|
||||||
|
depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_ECDSA_C:MBEDTLS_ECP_DP_SECP384R1_ENABLED:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_SHA256_C:MBEDTLS_X509_SAN_IP_ADDRESS_SUPPORT
|
||||||
|
x509_verify:"data_files/server5-san-ip.crt":"data_files/test-ca2.crt":"data_files/crl-ec-sha256.pem":"IP\:FE80\:0000\:0000\:0000\:0000\:0000\:0000\:0001":0:0:"NULL"
|
||||||
|
|
||||||
|
X509 Certificate verification #85 (SAN with IP, IPv6, bad)
|
||||||
|
depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_ECDSA_C:MBEDTLS_ECP_DP_SECP384R1_ENABLED:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_SHA256_C:MBEDTLS_X509_SAN_IP_ADDRESS_SUPPORT
|
||||||
|
x509_verify:"data_files/server5-san-ip.crt":"data_files/test-ca2.crt":"data_files/crl-ec-sha256.pem":"IP\:FE80\:0000\:0000\:0000\:0000\:0000\:0000\:0002":MBEDTLS_ERR_X509_CERT_VERIFY_FAILED:MBEDTLS_X509_BADCERT_CN_MISMATCH:"NULL"
|
||||||
|
|
||||||
|
X509 Certificate verification #86 (IP without SAN, bad)
|
||||||
|
depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_ECDSA_C:MBEDTLS_ECP_DP_SECP384R1_ENABLED:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_SHA256_C:MBEDTLS_X509_SAN_IP_ADDRESS_SUPPORT
|
||||||
|
x509_verify:"data_files/server5.crt":"data_files/test-ca2.crt":"data_files/crl-ec-sha256.pem":"IP\:FE80\:0000\:0000\:0000\:0000\:0000\:0000\:0001":MBEDTLS_ERR_X509_CERT_VERIFY_FAILED:MBEDTLS_X509_BADCERT_CN_MISMATCH:"NULL"
|
||||||
|
|
||||||
X509 Certificate verification callback: trusted EE cert
|
X509 Certificate verification callback: trusted EE cert
|
||||||
depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_ECDSA_C:MBEDTLS_SHA256_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED
|
depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_ECDSA_C:MBEDTLS_SHA256_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED
|
||||||
x509_verify_callback:"data_files/server5-selfsigned.crt":"data_files/server5-selfsigned.crt":0:"depth 0 - serial 53\:A2\:CB\:4B\:12\:4E\:AD\:83\:7D\:A8\:94\:B2 - subject CN=selfsigned, OU=testing, O=PolarSSL, C=NL\n"
|
x509_verify_callback:"data_files/server5-selfsigned.crt":"data_files/server5-selfsigned.crt":0:"depth 0 - serial 53\:A2\:CB\:4B\:12\:4E\:AD\:83\:7D\:A8\:94\:B2 - subject CN=selfsigned, OU=testing, O=PolarSSL, C=NL\n"
|
||||||
|
|
Loading…
Reference in a new issue