[cryptography] "best practices" for hostname validation when using JSSE
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
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:
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,
More information about the cryptography