[security-dev] Credentials API redesign
David M. Lloyd
david.lloyd at redhat.com
Thu Dec 6 11:12:12 EST 2012
Comments inline, extra stuff trimmed.
On 12/05/2012 08:18 PM, Shane Bryzak wrote:
> Hey guys,
>
> I've completed the first round of redesigns for the credentials API
> based on the feedback provided by Darran and others.
[...]
> To try and present this in a logical manner, I'm going to describe the
> credentials API in terms of the chronological order of events during the
> authentication process. To start with, let's take a look at the
> LoginCredentials interface:
>
> public interface LoginCredentials {
> void invalidate();
> }
General invalidation is a good idea.
> [...]
> Let's take a look at an implementation supporting the most common form
> of credentials, a username and password:
>
> public class UsernamePasswordCredentials implements LoginCredentials {
>
> private String username;
>
> private PasswordCredential password;
>
> public String getUsername() {
> return username;
> }
>
> public void setUsername(String username) {
> this.username = username;
> }
>
> public PasswordCredential getPassword() {
> return password;
> }
>
> public void setPassword(PasswordCredential password) {
> this.password = password;
> }
>
> @Override
> public void invalidate() {
> username = null;
> password.clear();
> }
> }
>
> This implementation provides the capability for setting a username
> (represented as a String) and a PasswordCredential. Other
> implementations are free to define whichever properties they require,
> for example a CertificateCredentials class may simply contain an
> X509CertificateCredential and nothing else.
I have concern over PasswordCredential. There are many ways in which a
password may be verified. It may be stored in the clear, or maybe with
some two-way encryption in the way. It may be stored as a salt of
various length plus a hash of various protocol. It may be stored as a
pure hash. Not only is there a wide variation in *how* the password can
be stored, but that variation can occur within a single identity store
(e.g. older users may be hashed with a weaker hash as time goes on and
stronger hash algorithms are introduced, for example the progression
between UNIX crypt->md5 crypt->sha1 crypt passwords; or a store might
contain a combination of clear and hashed passwords).
Finally, the way a password is stored directly affects what
authentication mechanisms it can support. For example a clear password
allows for many challenge/response protocols that are not possible with
salt+hash password. Some protocols like SASL DIGEST-MD5 can support
passwords that have been simply hashed in a certain way.
I don't see a LoginCredentials-style interface successfully
encapsulating this concept.
> Once the user provides their credentials, the LoginCredentials instance
> can be passed to IdentityManager via the following method:
>
> public interface IdentityManager {
> User validateCredentials(LoginCredentials credentials);
> }
Validation is highly protocol-specific. There's a basic assumption here
that the credentials being tested are similar or equivalent in form and
structure to the credentials being tested against; this is almost never
true in practice. For challenge/response authentications, the server
might never see the client's real credentials; approval is a result of a
conversational protocol in this case. Thus the credentials presented by
the user, the conversation across the wire, and the server's credentials
might all be different.
I think that the only way to encapsulate this is to allow for
credentials to be defined by their traits. For example, we can ask, for
each credential type:
1) Does it have the ability to validate a char[] password?
2) Does it have the ability to yield a char[] password?
3) Is it a one-way hash? If so:
3.1) What hash algorithm was used?
3.2) What is the salt, if any?
3.3) What salt algorithm was used?
4) Is there a shared key involved (i.e. a byte[] password)?
4.1) Is the shared key specified by a particular protocol?
5) Is there a private key involved? If so, what's its algorithm?
...etc...
The answers to these questions are not always mutually exclusive. But,
the answers will directly influence what kinds of authentication can
take place against that particular identity.
Finally there's the notion of federated identity management - what if I
want to delegate my authentication request to PAM or another external
API? How would that look from the perspective of IDM? Theoretically
external IDM systems *should* be able abstract themselves using the same
API. It just doesn't seem to me that the proposed SPI will be able to
encapsulate all of this stuff.
--
- DML
More information about the security-dev
mailing list