Search in sources :

Example 1 with AlgorithmCredential

use of org.wildfly.security.credential.AlgorithmCredential 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);
    }
}
Also used : MaskedPasswordSpec(org.wildfly.security.password.spec.MaskedPasswordSpec) KeyPair(java.security.KeyPair) Arrays(java.util.Arrays) Enumeration(java.util.Enumeration) SecretKeySpec(javax.crypto.spec.SecretKeySpec) KeyStoreException(java.security.KeyStoreException) CodePointIterator(org.wildfly.common.iteration.CodePointIterator) KeyUtil(org.wildfly.security.key.KeyUtil) UnixSHACryptPassword(org.wildfly.security.password.interfaces.UnixSHACryptPassword) GeneralSecurityException(java.security.GeneralSecurityException) Matcher(java.util.regex.Matcher) Map(java.util.Map) MaskedPasswordSpec(org.wildfly.security.password.spec.MaskedPasswordSpec) PasswordSpec(org.wildfly.security.password.spec.PasswordSpec) Path(java.nio.file.Path) ReadWriteLock(java.util.concurrent.locks.ReadWriteLock) EmptyProvider(org.wildfly.security.EmptyProvider) Assert(org.wildfly.common.Assert) Set(java.util.Set) DEREncoder(org.wildfly.security.asn1.DEREncoder) X509EncodedKeySpec(java.security.spec.X509EncodedKeySpec) StandardCharsets(java.nio.charset.StandardCharsets) PrivateKey(java.security.PrivateKey) NoSuchAlgorithmException(java.security.NoSuchAlgorithmException) InvalidKeyException(java.security.InvalidKeyException) BearerTokenCredential(org.wildfly.security.credential.BearerTokenCredential) SecretKey(javax.crypto.SecretKey) ByteArrayOutputStream(java.io.ByteArrayOutputStream) InvalidKeySpecException(java.security.spec.InvalidKeySpecException) DERDecoder(org.wildfly.security.asn1.DERDecoder) ReentrantReadWriteLock(java.util.concurrent.locks.ReentrantReadWriteLock) PasswordFactory(org.wildfly.security.password.PasswordFactory) AlgorithmCredential(org.wildfly.security.credential.AlgorithmCredential) OneTimePassword(org.wildfly.security.password.interfaces.OneTimePassword) IvParameterSpec(javax.crypto.spec.IvParameterSpec) PasswordCredential(org.wildfly.security.credential.PasswordCredential) ObjectOutputStream(java.io.ObjectOutputStream) SecretKeyCredential(org.wildfly.security.credential.SecretKeyCredential) HashPasswordSpec(org.wildfly.security.password.spec.HashPasswordSpec) Files(java.nio.file.Files) DigestPasswordSpec(org.wildfly.security.password.spec.DigestPasswordSpec) DigestPassword(org.wildfly.security.password.interfaces.DigestPassword) BCryptPassword(org.wildfly.security.password.interfaces.BCryptPassword) IOException(java.io.IOException) MaskedPassword(org.wildfly.security.password.interfaces.MaskedPassword) Paths(java.nio.file.Paths) CredentialStoreSpi(org.wildfly.security.credential.store.CredentialStoreSpi) AtomicFileOutputStream(org.wildfly.security.util.AtomicFileOutputStream) ScramDigestPassword(org.wildfly.security.password.interfaces.ScramDigestPassword) X509Certificate(java.security.cert.X509Certificate) ByteIterator(org.wildfly.common.iteration.ByteIterator) CertificateFactory(java.security.cert.CertificateFactory) X509CertificateChainPublicCredential(org.wildfly.security.credential.X509CertificateChainPublicCredential) ObjectInputStream(java.io.ObjectInputStream) Security(java.security.Security) OneTimePasswordSpec(org.wildfly.security.password.spec.OneTimePasswordSpec) SunUnixMD5CryptPassword(org.wildfly.security.password.interfaces.SunUnixMD5CryptPassword) CredentialSource(org.wildfly.security.credential.source.CredentialSource) ByteArrayInputStream(java.io.ByteArrayInputStream) Locale(java.util.Locale) AlgorithmParameterSpec(java.security.spec.AlgorithmParameterSpec) UnrecoverableEntryException(java.security.UnrecoverableEntryException) UnixMD5CryptPassword(org.wildfly.security.password.interfaces.UnixMD5CryptPassword) CredentialStore(org.wildfly.security.credential.store.CredentialStore) PublicKeyCredential(org.wildfly.security.credential.PublicKeyCredential) KeyStore(java.security.KeyStore) KeyPairCredential(org.wildfly.security.credential.KeyPairCredential) KeyFactory(java.security.KeyFactory) Provider(java.security.Provider) List(java.util.List) Certificate(java.security.cert.Certificate) Pattern(java.util.regex.Pattern) SimpleDigestPassword(org.wildfly.security.password.interfaces.SimpleDigestPassword) SaltedHashPasswordSpec(org.wildfly.security.password.spec.SaltedHashPasswordSpec) X500(org.wildfly.security.x500.X500) HashMap(java.util.HashMap) Cipher(javax.crypto.Cipher) IteratedSaltedHashPasswordSpec(org.wildfly.security.password.spec.IteratedSaltedHashPasswordSpec) HashSet(java.util.HashSet) ClearPasswordSpec(org.wildfly.security.password.spec.ClearPasswordSpec) NoSuchPaddingException(javax.crypto.NoSuchPaddingException) InvalidParameterSpecException(java.security.spec.InvalidParameterSpecException) ElytronMessages.log(org.wildfly.security.credential.store._private.ElytronMessages.log) UnixDESCryptPassword(org.wildfly.security.password.interfaces.UnixDESCryptPassword) OutputStream(java.io.OutputStream) X509CertificateChainPrivateCredential(org.wildfly.security.credential.X509CertificateChainPrivateCredential) PKCS8EncodedKeySpec(java.security.spec.PKCS8EncodedKeySpec) Iterator(java.util.Iterator) ASN1Exception(org.wildfly.security.asn1.ASN1Exception) PublicKey(java.security.PublicKey) CertificateException(java.security.cert.CertificateException) Base32Alphabet(org.wildfly.common.codec.Base32Alphabet) AlgorithmParameters(java.security.AlgorithmParameters) BadPaddingException(javax.crypto.BadPaddingException) SaltedSimpleDigestPassword(org.wildfly.security.password.interfaces.SaltedSimpleDigestPassword) BSDUnixDESCryptPassword(org.wildfly.security.password.interfaces.BSDUnixDESCryptPassword) Password(org.wildfly.security.password.Password) CredentialStoreException(org.wildfly.security.credential.store.CredentialStoreException) ClearPassword(org.wildfly.security.password.interfaces.ClearPassword) Credential(org.wildfly.security.credential.Credential) Collections(java.util.Collections) InputStream(java.io.InputStream) PrivateKey(java.security.PrivateKey) PasswordCredential(org.wildfly.security.credential.PasswordCredential) SaltedHashPasswordSpec(org.wildfly.security.password.spec.SaltedHashPasswordSpec) IteratedSaltedHashPasswordSpec(org.wildfly.security.password.spec.IteratedSaltedHashPasswordSpec) BearerTokenCredential(org.wildfly.security.credential.BearerTokenCredential) ClearPasswordSpec(org.wildfly.security.password.spec.ClearPasswordSpec) CertificateException(java.security.cert.CertificateException) NoSuchAlgorithmException(java.security.NoSuchAlgorithmException) SecretKeyCredential(org.wildfly.security.credential.SecretKeyCredential) OneTimePasswordSpec(org.wildfly.security.password.spec.OneTimePasswordSpec) AlgorithmCredential(org.wildfly.security.credential.AlgorithmCredential) DEREncoder(org.wildfly.security.asn1.DEREncoder) SecretKeySpec(javax.crypto.spec.SecretKeySpec) HashPasswordSpec(org.wildfly.security.password.spec.HashPasswordSpec) SaltedHashPasswordSpec(org.wildfly.security.password.spec.SaltedHashPasswordSpec) IteratedSaltedHashPasswordSpec(org.wildfly.security.password.spec.IteratedSaltedHashPasswordSpec) InvalidKeySpecException(java.security.spec.InvalidKeySpecException) X509CertificateChainPublicCredential(org.wildfly.security.credential.X509CertificateChainPublicCredential) KeyFactory(java.security.KeyFactory) UnixSHACryptPassword(org.wildfly.security.password.interfaces.UnixSHACryptPassword) OneTimePassword(org.wildfly.security.password.interfaces.OneTimePassword) DigestPassword(org.wildfly.security.password.interfaces.DigestPassword) BCryptPassword(org.wildfly.security.password.interfaces.BCryptPassword) MaskedPassword(org.wildfly.security.password.interfaces.MaskedPassword) ScramDigestPassword(org.wildfly.security.password.interfaces.ScramDigestPassword) SunUnixMD5CryptPassword(org.wildfly.security.password.interfaces.SunUnixMD5CryptPassword) UnixMD5CryptPassword(org.wildfly.security.password.interfaces.UnixMD5CryptPassword) SimpleDigestPassword(org.wildfly.security.password.interfaces.SimpleDigestPassword) UnixDESCryptPassword(org.wildfly.security.password.interfaces.UnixDESCryptPassword) SaltedSimpleDigestPassword(org.wildfly.security.password.interfaces.SaltedSimpleDigestPassword) BSDUnixDESCryptPassword(org.wildfly.security.password.interfaces.BSDUnixDESCryptPassword) Password(org.wildfly.security.password.Password) ClearPassword(org.wildfly.security.password.interfaces.ClearPassword) KeyPair(java.security.KeyPair) X509CertificateChainPrivateCredential(org.wildfly.security.credential.X509CertificateChainPrivateCredential) PublicKey(java.security.PublicKey) X509EncodedKeySpec(java.security.spec.X509EncodedKeySpec) PublicKeyCredential(org.wildfly.security.credential.PublicKeyCredential) KeyStoreException(java.security.KeyStoreException) InvalidKeyException(java.security.InvalidKeyException) KeyStore(java.security.KeyStore) X509Certificate(java.security.cert.X509Certificate) IteratedSaltedHashPasswordSpec(org.wildfly.security.password.spec.IteratedSaltedHashPasswordSpec) PasswordFactory(org.wildfly.security.password.PasswordFactory) KeyPairCredential(org.wildfly.security.credential.KeyPairCredential) PKCS8EncodedKeySpec(java.security.spec.PKCS8EncodedKeySpec) AlgorithmParameterSpec(java.security.spec.AlgorithmParameterSpec) DigestPasswordSpec(org.wildfly.security.password.spec.DigestPasswordSpec)

Aggregations

ByteArrayInputStream (java.io.ByteArrayInputStream)1 ByteArrayOutputStream (java.io.ByteArrayOutputStream)1 IOException (java.io.IOException)1 InputStream (java.io.InputStream)1 ObjectInputStream (java.io.ObjectInputStream)1 ObjectOutputStream (java.io.ObjectOutputStream)1 OutputStream (java.io.OutputStream)1 StandardCharsets (java.nio.charset.StandardCharsets)1 Files (java.nio.file.Files)1 Path (java.nio.file.Path)1 Paths (java.nio.file.Paths)1 AlgorithmParameters (java.security.AlgorithmParameters)1 GeneralSecurityException (java.security.GeneralSecurityException)1 InvalidKeyException (java.security.InvalidKeyException)1 KeyFactory (java.security.KeyFactory)1 KeyPair (java.security.KeyPair)1 KeyStore (java.security.KeyStore)1 KeyStoreException (java.security.KeyStoreException)1 NoSuchAlgorithmException (java.security.NoSuchAlgorithmException)1 PrivateKey (java.security.PrivateKey)1