Re: ports and ipv6 brackets in certificate subjects

2006-10-06 Thread Rich Megginson

Nelson B wrote:

Rich Megginson wrote:

In the LDAP C SDK code, we call SSL_SetURL with the hostlist argument 
which is passed in to ldapssl_connect().  So I suppose the real fix for 
the ldap c sdk is to make sure we call SSL_SetURL with a simple 
hostname.  


Let me suggest that the "real fix" is for the LDAP C SDK to provide its
own replacement for SSL_AuthCertificate.  That replacement can parse
the string as it chooses, and could (e.g.) pass a part of that string to
CERT_VerifyCertName, or even could invoke CERT_VerifyCertName multiple
times, once per host name in the string.


Yes, we already have our own authcertificate function.  I suppose we 
could parse the list in the authcertificate function, but it seems like 
a waste, since we will only be connected to one server at a time.





I think the hostlist parameter can be formatted like this:
"host:port host:port "  This is set if you attempt to use one of the 
API functions which takes an LDAP URL, which can be in the form

"ldap://host:port host:port ... host:port/"


So, now I think I understand the source of Ulf Weltman's problem.

The functions ldap_x_hostlist_first/ldap_x_hostlist_next are used to 
parse and iterate through these host/port combinations.  I think the 
real problem is that we can't figure out which of these hostnames was 
the one we actually connected to.  In the LDAPSSL case, prldap_connect 
does the hostlist parsing, but it doesn't save the hostname anywhere, so 
I'm not sure how ldapssl_connect() is supposed to figure that out.


If it is true that any of the names in that list would be acceptable to
the client, then you might just try them all, one at a time, until you
find a match or finish the list without finding a match.


Since this logic is already done in prldap_connect, it would be better 
if prldap_connect somehow saved the name of the host connected to 
somewhere for the authcertificate function to grab.  Perhaps it is 
already stored somewhere in the LDAP* structure.


___
dev-tech-crypto mailing list
dev-tech-crypto@lists.mozilla.org
https://lists.mozilla.org/listinfo/dev-tech-crypto


Re: ports and ipv6 brackets in certificate subjects

2006-10-06 Thread Nelson B
Rich Megginson wrote:

> In the LDAP C SDK code, we call SSL_SetURL with the hostlist argument 
> which is passed in to ldapssl_connect().  So I suppose the real fix for 
> the ldap c sdk is to make sure we call SSL_SetURL with a simple 
> hostname.  

Let me suggest that the "real fix" is for the LDAP C SDK to provide its
own replacement for SSL_AuthCertificate.  That replacement can parse
the string as it chooses, and could (e.g.) pass a part of that string to
CERT_VerifyCertName, or even could invoke CERT_VerifyCertName multiple
times, once per host name in the string.

> I think the hostlist parameter can be formatted like this:
> "host:port host:port "  This is set if you attempt to use one of the 
> API functions which takes an LDAP URL, which can be in the form
> "ldap://host:port host:port ... host:port/"

So, now I think I understand the source of Ulf Weltman's problem.

> The functions ldap_x_hostlist_first/ldap_x_hostlist_next are used to 
> parse and iterate through these host/port combinations.  I think the 
> real problem is that we can't figure out which of these hostnames was 
> the one we actually connected to.  In the LDAPSSL case, prldap_connect 
> does the hostlist parsing, but it doesn't save the hostname anywhere, so 
> I'm not sure how ldapssl_connect() is supposed to figure that out.

If it is true that any of the names in that list would be acceptable to
the client, then you might just try them all, one at a time, until you
find a match or finish the list without finding a match.

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


Re: ports and ipv6 brackets in certificate subjects

2006-10-06 Thread Nelson B
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 ide