571
574
- Ensure that ASN1 strings from the certificate are encoded as
572
575
UTF-8 which can be meaningfully compared to HOST. */
574
X509_NAME *xname = X509_get_subject_name(cert);
575
common_name[0] = '\0';
576
X509_NAME_get_text_by_NID (xname, NID_commonName, common_name,
577
sizeof (common_name));
577
subjectAltNames = X509_get_ext_d2i (cert, NID_subject_alt_name, NULL, NULL);
579
if (!pattern_match (common_name, host))
581
logprintf (LOG_NOTQUIET, _("\
582
%s: certificate common name %s doesn't match requested host name %s.\n"),
583
severity, quote_n (0, common_name), quote_n (1, host));
581
/* Test subject alternative names */
583
/* Do we want to check for dNSNAmes or ipAddresses (see RFC 2818)?
584
* Signal it by host_in_octet_string. */
585
ASN1_OCTET_STRING *host_in_octet_string = a2i_IPADDRESS (host);
587
int numaltnames = sk_GENERAL_NAME_num (subjectAltNames);
589
for (i=0; i < numaltnames; i++)
591
const GENERAL_NAME *name =
592
sk_GENERAL_NAME_value (subjectAltNames, i);
595
if (host_in_octet_string)
597
if (name->type == GEN_IPADD)
599
/* Check for ipAddress */
600
/* TODO: Should we convert between IPv4-mapped IPv6
601
* addresses and IPv4 addresses? */
602
alt_name_checked = true;
603
if (!ASN1_STRING_cmp (host_in_octet_string,
608
else if (name->type == GEN_DNS)
610
/* dNSName should be IA5String (i.e. ASCII), however who
611
* does trust CA? Convert it into UTF-8 for sure. */
612
unsigned char *name_in_utf8 = NULL;
614
/* Check for dNSName */
615
alt_name_checked = true;
617
if (0 <= ASN1_STRING_to_UTF8 (&name_in_utf8, name->d.dNSName))
619
/* Compare and check for NULL attack in ASN1_STRING */
620
if (pattern_match ((char *)name_in_utf8, host) &&
621
(strlen ((char *)name_in_utf8) ==
622
ASN1_STRING_length (name->d.dNSName)))
624
OPENSSL_free (name_in_utf8);
627
OPENSSL_free (name_in_utf8);
632
sk_GENERAL_NAME_free (subjectAltNames);
633
if (host_in_octet_string)
634
ASN1_OCTET_STRING_free(host_in_octet_string);
636
if (alt_name_checked == true && i >= numaltnames)
638
logprintf (LOG_NOTQUIET,
639
_("%s: no certificate subject alternative name matches\n"
640
"\trequested host name %s.\n"),
641
severity, quote_n (1, host));
646
if (alt_name_checked == false)
588
/* We now determine the length of the ASN1 string. If it differs from
589
* common_name's length, then there is a \0 before the string terminates.
590
* This can be an instance of a null-prefix attack.
592
* https://www.blackhat.com/html/bh-usa-09/bh-usa-09-archives.html#Marlinspike
596
X509_NAME_ENTRY *xentry;
602
j = X509_NAME_get_index_by_NID (xname, NID_commonName, i);
648
/* Test commomName */
649
X509_NAME *xname = X509_get_subject_name(cert);
650
common_name[0] = '\0';
651
X509_NAME_get_text_by_NID (xname, NID_commonName, common_name,
652
sizeof (common_name));
654
if (!pattern_match (common_name, host))
656
logprintf (LOG_NOTQUIET, _("\
657
%s: certificate common name %s doesn't match requested host name %s.\n"),
658
severity, quote_n (0, common_name), quote_n (1, host));
663
/* We now determine the length of the ASN1 string. If it
664
* differs from common_name's length, then there is a \0
665
* before the string terminates. This can be an instance of a
666
* null-prefix attack.
668
* https://www.blackhat.com/html/bh-usa-09/bh-usa-09-archives.html#Marlinspike
672
X509_NAME_ENTRY *xentry;
678
j = X509_NAME_get_index_by_NID (xname, NID_commonName, i);
608
xentry = X509_NAME_get_entry(xname,i);
609
sdata = X509_NAME_ENTRY_get_data(xentry);
610
if (strlen (common_name) != ASN1_STRING_length (sdata))
612
logprintf (LOG_NOTQUIET, _("\
613
%s: certificate common name is invalid (contains a NUL character).\n\
614
This may be an indication that the host is not who it claims to be\n\
615
(that is, it is not the real %s).\n"),
616
severity, quote (host));
684
xentry = X509_NAME_get_entry(xname,i);
685
sdata = X509_NAME_ENTRY_get_data(xentry);
686
if (strlen (common_name) != ASN1_STRING_length (sdata))
688
logprintf (LOG_NOTQUIET, _("\
689
%s: certificate common name is invalid (contains a NUL character).\n\
690
This may be an indication that the host is not who it claims to be\n\
691
(that is, it is not the real %s).\n"),
692
severity, quote (host));