org.wildfly.security.mechanism.scram.ScramMechanism Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of wildfly-elytron-mechanism-scram
Show all versions of wildfly-elytron-mechanism-scram
WildFly Security Mechanism SCRAM
The newest version!
/*
* JBoss, Home of Professional Open Source.
* Copyright 2015 Red Hat, Inc., and individual contributors
* as indicated by the @author tags.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.wildfly.security.mechanism.scram;
import java.security.Provider;
import java.security.SecureRandom;
import java.util.function.Supplier;
import javax.security.auth.callback.CallbackHandler;
import org.wildfly.security.auth.callback.ChannelBindingCallback;
import org.wildfly.security.mechanism.AuthenticationMechanismException;
import org.wildfly.security.password.interfaces.ScramDigestPassword;
import org.wildfly.security.sasl.WildFlySasl;
/**
* Implementation of the SCRAM authentication mechanism.
*
* @author David M. Lloyd
*/
public final class ScramMechanism {
// Hash size; may be less than the output size of the MD/MAC
private final int hashSize;
private final String messageDigestName;
private final String hmacName;
private final boolean plus;
private final String passwordAlgorithm;
private final String toString;
/**
* Constructs a new {@code ScramMechanism}.
*
* @param hashSize the size of the hash of the SCRAM mechanism.
* @param messageDigestName the name of the message digest algorithm.
* @param hmacName the name of the HMAC algorithm.
* @param plus {@code true} to use the PLUS channel binding, {@code false} otherwise.
* @param passwordAlgorithm the name of the password algorithm in {@link ScramDigestPassword}.
*/
private ScramMechanism(final int hashSize, final String messageDigestName, final String hmacName, final boolean plus, final String passwordAlgorithm) {
this.hashSize = hashSize;
this.messageDigestName = messageDigestName;
this.hmacName = hmacName;
this.plus = plus;
this.passwordAlgorithm = passwordAlgorithm;
StringBuilder b = new StringBuilder();
b.append("SCRAM ").append(messageDigestName).append(' ');
if (plus) b.append("(PLUS channel binding) ");
b.append(hashSize * 8).append(" bits");
toString = b.toString();
}
public static final ScramMechanism SCRAM_SHA_1 = new ScramMechanism(20, "SHA-1", "HmacSHA1", false, ScramDigestPassword.ALGORITHM_SCRAM_SHA_1);
public static final ScramMechanism SCRAM_SHA_1_PLUS = new ScramMechanism(20, "SHA-1", "HmacSHA1", true, ScramDigestPassword.ALGORITHM_SCRAM_SHA_1);
public static final ScramMechanism SCRAM_SHA_256 = new ScramMechanism(32, "SHA-256", "HmacSHA256", false, ScramDigestPassword.ALGORITHM_SCRAM_SHA_256);
public static final ScramMechanism SCRAM_SHA_256_PLUS = new ScramMechanism(32, "SHA-256", "HmacSHA256", true, ScramDigestPassword.ALGORITHM_SCRAM_SHA_256);
public static final ScramMechanism SCRAM_SHA_384 = new ScramMechanism(48, "SHA-384", "HmacSHA384", false, ScramDigestPassword.ALGORITHM_SCRAM_SHA_384);
public static final ScramMechanism SCRAM_SHA_384_PLUS = new ScramMechanism(32, "SHA-384", "HmacSHA384", true, ScramDigestPassword.ALGORITHM_SCRAM_SHA_384);
public static final ScramMechanism SCRAM_SHA_512 = new ScramMechanism(64, "SHA-512", "HmacSHA512", false, ScramDigestPassword.ALGORITHM_SCRAM_SHA_512);
public static final ScramMechanism SCRAM_SHA_512_PLUS = new ScramMechanism(64, "SHA-512", "HmacSHA512", true, ScramDigestPassword.ALGORITHM_SCRAM_SHA_512);
/**
* Create a SCRAM client for this mechanism.
*
* @param authorizationId the authorization ID ({@code null} if none is given)
* @param callbackHandler the callback handler (may not be {@code null})
* @param secureRandom an optional secure random implementation to use (may be {@code null})
* @param bindingCallback the optional channel binding callback result (may be {@code null})
* @param minimumIterationCount the minimum iteration count to allow
* @param maximumIterationCount the maximum iteration count to allow
* @param providers the security providers.
* @return the SCRAM client, or {@code null} if the client cannot be created from this mechanism variant
* @throws AuthenticationMechanismException if the mechanism fails for some reason
* @see WildFlySasl#SCRAM_MIN_ITERATION_COUNT
* @see WildFlySasl#SCRAM_MAX_ITERATION_COUNT
*/
public ScramClient createClient(final String authorizationId, final CallbackHandler callbackHandler, final SecureRandom secureRandom, final ChannelBindingCallback bindingCallback, final int minimumIterationCount, final int maximumIterationCount, final Supplier providers) throws AuthenticationMechanismException {
final byte[] bindingData;
final String bindingType;
if (bindingCallback != null) {
bindingData = bindingCallback.getBindingData();
bindingType = bindingCallback.getBindingType();
} else {
if (plus) return null;
bindingData = null;
bindingType = null;
}
return new ScramClient(this, authorizationId, callbackHandler, secureRandom, bindingData, bindingType, minimumIterationCount, maximumIterationCount, providers);
}
/**
* Create a SCRAM server for this mechanism.
*
* @param callbackHandler the callback handler (may not be {@code null}).
* @param random an optional secure random implementation to use (may be {@code null}).
* @param bindingCallback the optional channel binding callback result (may be {@code null}).
* @param minimumIterationCount the minimum iteration count to allow.
* @param maximumIterationCount the maximum iteration count to allow.
* @param providers the security providers.
* @return the SCRAM server, or {@code null} if the server cannot be created from this mechanism variant.
* @throws AuthenticationMechanismException if the mechanism fails for some reason.
*/
public ScramServer createServer(final CallbackHandler callbackHandler, final SecureRandom random, final ChannelBindingCallback bindingCallback, final int minimumIterationCount, final int maximumIterationCount, final Supplier providers) throws AuthenticationMechanismException {
final byte[] bindingData;
final String bindingType;
if (bindingCallback != null) {
bindingData = bindingCallback.getBindingData();
bindingType = bindingCallback.getBindingType();
} else {
if (plus) return null;
bindingData = null;
bindingType = null;
}
return new ScramServer(this, callbackHandler, random, bindingData, bindingType, minimumIterationCount, maximumIterationCount, providers);
}
/**
* Returns the size of the hash of the SCRAM mechanism.
*
* @return the size of the hash of the SCRAM mechanism.
*/
public int getHashSize() {
return hashSize;
}
/**
* Returns the name of the message digest algorithm.
*
* @return the name of the message digest algorithm.
*/
public String getMessageDigestName() {
return messageDigestName;
}
/**
* Returns the name of the HMAC algorithm.
*
* @return the name of the HMAC algorithm.
*/
public String getHmacName() {
return hmacName;
}
/**
* Returns whether the SCRAM mechanism uses the PLUS channel binding.
*
* @return {@code true} to use the PLUS channel binding, {@code false} otherwise.
*/
public boolean isPlus() {
return plus;
}
/**
* Returns the name of the password algorithm from {@code ScramDigestPassword}.
*
* @return the name of the password algorithm.
*/
public String getPasswordAlgorithm() {
return passwordAlgorithm;
}
/**
* Returns a String representation of the SCRAM mechanism.
* Contains the Digest name, PLUS channel binding and hash size.
*
* @return a String representation of the SCRAM mechanism.
*/
public String toString() {
return toString;
}
}