As I've stated before, I intend for JBoss Remoting 3 to utilize SASL for authentication, with SRP as its default mechanism. So pursuant to that, yesterday I put together a simple SRP SASL client & server provider.
However, I can't work out the best way to handle password verification on the server side. One of the key security advantages of SRP is that the server does not need to store the user password, so if this database is compromised, the attacker cannot directly use this database to impersonate users. Instead, SRP stores a password verifier which is calculated from the password using a one-way algorithm.
However the default SASL mechanisms generally require the server to have a copy of the cleartext password. In fact, the SASL API does not even include a Callback type to handle a password verifier of any kind. So, using just the default SASL API, there is no way to acquire the SRP password verifier value.
Here's the options as I see them:
Option #1: Just use PasswordCallback on the server side to get the clear password and derive the verifier from that value at authentication time. Pro: uses existing API; compatible out-of-the-box with code that uses default mechanisms such as DIGEST-MD5 or CRAM-MD5. Con: Loses key advantage of SRP (ability to avoid storing cleartext passwords).
Option #2: Add a custom VerifierCallback used by the server side to get the verifier value. Pro: Stronger server-side security (no cleartext passwords stored). Con: SRP server code must be aware that SRP is the mechanism in use; will not be portable between different SRP SASL implementations (on the server side anyway).
Option #3: Do not use a callback for password or verifier; instead, use a SASL configuration parameter to specify either a password file or some other means to acquire the verifier. Pro: still *mostly* compatible out-of-the-box with SASL authentication code (still would use NameCallback and AuthorizeCallback normally). Con: "mostly" != "fully"...
Another possible option is to create a new GSSAPI provider and use SRP that way, with a special credential for SRP verifier. However, Sun's GSSAPI SASL mechanism cannot support any GSSAPI mechanism other than Kerberos. Also, this is a considerably more complex solution, and requires additional security APIs. For these reasons, I don't want to go this route for Remoting unless there's no other choice.
I'm leaning towards doing Option #1 by default, for simplicity, but providing a SASL server property that can be enabled that causes the server to use the custom VerifierCallback, per Option #2.
Have you checked the latest SRP version 6a as I thought it was updated to be more compatible with SASL type exchanges?
Here is a reference to an ietf draft on a sasl version, but the link fails:
Its supposedly in cryptix:
Here is an ietf draft on using srp with TLS
http://www.ietf.org/internet-drafts/draft-ietf-tls-srp-14.txt (using with tls should be similar?)
I'm working from:
http://tools.ietf.org/id/draft-burdis-cat-srp-sasl-08.txt which, as far as I can see, was the latest published.
It seems perfectly compatible with SASL, it's just Java's SASL API that is lacking the notion of acquiring a verifier on the server side.
But can't you pass in the verifier as the "password'? I guess I would have to see what the current mapping of srp to sasl is. Is it checked in somewhere?
But can't you pass in the verifier as the "password'?
You could. That would be kind of ugly though. PasswordCallback sends in a char; you'd have to send in the verifier, salt, N, and generater values all encoded in the password somehow.
I guess I would have to see what the current mapping of srp to sasl is. Is it checked in somewhere?
I hadn't bothered checking it in because it doesn't actually *work* yet. But on the other hand, that hasn't stopped me before, so...
Ok, I'll take a look at it when I get a chance. Another workaround is to just fix the parameters for a user via lookup outside of the sasl exchange, or fix them period. This is discussed some in this paper:
Encoding the information in the 'password' would also not be that bad. Just make it the base64 representation of the byte from an ObjectOutputStream containing the serialized parameters.
Incidentally, GNU Crypto (and now, I guess, Classpath) has an SRP SASL implementation as well (based on the same spec I'm using). It's pretty complex compared to mine though (they use password file management). But I plan to use it for interoperability testing.
David, when you said that you were going to be doing SRP with SASL, I was visualizing you providing some type of GSS Adapter for SRP. I think that is how the world does it with SASL.
I need to refresh my knowledge of sasl/gss to get back.
Additionally, with SRP (like SSL), the only thing common between the client and the server is the session key. So if there is any need to do password verification semantics, you have to do it on the session key.
I was, initially. But it turns out that the JDK GSSAPI module for SASL cannot do any GSSAPI mechanism other than Kerberos. This means that I'd not only have to develop the SRP plugin for GSS, but I'd also have to develop an alternate GSSAPI mechanism for SASL, and the user would have to make sure that mine supersedes the JDK one. So I thought I'd evaluate this route instead, since it's much simpler overall, from both a user standpoint and my standpoint.
Just to get on the same page, SASL does the pluggable transfer of authentication information between point A and point B. Then you can configure SASL providers to ensure the confidentiality of the transport and the mechanics of it.
I am thinking that you will need a SRP based SASL provider.
The implementation in SVN now actually authenticates. I elected to make the server configurable (with respect to password verification) using SASL parameters. You can choose whether to simply supply the password, supply a verifier (via custom callback), or supply a text-encoded verifier to the password callback (the SrpVerifier class has methods to encode and decode the information).
Possible to bring in JSR-196 to replace your verifier mechanism?
I don't see any Callbacks within JSR-196 that specifically look like they can handle the type of verifier values that are needed by SRP. But if there is (and I'm just missing it), it should be trivial to add.
Otherwise it should be easy for someone to write a bridge between the two.