use of org.wildfly.common.Assert in project wildfly-elytron by wildfly-security.
the class ElytronXmlParser method parseCredentialsType.
private static ExceptionSupplier<CredentialSource, ConfigXMLParseException> parseCredentialsType(final ConfigurationXMLStreamReader reader, final Version xmlVersion, final Map<String, ExceptionSupplier<KeyStore, ConfigXMLParseException>> keyStoresMap, final Map<String, ExceptionSupplier<CredentialStore, ConfigXMLParseException>> credentialStoresMap, Supplier<Provider[]> providers) throws ConfigXMLParseException {
ExceptionUnaryOperator<CredentialSource, ConfigXMLParseException> function = parent -> CredentialSource.NONE;
requireNoAttributes(reader);
while (reader.hasNext()) {
final int tag = reader.nextTag();
if (tag == START_ELEMENT) {
checkElementNamespace(reader, xmlVersion);
switch(reader.getLocalName()) {
case "key-store-reference":
{
final ExceptionSupplier<KeyStore.Entry, ConfigXMLParseException> supplier = parseKeyStoreRefType(reader, xmlVersion, keyStoresMap, credentialStoresMap, providers);
function = andThenOp(function, credentialSource -> credentialSource.with(new KeyStoreCredentialSource(new FixedSecurityFactory<KeyStore.Entry>(supplier.get()))));
break;
}
case "credential-store-reference":
{
final ExceptionSupplier<CredentialSource, ConfigXMLParseException> supplier = parseCredentialStoreRefType(reader, credentialStoresMap);
function = andThenOp(function, credentialSource -> credentialSource.with(supplier.get()));
break;
}
case "clear-password":
{
ExceptionSupplier<Password, ConfigXMLParseException> password = parseClearPassword(reader, providers);
function = andThenOp(function, credentialSource -> credentialSource.with(IdentityCredentials.NONE.withCredential(new PasswordCredential(password.get()))));
break;
}
case "masked-password":
{
if (!xmlVersion.isAtLeast(Version.VERSION_1_4)) {
throw reader.unexpectedElement();
}
final XMLLocation location = reader.getLocation();
ExceptionSupplier<Password, ConfigXMLParseException> password = parseMaskedPassword(reader, providers);
Password maskedPassword = password.get();
Password finalPassword;
try {
final PasswordFactory passwordFactory = PasswordFactory.getInstance(maskedPassword.getAlgorithm(), providers);
final ClearPasswordSpec spec = passwordFactory.getKeySpec(maskedPassword, ClearPasswordSpec.class);
final char[] clearPassword = spec.getEncodedPassword();
PasswordFactory clearPasswordFactory = PasswordFactory.getInstance(ClearPassword.ALGORITHM_CLEAR, providers);
finalPassword = clearPasswordFactory.generatePassword(new ClearPasswordSpec(clearPassword)).castAs(ClearPassword.class);
} catch (InvalidKeySpecException | NoSuchAlgorithmException cause) {
throw xmlLog.xmlFailedToCreateCredential(location, cause);
}
function = andThenOp(function, credentialSource -> credentialSource.with(IdentityCredentials.NONE.withCredential(new PasswordCredential(finalPassword))));
break;
}
case "key-pair":
{
KeyPairCredential keyPairCredential = parseKeyPair(reader, xmlVersion, credentialStoresMap, providers);
function = andThenOp(function, credentialSource -> credentialSource.with(IdentityCredentials.NONE.withCredential(keyPairCredential)));
break;
}
case "certificate":
{
X509CertificateChainPrivateCredential credential = parseCertificateType(reader, xmlVersion);
function = andThenOp(function, credentialSource -> credentialSource.with(IdentityCredentials.NONE.withCredential(credential)));
break;
}
case "public-key-pem":
{
PublicKey publicKey = parsePem(reader, PublicKey.class);
function = andThenOp(function, credentialSource -> credentialSource.with(IdentityCredentials.NONE.withCredential(new PublicKeyCredential(publicKey))));
break;
}
case "bearer-token":
{
BearerTokenCredential bearerToken = parseBearerTokenType(reader);
function = andThenOp(function, credentialSource -> credentialSource.with(IdentityCredentials.NONE.withCredential(bearerToken)));
break;
}
case "oauth2-bearer-token":
{
final ExceptionSupplier<CredentialSource, ConfigXMLParseException> oauthCredentialSourceSupplier = parseOAuth2BearerTokenType(reader, credentialStoresMap, xmlVersion);
function = andThenOp(function, credentialSource -> credentialSource.with(oauthCredentialSourceSupplier.get()));
break;
}
case "local-kerberos":
{
if (!xmlVersion.isAtLeast(Version.VERSION_1_1)) {
throw reader.unexpectedElement();
}
CredentialSource kerberosCredentialSource = parseLocalKerberos(reader);
function = andThenOp(function, credentialSource -> credentialSource.with(kerberosCredentialSource));
xmlLog.xmlDeprecatedElement(reader.getLocalName(), reader.getLocation());
break;
}
case "ssh-credential":
{
if (!xmlVersion.isAtLeast(Version.VERSION_1_6)) {
throw reader.unexpectedElement();
}
SSHCredential sshCredential = parseSSHKeyLocationCredential(reader, xmlVersion, credentialStoresMap, providers);
function = andThenOp(function, credentialSource -> credentialSource.with(credentialSource.with(IdentityCredentials.NONE.withCredential(sshCredential))));
break;
}
default:
{
throw reader.unexpectedElement();
}
}
} else if (tag == END_ELEMENT) {
assert reader.getLocalName().equals("credentials") || reader.getLocalName().equals("protection-parameter-credentials");
final ExceptionUnaryOperator<CredentialSource, ConfigXMLParseException> finalFunction = function;
return () -> finalFunction.apply(null);
} else {
throw reader.unexpectedContent();
}
}
throw reader.unexpectedDocumentEnd();
}
use of org.wildfly.common.Assert in project wildfly-elytron by wildfly-security.
the class KeyStoreCredentialStore method store.
public void store(final String credentialAlias, final Credential credential, final CredentialStore.ProtectionParameter protectionParameter) throws CredentialStoreException {
try {
// first, attempt to encode the credential into a keystore entry
final Class<? extends Credential> credentialClass = credential.getClass();
final String algorithmName = credential instanceof AlgorithmCredential ? ((AlgorithmCredential) credential).getAlgorithm() : null;
final AlgorithmParameterSpec parameterSpec = credential.castAndApply(AlgorithmCredential.class, AlgorithmCredential::getParameters);
final KeyStore.Entry entry;
if (credentialClass == SecretKeyCredential.class) {
entry = new KeyStore.SecretKeyEntry(credential.castAndApply(SecretKeyCredential.class, SecretKeyCredential::getSecretKey));
} else if (credentialClass == PublicKeyCredential.class) {
final PublicKey publicKey = credential.castAndApply(PublicKeyCredential.class, PublicKeyCredential::getPublicKey);
final KeyFactory keyFactory = KeyFactory.getInstance(publicKey.getAlgorithm());
final X509EncodedKeySpec keySpec = keyFactory.getKeySpec(keyFactory.translateKey(publicKey), X509EncodedKeySpec.class);
final byte[] encoded = keySpec.getEncoded();
entry = new KeyStore.SecretKeyEntry(new SecretKeySpec(encoded, DATA_OID));
} else if (credentialClass == KeyPairCredential.class) {
final KeyPair keyPair = credential.castAndApply(KeyPairCredential.class, KeyPairCredential::getKeyPair);
final PublicKey publicKey = keyPair.getPublic();
final PrivateKey privateKey = keyPair.getPrivate();
final KeyFactory keyFactory = KeyFactory.getInstance(publicKey.getAlgorithm());
// ensured by KeyPairCredential
assert privateKey.getAlgorithm().equals(publicKey.getAlgorithm());
final X509EncodedKeySpec publicSpec = keyFactory.getKeySpec(keyFactory.translateKey(publicKey), X509EncodedKeySpec.class);
final PKCS8EncodedKeySpec privateSpec = keyFactory.getKeySpec(keyFactory.translateKey(privateKey), PKCS8EncodedKeySpec.class);
final DEREncoder encoder = new DEREncoder();
encoder.startSequence();
encoder.writeEncoded(publicSpec.getEncoded());
encoder.writeEncoded(privateSpec.getEncoded());
encoder.endSequence();
entry = new KeyStore.SecretKeyEntry(new SecretKeySpec(encoder.getEncoded(), DATA_OID));
} else if (credentialClass == X509CertificateChainPublicCredential.class) {
final X509Certificate[] x509Certificates = credential.castAndApply(X509CertificateChainPublicCredential.class, X509CertificateChainPublicCredential::getCertificateChain);
final DEREncoder encoder = new DEREncoder();
encoder.encodeInteger(x509Certificates.length);
encoder.startSequence();
for (X509Certificate x509Certificate : x509Certificates) {
encoder.writeEncoded(x509Certificate.getEncoded());
}
encoder.endSequence();
entry = new KeyStore.SecretKeyEntry(new SecretKeySpec(encoder.getEncoded(), DATA_OID));
} else if (credentialClass == X509CertificateChainPrivateCredential.class) {
@SuppressWarnings("ConstantConditions") X509CertificateChainPrivateCredential cred = (X509CertificateChainPrivateCredential) credential;
entry = new KeyStore.PrivateKeyEntry(cred.getPrivateKey(), cred.getCertificateChain());
} else if (credentialClass == BearerTokenCredential.class) {
entry = new KeyStore.SecretKeyEntry(new SecretKeySpec(credential.castAndApply(BearerTokenCredential.class, c -> c.getToken().getBytes(StandardCharsets.UTF_8)), DATA_OID));
} else if (credentialClass == PasswordCredential.class) {
final Password password = credential.castAndApply(PasswordCredential.class, PasswordCredential::getPassword);
final String algorithm = password.getAlgorithm();
final DEREncoder encoder = new DEREncoder();
final PasswordFactory passwordFactory = providers != null ? PasswordFactory.getInstance(algorithm, () -> providers) : PasswordFactory.getInstance(algorithm);
switch(algorithm) {
case BCryptPassword.ALGORITHM_BCRYPT:
case BSDUnixDESCryptPassword.ALGORITHM_BSD_CRYPT_DES:
case ScramDigestPassword.ALGORITHM_SCRAM_SHA_1:
case ScramDigestPassword.ALGORITHM_SCRAM_SHA_256:
case ScramDigestPassword.ALGORITHM_SCRAM_SHA_384:
case ScramDigestPassword.ALGORITHM_SCRAM_SHA_512:
case SunUnixMD5CryptPassword.ALGORITHM_SUN_CRYPT_MD5:
case SunUnixMD5CryptPassword.ALGORITHM_SUN_CRYPT_MD5_BARE_SALT:
case UnixSHACryptPassword.ALGORITHM_CRYPT_SHA_256:
case UnixSHACryptPassword.ALGORITHM_CRYPT_SHA_512:
{
IteratedSaltedHashPasswordSpec passwordSpec = passwordFactory.getKeySpec(passwordFactory.translate(password), IteratedSaltedHashPasswordSpec.class);
encoder.startSequence();
encoder.encodeOctetString(passwordSpec.getHash());
encoder.encodeOctetString(passwordSpec.getSalt());
encoder.encodeInteger(passwordSpec.getIterationCount());
encoder.endSequence();
break;
}
case ClearPassword.ALGORITHM_CLEAR:
{
final ClearPasswordSpec passwordSpec = passwordFactory.getKeySpec(passwordFactory.translate(password), ClearPasswordSpec.class);
encoder.encodeOctetString(new String(passwordSpec.getEncodedPassword()));
break;
}
case DigestPassword.ALGORITHM_DIGEST_MD5:
case DigestPassword.ALGORITHM_DIGEST_SHA:
case DigestPassword.ALGORITHM_DIGEST_SHA_256:
case DigestPassword.ALGORITHM_DIGEST_SHA_384:
case DigestPassword.ALGORITHM_DIGEST_SHA_512:
case DigestPassword.ALGORITHM_DIGEST_SHA_512_256:
{
final DigestPasswordSpec passwordSpec = passwordFactory.getKeySpec(passwordFactory.translate(password), DigestPasswordSpec.class);
encoder.startSequence();
encoder.encodeOctetString(passwordSpec.getUsername());
encoder.encodeOctetString(passwordSpec.getRealm());
encoder.encodeOctetString(passwordSpec.getDigest());
encoder.endSequence();
break;
}
case OneTimePassword.ALGORITHM_OTP_MD5:
case OneTimePassword.ALGORITHM_OTP_SHA1:
case OneTimePassword.ALGORITHM_OTP_SHA_256:
case OneTimePassword.ALGORITHM_OTP_SHA_384:
case OneTimePassword.ALGORITHM_OTP_SHA_512:
{
final OneTimePasswordSpec passwordSpec = passwordFactory.getKeySpec(passwordFactory.translate(password), OneTimePasswordSpec.class);
encoder.startSequence();
encoder.encodeOctetString(passwordSpec.getHash());
encoder.encodeIA5String(passwordSpec.getSeed());
encoder.encodeInteger(passwordSpec.getSequenceNumber());
encoder.endSequence();
break;
}
case SaltedSimpleDigestPassword.ALGORITHM_PASSWORD_SALT_DIGEST_MD5:
case SaltedSimpleDigestPassword.ALGORITHM_PASSWORD_SALT_DIGEST_SHA_1:
case SaltedSimpleDigestPassword.ALGORITHM_PASSWORD_SALT_DIGEST_SHA_256:
case SaltedSimpleDigestPassword.ALGORITHM_PASSWORD_SALT_DIGEST_SHA_384:
case SaltedSimpleDigestPassword.ALGORITHM_PASSWORD_SALT_DIGEST_SHA_512:
case SaltedSimpleDigestPassword.ALGORITHM_SALT_PASSWORD_DIGEST_MD5:
case SaltedSimpleDigestPassword.ALGORITHM_SALT_PASSWORD_DIGEST_SHA_1:
case SaltedSimpleDigestPassword.ALGORITHM_SALT_PASSWORD_DIGEST_SHA_256:
case SaltedSimpleDigestPassword.ALGORITHM_SALT_PASSWORD_DIGEST_SHA_384:
case SaltedSimpleDigestPassword.ALGORITHM_SALT_PASSWORD_DIGEST_SHA_512:
case UnixDESCryptPassword.ALGORITHM_CRYPT_DES:
case UnixMD5CryptPassword.ALGORITHM_CRYPT_MD5:
{
final SaltedHashPasswordSpec passwordSpec = passwordFactory.getKeySpec(passwordFactory.translate(password), SaltedHashPasswordSpec.class);
encoder.startSequence();
encoder.encodeOctetString(passwordSpec.getHash());
encoder.encodeOctetString(passwordSpec.getSalt());
encoder.endSequence();
break;
}
case SimpleDigestPassword.ALGORITHM_SIMPLE_DIGEST_MD2:
case SimpleDigestPassword.ALGORITHM_SIMPLE_DIGEST_MD5:
case SimpleDigestPassword.ALGORITHM_SIMPLE_DIGEST_SHA_1:
case SimpleDigestPassword.ALGORITHM_SIMPLE_DIGEST_SHA_256:
case SimpleDigestPassword.ALGORITHM_SIMPLE_DIGEST_SHA_384:
case SimpleDigestPassword.ALGORITHM_SIMPLE_DIGEST_SHA_512:
{
final HashPasswordSpec passwordSpec = passwordFactory.getKeySpec(passwordFactory.translate(password), HashPasswordSpec.class);
encoder.startSequence();
encoder.encodeOctetString(passwordSpec.getDigest());
encoder.endSequence();
break;
}
default:
{
if (MaskedPassword.isMaskedAlgorithm(algorithmName)) {
final MaskedPasswordSpec passwordSpec = passwordFactory.getKeySpec(passwordFactory.translate(password), MaskedPasswordSpec.class);
encoder.startSequence();
encoder.encodeOctetString(new String(passwordSpec.getInitialKeyMaterial()));
encoder.encodeInteger(passwordSpec.getIterationCount());
encoder.encodeOctetString(passwordSpec.getSalt());
encoder.encodeOctetString(passwordSpec.getMaskedPasswordBytes());
encoder.endSequence();
break;
} else {
throw log.unsupportedCredentialType(credentialClass);
}
}
}
entry = new KeyStore.SecretKeyEntry(new SecretKeySpec(encoder.getEncoded(), DATA_OID));
} else {
throw log.unsupportedCredentialType(credentialClass);
}
// now, store it under a unique alias
final String ksAlias = calculateNewAlias(credentialAlias, credentialClass, algorithmName, parameterSpec);
try (Hold hold = lockForWrite()) {
keyStore.setEntry(ksAlias, entry, convertParameter(protectionParameter));
final TopEntry topEntry = cache.computeIfAbsent(toLowercase(credentialAlias), TopEntry::new);
final MidEntry midEntry = topEntry.getMap().computeIfAbsent(credentialClass, c -> new MidEntry(topEntry, c));
final BottomEntry bottomEntry;
if (algorithmName != null) {
bottomEntry = midEntry.getMap().computeIfAbsent(algorithmName, n -> new BottomEntry(midEntry, n));
} else {
bottomEntry = midEntry.getOrCreateNoAlgorithm();
}
final String oldAlias;
if (parameterSpec != null) {
oldAlias = bottomEntry.getMap().put(new ParamKey(parameterSpec), ksAlias);
} else {
oldAlias = bottomEntry.setNoParams(ksAlias);
}
if (oldAlias != null && !oldAlias.equals(ksAlias)) {
// unlikely but possible
keyStore.deleteEntry(oldAlias);
}
}
} catch (KeyStoreException | NoSuchAlgorithmException | InvalidKeySpecException | InvalidKeyException | CertificateException e) {
throw log.cannotWriteCredentialToStore(e);
}
}
Aggregations