mirror of
https://github.com/yuzu-emu/mbedtls.git
synced 2025-02-02 03:11:13 +00:00
x509: add parse/print support for IPs in SAN
RFC 5280 defines many type of names to be used in the subjectAltName extension of certificate. So far we only supported dNSName, but there is demand for IP addresses too. This is the first step, support for verification will be added in the next commit.
This commit is contained in:
parent
803183f5fe
commit
3ad9437923
|
@ -1318,6 +1318,18 @@
|
|||
*/
|
||||
#define MBEDTLS_X509_RSASSA_PSS_SUPPORT
|
||||
|
||||
/**
|
||||
* \def MBEDTLS_X509_SAN_IP_ADDRESS_SUPPORT
|
||||
*
|
||||
* Enable support for IP addresses (IPv4 and IPv6) in subjectAltName in
|
||||
* certificates. This includes parsing, printing with
|
||||
* \c mbedtls_x509_crt_info(), and verification - see the documentation of
|
||||
* \c mbedtls_x509_crt_verify_with_profile()
|
||||
*
|
||||
* Comment this macro to disallow using IP addresses in
|
||||
*/
|
||||
#define MBEDTLS_X509_SAN_IP_ADDRESS_SUPPORT
|
||||
|
||||
/**
|
||||
* \def MBEDTLS_ZLIB_SUPPORT
|
||||
*
|
||||
|
|
|
@ -414,6 +414,9 @@ static const char *features[] = {
|
|||
#if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT)
|
||||
"MBEDTLS_X509_RSASSA_PSS_SUPPORT",
|
||||
#endif /* MBEDTLS_X509_RSASSA_PSS_SUPPORT */
|
||||
#if defined(MBEDTLS_X509_SAN_IP_ADDRESS_SUPPORT)
|
||||
"MBEDTLS_X509_SAN_IP_ADDRESS_SUPPORT",
|
||||
#endif /* MBEDTLS_X509_SAN_IP_ADDRESS_SUPPORT */
|
||||
#if defined(MBEDTLS_ZLIB_SUPPORT)
|
||||
"MBEDTLS_ZLIB_SUPPORT",
|
||||
#endif /* MBEDTLS_ZLIB_SUPPORT */
|
||||
|
|
|
@ -438,8 +438,13 @@ static int x509_get_ext_key_usage( unsigned char **p,
|
|||
* nameAssigner [0] DirectoryString OPTIONAL,
|
||||
* partyName [1] DirectoryString }
|
||||
*
|
||||
* NOTE: we only parse and use dNSName at this point.
|
||||
* NOTE: we only parse and use dNSName and iPAddress at this point.
|
||||
* NOTE: update x509_info_subject_alt_name() and x509_crt_verify() if and when
|
||||
* adding support for more name types.
|
||||
*/
|
||||
#define X509_CRT_SAN_DNS_NAME 2
|
||||
#define X509_CRT_SAN_IP_ADDRESS 7
|
||||
|
||||
static int x509_get_subject_alt_name( unsigned char **p,
|
||||
const unsigned char *end,
|
||||
mbedtls_x509_sequence *subject_alt_name )
|
||||
|
@ -474,8 +479,17 @@ static int x509_get_subject_alt_name( unsigned char **p,
|
|||
return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS +
|
||||
MBEDTLS_ERR_ASN1_UNEXPECTED_TAG );
|
||||
|
||||
/* Skip everything but DNS name */
|
||||
if( tag != ( MBEDTLS_ASN1_CONTEXT_SPECIFIC | 2 ) )
|
||||
/* Skip everything but DNS name and IP address */
|
||||
#if defined(MBEDTLS_X509_SAN_IP_ADDRESS_SUPPORT)
|
||||
if( tag == ( MBEDTLS_ASN1_CONTEXT_SPECIFIC | X509_CRT_SAN_IP_ADDRESS ) )
|
||||
{
|
||||
/* If IP adress, only valid lengths are 4 and 16 */
|
||||
if( tag_len != 4 && tag_len != 16 )
|
||||
return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS );
|
||||
}
|
||||
else
|
||||
#endif
|
||||
if( tag != ( MBEDTLS_ASN1_CONTEXT_SPECIFIC | X509_CRT_SAN_DNS_NAME ) )
|
||||
{
|
||||
*p += tag_len;
|
||||
continue;
|
||||
|
@ -1213,20 +1227,74 @@ static int x509_info_subject_alt_name( char **buf, size_t *size,
|
|||
const mbedtls_x509_sequence *cur = subject_alt_name;
|
||||
const char *sep = "";
|
||||
size_t sep_len = 0;
|
||||
int ret;
|
||||
|
||||
while( cur != NULL )
|
||||
{
|
||||
if( cur->buf.len + sep_len >= n )
|
||||
if( cur->buf.tag == ( MBEDTLS_ASN1_CONTEXT_SPECIFIC | X509_CRT_SAN_DNS_NAME ) )
|
||||
{
|
||||
*p = '\0';
|
||||
return( MBEDTLS_ERR_X509_BUFFER_TOO_SMALL );
|
||||
}
|
||||
if( cur->buf.len + sep_len >= n )
|
||||
{
|
||||
*p = '\0';
|
||||
return( MBEDTLS_ERR_X509_BUFFER_TOO_SMALL );
|
||||
}
|
||||
|
||||
n -= cur->buf.len + sep_len;
|
||||
for( i = 0; i < sep_len; i++ )
|
||||
*p++ = sep[i];
|
||||
for( i = 0; i < cur->buf.len; i++ )
|
||||
*p++ = cur->buf.p[i];
|
||||
n -= cur->buf.len + sep_len;
|
||||
for( i = 0; i < sep_len; i++ )
|
||||
*p++ = sep[i];
|
||||
for( i = 0; i < cur->buf.len; i++ )
|
||||
*p++ = cur->buf.p[i];
|
||||
}
|
||||
#if defined(MBEDTLS_X509_SAN_IP_ADDRESS_SUPPORT)
|
||||
else if( cur->buf.tag == ( MBEDTLS_ASN1_CONTEXT_SPECIFIC | X509_CRT_SAN_IP_ADDRESS ) )
|
||||
{
|
||||
if( cur->buf.len == 4 )
|
||||
{
|
||||
ret = mbedtls_snprintf( p, n, "%sIP:%d.%d.%d.%d", sep,
|
||||
cur->buf.p[0], cur->buf.p[1],
|
||||
cur->buf.p[2], cur->buf.p[4] );
|
||||
MBEDTLS_X509_SAFE_SNPRINTF;
|
||||
}
|
||||
else if( cur->buf.len == 16 )
|
||||
{
|
||||
if( sep_len + 2 >= n )
|
||||
{
|
||||
*p = '\0';
|
||||
return( MBEDTLS_ERR_X509_BUFFER_TOO_SMALL );
|
||||
}
|
||||
|
||||
memcpy( p, sep, sep_len );
|
||||
p += sep_len;
|
||||
n -= sep_len;
|
||||
|
||||
memcpy( p, "IP", 2 );
|
||||
p += 2;
|
||||
n -= 2;
|
||||
|
||||
for( i = 0; i < 8; i++ )
|
||||
{
|
||||
ret = mbedtls_snprintf( p, n, ":%02x%02x",
|
||||
cur->buf.p[2 * i],
|
||||
cur->buf.p[2 * i + 1] );
|
||||
MBEDTLS_X509_SAFE_SNPRINTF;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = mbedtls_snprintf( p, n, "IP:???" );
|
||||
MBEDTLS_X509_SAFE_SNPRINTF;
|
||||
}
|
||||
}
|
||||
#endif /* MBEDTLS_X509_SAN_IP_ADDRESS_SUPPORT */
|
||||
/*
|
||||
* tag == 0 happens when the extension is present but with only unknow
|
||||
* types: we get a list with one uninitialized element
|
||||
*/
|
||||
else if( cur->buf.tag != 0 )
|
||||
{
|
||||
ret = mbedtls_snprintf( p, n, "???unknown name type???" );
|
||||
MBEDTLS_X509_SAFE_SNPRINTF;
|
||||
}
|
||||
|
||||
sep = ", ";
|
||||
sep_len = 2;
|
||||
|
|
12
tests/data_files/server5-san-ip.crt
Normal file
12
tests/data_files/server5-san-ip.crt
Normal file
|
@ -0,0 +1,12 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIIBrjCCATOgAwIBAgIBUDAKBggqhkjOPQQDAjA+MQswCQYDVQQGEwJOTDERMA8G
|
||||
A1UEChMIUG9sYXJTU0wxHDAaBgNVBAMTE1BvbGFyc3NsIFRlc3QgRUMgQ0EwHhcN
|
||||
MTYwMTI3MTYzNDQzWhcNMjYwMTI0MTYzNDQzWjAPMQ0wCwYDVQQDEwRUZXN0MFkw
|
||||
EwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEN8xW2XYJHlpyPsdZLf8gbu58+QaRdNCt
|
||||
FLX3aCJZYpJO5QDYIxH/6i/SNF1dFr2KiMJrdw1VzYoqDvoByLTt/6NRME8wTQYD
|
||||
VR0RBEYwRIIIZm9vLnRlc3SCCGJhci50ZXN0hwR/AAABhwTAqAAqhxD+gAAAAAAA
|
||||
AAAAAAAAAAABhxASNFZ4mrze8A/ey6mHZUMhMAoGCCqGSM49BAMCA2kAMGYCMQCI
|
||||
TJvNYovxkfjoMcNqHMbrSSNAity3RSqrAA/loKCiw6kpsEOAItjXwxkHj0WH/4kC
|
||||
MQDhdrbfoTxxD6AqNelMlpk2oE4c5ewsA2s53CLICqEy951jw47MqI+LYMmlsS/A
|
||||
T5A=
|
||||
-----END CERTIFICATE-----
|
|
@ -99,8 +99,8 @@ depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_RSA_C
|
|||
x509_cert_info:"data_files/cert_example_multi.crt":"cert. version \: 3\nserial number \: 11\nissuer name \: C=NL, O=PolarSSL, CN=PolarSSL Test CA\nsubject name \: C=NL, O=PolarSSL, CN=www.example.com\nissued on \: 2012-05-10 13\:23\:41\nexpires on \: 2022-05-11 13\:23\:41\nsigned using \: RSA with SHA1\nRSA key size \: 2048 bits\nbasic constraints \: CA=false\nsubject alt name \: example.com, example.net, *.example.org\n"
|
||||
|
||||
X509 Certificate information, Subject Alt Name + Key Usage
|
||||
depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_RSA_C
|
||||
x509_cert_info:"data_files/cert_example_multi_nocn.crt":"cert. version \: 3\nserial number \: F7\:C6\:7F\:F8\:E9\:A9\:63\:F9\nissuer name \: C=NL\nsubject name \: C=NL\nissued on \: 2014-01-22 10\:04\:33\nexpires on \: 2024-01-22 10\:04\:33\nsigned using \: RSA with SHA1\nRSA key size \: 1024 bits\nbasic constraints \: CA=false\nsubject alt name \: www.shotokan-braunschweig.de, www.massimo-abate.eu\nkey usage \: Digital Signature, Non Repudiation, Key Encipherment\n"
|
||||
depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_RSA_C:MBEDTLS_X509_SAN_IP_ADDRESS_SUPPORT
|
||||
x509_cert_info:"data_files/cert_example_multi_nocn.crt":"cert. version \: 3\nserial number \: F7\:C6\:7F\:F8\:E9\:A9\:63\:F9\nissuer name \: C=NL\nsubject name \: C=NL\nissued on \: 2014-01-22 10\:04\:33\nexpires on \: 2024-01-22 10\:04\:33\nsigned using \: RSA with SHA1\nRSA key size \: 1024 bits\nbasic constraints \: CA=false\nsubject alt name \: www.shotokan-braunschweig.de, www.massimo-abate.eu, IP\:192.168.1.135, IP\:192.168.69.48\nkey usage \: Digital Signature, Non Repudiation, Key Encipherment\n"
|
||||
|
||||
X509 Certificate information, Key Usage + Extended Key Usage
|
||||
depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_RSA_C
|
||||
|
@ -118,6 +118,10 @@ X509 Certificate information Bitstring in subject name
|
|||
depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_RSA_C
|
||||
x509_cert_info:"data_files/bitstring-in-dn.pem":"cert. version \: 3\nserial number \: 02\nissuer name \: CN=Test CA 01, ST=Ecnivorp, C=XX, emailAddress=tca@example.com, O=Test CA Authority\nsubject name \: C=XX, O=tca, ST=Ecnivorp, OU=TCA, CN=Client, emailAddress=client@example.com, serialNumber=7101012255, uniqueIdentifier=?7101012255\nissued on \: 2015-03-11 12\:06\:51\nexpires on \: 2025-03-08 12\:06\:51\nsigned using \: RSA with SHA1\nRSA key size \: 2048 bits\nbasic constraints \: CA=false\nsubject alt name \: \next key usage \: TLS Web Client Authentication\n"
|
||||
|
||||
X509 Certificate information SAN with IP
|
||||
depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_ECP_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_X509_SAN_IP_ADDRESS_SUPPORT
|
||||
x509_cert_info:"data_files/server5-san-ip.crt":"cert. version \: 3\nserial number \: 50\nissuer name \: C=NL, O=PolarSSL, CN=Polarssl Test EC CA\nsubject name \: CN=Test\nissued on \: 2016-01-27 16\:34\:43\nexpires on \: 2026-01-24 16\:34\:43\nsigned using \: ECDSA with SHA256\nEC key size \: 256 bits\nsubject alt name \: foo.test, bar.test, IP\:127.0.0.135, IP\:192.168.0.135, IP\:fe80\:0000\:0000\:0000\:0000\:0000\:0000\:0001, IP\:1234\:5678\:9abc\:def0\:0fde\:cba9\:8765\:4321\n"
|
||||
|
||||
X509 certificate v1 with extension
|
||||
depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_RSA_C:MBEDTLS_X509_ALLOW_EXTENSIONS_NON_V3
|
||||
x509_cert_info:"data_files/cert_v1_with_ext.crt":"cert. version \: 1\nserial number \: BD\:ED\:44\:C7\:D2\:3E\:C2\:A4\nissuer name \: C=XX, ST=XX, L=XX, O=XX, OU=XX, emailAddress=admin@identity-check.org, CN=identity-check.org\nsubject name \: C=XX, ST=XX, L=XX, O=XX, OU=XX, emailAddress=admin@identity-check.org, CN=identity-check.org\nissued on \: 2013-07-04 16\:17\:02\nexpires on \: 2014-07-04 16\:17\:02\nsigned using \: RSA with SHA1\nRSA key size \: 2048 bits\nsubject alt name \: identity-check.org, www.identity-check.org\n"
|
||||
|
|
Loading…
Reference in a new issue