[cryptography] "best practices" for hostname validation when using JSSE

Patrick Pelletier code at funwithsoftware.org
Sat Aug 10 01:50:18 EDT 2013


On Aug 9, 2013, at 12:49 PM, Tim Dierks wrote:

> I added a comment on your Stack Overflow post (incorrectly closed,  
> IMHO, but the SO crowd can be prickly).

Thanks!  This was my first attempt at using Stack Overflow.

> The right thing to do depends on knowing a couple more details:
>  1. Where are you getting your certificates?

To be determined, mostly.  Right now, I'm just generating them on my  
desktop with gnoMint.  The deployment has yet to be ironed out.  (I'm  
just writing a library, and the actual applications that use it will  
be written by others in our company.)  We definitely don't plan on  
using commercial CAs, though!  Either our company would act as a CA  
for all of our customers, or else each customer would act as a CA for  
themselves.  (In the latter case, though, we still want customers to  
be able to talk to each other, so they would have to install each  
other's trust roots.  Although then one customer could in theory MITM  
another customer, which seems bad.  I suppose that we're running up  
against Zooko's triangle, though, in that in order to be secure, we  
either need a centralized CA, or else we'd need to move away from  
domain names and use something like a hash of the public key.  Ugh.)   
But either way, the number of trust roots will be very limited.

I suppose we could switch to a system like trust-on-first-use, which  
would be much less hassle for the users, but then it would be easy to  
MITM as long as the MITM is in place ahead of time.

>  2. What's the best way to name the servers you trust?

I think DNS is best.  We identify servers via a URI-like string (e. g.  
"foo://example.com/bar/whatever"), so the advantage of using the DNS  
name is that we are validating information that is already contained  
in the URI.  If we used some other sort of identifier, then the user  
would need to communicate that identifier in addition to the  
hostname.  (But see previous lament about Zooko's triangle.  I suppose  
we could adopt a syntax like "foo://HashOfPublicKey@example.com/bar/ 
whatever", to avoid needing a centralized CA, but users would probably  
complain about typing in ugly hex strings.)

> Since you have a proprietary protocol, the easiest thing to do is  
> make sure the cert chains up to a root you trust (ideally not system- 
> installed roots, because nobody knows how deep the sewage flows there 
> —the only exception would be if you want to delegate trust issues to  
> a user of your software who might be expected to manage their own  
> trustpoints using system configuration tools, but that gives me the  
> willies).

Yeah, I plan on using JSSE's ability to validate the certificate  
chain, except I'll give it a custom set of trust roots instead of the  
"standard" ones.  That's one reason I'm leaning toward JSSE instead of  
BouncyCastle, since BouncyCastle lacks certificate chain validation in  
addition to hostname validation, while JSSE has certificate chain  
validation and only lacks hostname validation.

> Then make sure the name on the cert matches the name of who you  
> think you're communicating with (could be DNS name, or some other  
> identification of the entity); if you may want to use SSL libraries  
> which check certs and which are designed for HTTPS, you probably  
> want to use the DNS name.

Yeah, I think that modeling the validation on HTTPS makes sense, even  
though it isn't HTTPS.  That's what I'm already doing in the C  
implementation.  (Since I did this in C several months ago, and now  
I'm doing it in Java.)  I went through pretty much this same thing  
back then, since OpenSSL doesn't validate hostnames, either.  I ended  
up using some sample code from the 2002 O'Reilly book "Network  
Security with OpenSSL" by Viega/Messier/Chandra to do hostname  
validation, although I'm thinking about switching to the hostname  
validation code published by iSecPartners in conjunction with the  
"Most Dangerous Code in the World" paper.  Either way, though, neither  
of those validation routines handle wildcards.

I'm not sure yet whether we'll need wildcards.  We're getting along  
fine without them so far.  But if we end up acting as a CA, it might  
be convenient to just issue each customer a wildcard certificate for  
their domain, and let them install it on as many servers as they want,  
rather than us having to get involved every time they add or rename a  
server.  In which case, I'd need to revisit the C implementation and  
add wildcard support.

> I don't know enough about JSSE-specific implementation to be able to  
> give you a precise answer.

Bruno on Stack Overflow gave an answer that works on Java 7:

http://stackoverflow.com/a/17979954/372643

but since I need a solution that's more portable than that, I think  
I'll just proceed with my original plan of adapting some code from  
Apache HttpComponents.  I just wanted to run it by some experienced  
people and see if anyone said, "No, that's crazy!" or "Here, try my  
library that already does that."

Thanks for all your input and support,

--Patrick



More information about the cryptography mailing list