use of com.unboundid.asn1.ASN1Exception in project wildfly-elytron by wildfly-security.
the class KeyStoreCredentialStore method retrieve.
public <C extends Credential> C retrieve(final String credentialAlias, final Class<C> credentialType, final String credentialAlgorithm, final AlgorithmParameterSpec parameterSpec, final CredentialStore.ProtectionParameter protectionParameter) throws CredentialStoreException {
final KeyStore.Entry entry;
final MidEntry midEntry;
final BottomEntry bottomEntry;
final String ksAlias;
try (Hold hold = lockForRead()) {
final TopEntry topEntry = cache.get(toLowercase(credentialAlias));
if (topEntry == null) {
log.trace("KeyStoreCredentialStore: alias not found in cache");
return null;
}
if (topEntry.getMap().containsKey(credentialType)) {
log.trace("KeyStoreCredentialStore: contains exact type");
midEntry = topEntry.getMap().get(credentialType);
} else {
// loose (slow) match
final Iterator<MidEntry> iterator = topEntry.getMap().values().iterator();
for (; ; ) {
if (!iterator.hasNext()) {
log.trace("KeyStoreCredentialStore: no assignable found");
return null;
}
MidEntry item = iterator.next();
if (credentialType.isAssignableFrom(item.getCredentialType())) {
log.trace("KeyStoreCredentialStore: assignable found");
midEntry = item;
break;
}
}
}
if (credentialAlgorithm != null) {
bottomEntry = midEntry.getMap().get(credentialAlgorithm);
} else {
// match any
final Iterator<BottomEntry> iterator = midEntry.getMap().values().iterator();
if (iterator.hasNext()) {
bottomEntry = iterator.next();
} else {
bottomEntry = midEntry.getNoAlgorithm();
}
}
if (bottomEntry == null) {
log.tracef("KeyStoreCredentialStore: no entry for algorithm %s", credentialAlgorithm);
return null;
}
if (parameterSpec != null) {
ksAlias = bottomEntry.getMap().get(new ParamKey(parameterSpec));
} else {
// match any
final Iterator<String> iterator = bottomEntry.getMap().values().iterator();
if (iterator.hasNext()) {
ksAlias = iterator.next();
} else {
ksAlias = bottomEntry.getNoParams();
}
}
if (ksAlias == null) {
log.tracef("KeyStoreCredentialStore: no entry for parameterSpec %s", parameterSpec);
return null;
}
entry = keyStore.getEntry(ksAlias, convertParameter(protectionParameter));
} catch (NoSuchAlgorithmException | UnrecoverableEntryException | KeyStoreException e) {
throw log.cannotAcquireCredentialFromStore(e);
}
if (entry == null) {
// odd, but we can handle it
log.trace("KeyStoreCredentialStore: null entry");
return null;
}
final Class<? extends Credential> matchedCredentialType = midEntry.getCredentialType();
if (matchedCredentialType == SecretKeyCredential.class) {
if (entry instanceof KeyStore.SecretKeyEntry) {
// simple
final SecretKey secretKey = ((KeyStore.SecretKeyEntry) entry).getSecretKey();
return credentialType.cast(new SecretKeyCredential(secretKey));
} else {
throw log.invalidCredentialStoreEntryType(KeyStore.SecretKeyEntry.class, entry.getClass());
}
} else if (matchedCredentialType == PublicKeyCredential.class) {
if (entry instanceof KeyStore.SecretKeyEntry)
try {
// we store as a secret key because we can't store the public key properly...
final SecretKey secretKey = ((KeyStore.SecretKeyEntry) entry).getSecretKey();
final byte[] encoded = secretKey.getEncoded();
final String matchedAlgorithm = bottomEntry.getAlgorithm();
// because PublicKeyCredential is an AlgorithmCredential
assert matchedAlgorithm != null;
final KeyFactory keyFactory = KeyFactory.getInstance(matchedAlgorithm);
final PublicKey publicKey = keyFactory.generatePublic(new X509EncodedKeySpec(encoded));
return credentialType.cast(new PublicKeyCredential(publicKey));
} catch (InvalidKeySpecException | NoSuchAlgorithmException e) {
throw log.cannotAcquireCredentialFromStore(e);
}
else {
throw log.invalidCredentialStoreEntryType(KeyStore.SecretKeyEntry.class, entry.getClass());
}
} else if (matchedCredentialType == KeyPairCredential.class) {
if (entry instanceof KeyStore.SecretKeyEntry)
try {
final SecretKey secretKey = ((KeyStore.SecretKeyEntry) entry).getSecretKey();
final byte[] encoded = secretKey.getEncoded();
final String matchedAlgorithm = bottomEntry.getAlgorithm();
// because KeyPairCredential is an AlgorithmCredential
assert matchedAlgorithm != null;
// extract public and private segments
final DERDecoder decoder = new DERDecoder(encoded);
decoder.startSequence();
final byte[] publicBytes = decoder.drainElement();
final byte[] privateBytes = decoder.drainElement();
decoder.endSequence();
final KeyFactory keyFactory = KeyFactory.getInstance(matchedAlgorithm);
final PublicKey publicKey = keyFactory.generatePublic(new X509EncodedKeySpec(publicBytes));
final PrivateKey privateKey = keyFactory.generatePrivate(new PKCS8EncodedKeySpec(privateBytes));
final KeyPair keyPair = new KeyPair(publicKey, privateKey);
return credentialType.cast(new KeyPairCredential(keyPair));
} catch (InvalidKeySpecException | NoSuchAlgorithmException | ASN1Exception e) {
throw log.cannotAcquireCredentialFromStore(e);
}
else {
throw log.invalidCredentialStoreEntryType(KeyStore.SecretKeyEntry.class, entry.getClass());
}
} else if (matchedCredentialType == X509CertificateChainPublicCredential.class) {
if (entry instanceof KeyStore.SecretKeyEntry)
try {
// OK so this is pretty ugly, but the TrustedCertificateEntry type only holds a single cert so it's no good
final SecretKey secretKey = ((KeyStore.SecretKeyEntry) entry).getSecretKey();
final byte[] encoded = secretKey.getEncoded();
final String matchedAlgorithm = bottomEntry.getAlgorithm();
// because it is an AlgorithmCredential
assert matchedAlgorithm != null;
final DERDecoder decoder = new DERDecoder(encoded);
final CertificateFactory certificateFactory = CertificateFactory.getInstance(X_509);
final int count = decoder.decodeInteger().intValueExact();
final X509Certificate[] array = new X509Certificate[count];
decoder.startSequence();
int i = 0;
while (decoder.hasNextElement()) {
final byte[] certBytes = decoder.drainElement();
array[i++] = (X509Certificate) certificateFactory.generateCertificate(new ByteArrayInputStream(certBytes));
}
decoder.endSequence();
return credentialType.cast(new X509CertificateChainPublicCredential(array));
} catch (ASN1Exception | CertificateException | ArrayIndexOutOfBoundsException e) {
throw log.cannotAcquireCredentialFromStore(e);
}
else {
throw log.invalidCredentialStoreEntryType(KeyStore.SecretKeyEntry.class, entry.getClass());
}
} else if (matchedCredentialType == X509CertificateChainPrivateCredential.class) {
if (entry instanceof KeyStore.PrivateKeyEntry) {
// an entry type that matches our credential type!
final KeyStore.PrivateKeyEntry privateKeyEntry = (KeyStore.PrivateKeyEntry) entry;
final PrivateKey privateKey = privateKeyEntry.getPrivateKey();
final Certificate[] certificateChain = privateKeyEntry.getCertificateChain();
final X509Certificate[] x509Certificates = X500.asX509CertificateArray(certificateChain);
return credentialType.cast(new X509CertificateChainPrivateCredential(privateKey, x509Certificates));
} else {
throw log.invalidCredentialStoreEntryType(KeyStore.PrivateKeyEntry.class, entry.getClass());
}
} else if (matchedCredentialType == BearerTokenCredential.class) {
if (entry instanceof KeyStore.SecretKeyEntry) {
final SecretKey secretKey = ((KeyStore.SecretKeyEntry) entry).getSecretKey();
final byte[] encoded = secretKey.getEncoded();
return credentialType.cast(new BearerTokenCredential(new String(encoded, StandardCharsets.UTF_8)));
} else {
throw log.invalidCredentialStoreEntryType(KeyStore.SecretKeyEntry.class, entry.getClass());
}
} else if (matchedCredentialType == PasswordCredential.class) {
if (entry instanceof KeyStore.SecretKeyEntry)
try {
final SecretKey secretKey = ((KeyStore.SecretKeyEntry) entry).getSecretKey();
final byte[] encoded = secretKey.getEncoded();
final String matchedAlgorithm = bottomEntry.getAlgorithm();
// because it is an AlgorithmCredential
assert matchedAlgorithm != null;
final DERDecoder decoder = new DERDecoder(encoded);
// we use algorithm-based encoding rather than a standard that encompasses all password types.
final PasswordSpec passwordSpec;
switch(matchedAlgorithm) {
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:
{
decoder.startSequence();
final byte[] hash = decoder.decodeOctetString();
final byte[] salt = decoder.decodeOctetString();
final int iterationCount = decoder.decodeInteger().intValue();
decoder.endSequence();
passwordSpec = new IteratedSaltedHashPasswordSpec(hash, salt, iterationCount);
break;
}
case ClearPassword.ALGORITHM_CLEAR:
{
passwordSpec = new ClearPasswordSpec(decoder.decodeOctetStringAsString().toCharArray());
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:
{
decoder.startSequence();
final String username = decoder.decodeOctetStringAsString();
final String realm = decoder.decodeOctetStringAsString();
final byte[] digest = decoder.decodeOctetString();
decoder.endSequence();
passwordSpec = new DigestPasswordSpec(username, realm, digest);
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:
{
decoder.startSequence();
final byte[] hash = decoder.decodeOctetString();
final String seed = decoder.decodeIA5String();
final int sequenceNumber = decoder.decodeInteger().intValue();
decoder.endSequence();
passwordSpec = new OneTimePasswordSpec(hash, seed, sequenceNumber);
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:
{
decoder.startSequence();
final byte[] hash = decoder.decodeOctetString();
final byte[] salt = decoder.decodeOctetString();
decoder.endSequence();
passwordSpec = new SaltedHashPasswordSpec(hash, salt);
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:
{
decoder.startSequence();
final byte[] hash = decoder.decodeOctetString();
decoder.endSequence();
passwordSpec = new HashPasswordSpec(hash);
break;
}
default:
{
if (MaskedPassword.isMaskedAlgorithm(matchedAlgorithm)) {
decoder.startSequence();
final char[] initialKeyMaterial = decoder.decodeOctetStringAsString().toCharArray();
final int iterationCount = decoder.decodeInteger().intValue();
final byte[] salt = decoder.decodeOctetString();
final byte[] maskedPasswordBytes = decoder.decodeOctetString();
decoder.endSequence();
passwordSpec = new MaskedPasswordSpec(initialKeyMaterial, iterationCount, salt, maskedPasswordBytes);
break;
} else {
throw log.unsupportedCredentialType(credentialType);
}
}
}
PasswordFactory passwordFactory = providers != null ? PasswordFactory.getInstance(matchedAlgorithm, () -> providers) : PasswordFactory.getInstance(matchedAlgorithm);
final Password password = passwordFactory.generatePassword(passwordSpec);
return credentialType.cast(new PasswordCredential(password));
} catch (InvalidKeySpecException | NoSuchAlgorithmException e) {
throw log.cannotAcquireCredentialFromStore(e);
}
else {
throw log.invalidCredentialStoreEntryType(KeyStore.SecretKeyEntry.class, entry.getClass());
}
} else {
throw log.unableToReadCredentialTypeFromStore(matchedCredentialType);
}
}
use of com.unboundid.asn1.ASN1Exception in project wildfly-elytron by wildfly-security.
the class EntityUtil method encodeX509CertificateChain.
/* -- Methods used to encode ASN.1 data structures required for entity authentication -- */
/**
* Encode an ASN.1 set of certificates using the given DER encoder and the
* given {@code X509Certificate} chain.
*
* @param encoder the DER encoder
* @param certChain the X.509 certificate chain to encode
* @throws ASN1Exception if an error occurs while encoding the given certificate chain
*/
public static void encodeX509CertificateChain(final DEREncoder encoder, X509Certificate[] certChain) throws ASN1Exception {
try {
int chainSize = certChain.length;
encoder.startSetOf();
for (int i = 0; i < chainSize; i++) {
encoder.writeEncoded(certChain[i].getEncoded());
}
encoder.endSetOf();
} catch (CertificateEncodingException e) {
throw new ASN1Exception(e);
}
}
use of com.unboundid.asn1.ASN1Exception in project wildfly-elytron by wildfly-security.
the class EntityUtil method decodeX509CertificateChain.
/**
* Decode the next element from the given DER decoder as an X.509 certificate chain.
*
* @param decoder the DER decoder
* @return the X.509 certificate chain
* @throws ASN1Exception if the next element from the given decoder is not an X.509
* certificate chain or if an error occurs while decoding the X.509 certificate chain
*/
public static X509Certificate[] decodeX509CertificateChain(final DERDecoder decoder) throws ASN1Exception {
if (decoder.peekType() != SET_TYPE) {
throw saslEntity.asnUnexpectedTag();
}
byte[] certChain = decoder.drainElement();
try {
CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
// CertificateFactory#generateCertPath requires a DER SEQUE
certChain[0] = SEQUENCE_TYPE;
CertPath certPath = certFactory.generateCertPath(new ByteArrayInputStream(certChain));
List<? extends Certificate> certs = certPath.getCertificates();
return certs.toArray(new X509Certificate[certs.size()]);
} catch (CertificateException e) {
throw new ASN1Exception(e);
}
}
use of com.unboundid.asn1.ASN1Exception in project wildfly-elytron by wildfly-security.
the class EntityUtil method decodeTrustedAuthorities.
/**
* Decode the next element from the given DER decoder as a trusted authorities element.
*
* @param decoder the DER decoder
* @return the trusted authorities
* @throws ASN1Exception if the next element from the given decoder is not a trusted authorities
* element or if an error occurs while decoding the trusted authorities element
*/
public static List<TrustedAuthority> decodeTrustedAuthorities(final DERDecoder decoder) throws ASN1Exception {
List<TrustedAuthority> trustedAuthorities = new ArrayList<TrustedAuthority>();
TrustedAuthority trustedAuthority = null;
decoder.startSequence();
while (decoder.hasNextElement()) {
out: {
for (int trustedAuthorityType = 0; trustedAuthorityType <= 4; trustedAuthorityType++) {
switch(trustedAuthorityType) {
case AUTHORITY_NAME:
if (decoder.isNextType(CONTEXT_SPECIFIC_MASK, trustedAuthorityType, true)) {
byte[] encodedName = decoder.drainElementValue();
trustedAuthority = new NameTrustedAuthority((new X500Principal(encodedName)).getName(X500Principal.CANONICAL));
break out;
}
break;
case AUTHORITY_CERTIFICATE:
if (decoder.isNextType(CONTEXT_SPECIFIC_MASK, trustedAuthorityType, true)) {
decoder.decodeImplicit(trustedAuthorityType);
byte[] cert = decoder.drainElement();
// Replace the trusted authority type tag with a DER SEQUENCE tag, as required by CertificateFactory#generateCertificate
cert[0] = SEQUENCE_TYPE;
try {
CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
trustedAuthority = new CertificateTrustedAuthority((X509Certificate) certFactory.generateCertificate(new ByteArrayInputStream(cert)));
} catch (CertificateException e) {
throw new ASN1Exception(e);
}
break out;
}
break;
case ISSUER_NAME_HASH:
if (decoder.isNextType(CONTEXT_SPECIFIC_MASK, trustedAuthorityType, false)) {
decoder.decodeImplicit(trustedAuthorityType);
trustedAuthority = new IssuerNameHashTrustedAuthority(decoder.decodeOctetString());
break out;
}
break;
case ISSUER_KEY_HASH:
if (decoder.isNextType(CONTEXT_SPECIFIC_MASK, trustedAuthorityType, false)) {
decoder.decodeImplicit(trustedAuthorityType);
trustedAuthority = new IssuerKeyHashTrustedAuthority(decoder.decodeOctetString());
break out;
}
break;
case PKCS_15_KEY_HASH:
if (decoder.isNextType(CONTEXT_SPECIFIC_MASK, trustedAuthorityType, false)) {
decoder.decodeImplicit(trustedAuthorityType);
trustedAuthority = new PKCS15KeyHashTrustedAuthority(decoder.decodeOctetString());
break out;
}
break;
default:
throw saslEntity.asnInvalidGeneralNameType();
}
}
}
trustedAuthorities.add(trustedAuthority);
}
decoder.endSequence();
return trustedAuthorities;
}
use of com.unboundid.asn1.ASN1Exception in project structure-project by wudskq.
the class KeyImpl method readObject.
private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {
try {
EncryptionKey encKey = new EncryptionKey(new DerValue((byte[]) ois.readObject()));
keyType = encKey.getEType();
keyBytes = encKey.getBytes();
} catch (Asn1Exception ae) {
throw new IOException(ae.getMessage());
}
}
Aggregations