Rich Megginson wrote:
> Nelson B wrote:

>> Below, you seem to be asking how they are stored in certificates.
>>
>> I'll answer the questions about what appear in certs.
>>
>>> 1) Are appended ports actually allowed in the subjectAltName or CN?  
>> No.
> 
> How about the return value from SSL_RevealURL( fd ) ?  Will that contain 
> anything except a hostname?

SSL_RevealURL and SSL_SetURL are a pair.  SSL_SetURL makes a copy of the
string it is passed and stores that copy in the SSL socket.  SSL_RevealURL
makes yet another copy of that string in the SSL socket and returns it to
the caller.

The string can contain anything, a host name, a URL, a favorite recipe.

NSS's SSL library uses the string in the SSL socket in just one place.
When the SSL protocol engine receives a certificate chain from the peer
system, it calls an application-supplied callback function to process that
received cert (chain).  The application may supply its own function for
that purpose, or it may choose to use libSSL's own built-in function
SSL_AuthCertificate as that callback function.  If the application does
not supply its own function, libSSL will call SSL_AuthCertificate by
default for that purpose.  So the use of SSL_AuthCertificate is optional.

The application that uses libSSL is free to provide its own function for
the purpose of validating the received cert chain, and if it does so,
it is free to interpret the SSL socket's "url" string any way it chooses,
and/or not use that string at all.

SSL_AuthCertificate uses the url string stored in the SSL socket as the
source of the host name (or IP address string) that it compares to the
contents of the cert.  It passes that string to CERT_VerifyCertName.
In CERT_VerifyCertName, if a SAN is present, the SAN contents are compared
to the string as described below.  Otherwise, the string is used to compare
to the Subject Common Name (if any).

While comparing the string to the SubjectAltName, the string is passed to
PR_StringToNetAddr which attempts to see if it is an IPv4 or IPv6 address
(NOT a DNS name) and if so, attempts to convert it to a binary IP address.
Then, if the SAN contains dNSNAmes, they are compared to the string, and
if the SAN contains iPAddresses, they are compared to the IP address
returned by PR_StringToNetAddr.

AFAIK, PR_StringToNetAddr does not ever expect an IPv6 IP address to
contain brackets.

>>> 2) When an IPv6 literal address is in the CN or the subjectAltName, and 
>>> if the answer to question 1 is that ports are not allowed, then are the 
>>> square brackets that may surround IPv6 addresses still allowed?
>>
>> RFC 2818 only allows IP addresses in SubjectAltNames (SANs), not in
>> Subject name CommonName attributes.
>>
>> As defined in RFC 3280, IP addresses in SANs are stored in binary form as
>> "octet strings", that is, as 4-byte IPv4 or 16-byte IPv6 binary addresses,
>> not as strings of decimal ASCII characters separated by dots, nor
>> hexadecimal ASCII characters separated by colons.  So, you won't see
>> brackets around IP addresses in certificates, because they aren't stored
>> as printable strings in certificates.
> 
> Does that mean we need to convert them to their string representation 
> before we call CERT_VerifyCertName(cert, hostname)?

Short answer: Converting a binary IP address to a string representation,
and passing that string to CERT_VerifyCertName is generally NOT advisable.

Generally, the host name or IP address that the user (or application)
provided (generally in string form) is the authoritative definition of the
server that you're trying to reach, and that's what you want to pass to
CERT_VerifyCertName.

The danger of taking an IP address in binary form and converting it to a
string form, and passing that to CERT_VerifyCertName, is that the binary
form may have come from a DNS lookup (or NIS lookup) and therefore may
already be falsified result.  That is, a "poisoned" DNS or NIS server may
have already given you the wrong IP address, the address of an attacker's
system.  You don't want to verify that the server's cert matches the
attacker-supplied IP address, because the attacker's server's cert will
undoubtedly match the attacker-supplied IP address.  You want to verify
that the server's cert matches the authoritative "name" (host name or IP
address) of the intended server, supplied by the user.  That acts as a
double-check that the DNS/NIS lookup did not send you to a attacker's server.

>> But even though the RFCs define how IP addresses are represented in
>> certificates, I think you'll not find any real CAs that issue certs with
>> IP addresses in them.  There are a lot of reasons for that.  

And now I've stated some of those reasons.  There are still others.

>> And it's
>> not safe to use DNS lookups or reverse DNS lookups as part of the server
>> identity verification process.  So, IMO, your best bet is to compare
>> the host names with the host names in the certs, and leave IP addresses
>> out of the server identity verification picture.

-- 
Nelson B
_______________________________________________
dev-tech-crypto mailing list
dev-tech-crypto@lists.mozilla.org
https://lists.mozilla.org/listinfo/dev-tech-crypto

Reply via email to