/* See LICENSE for licensing and NOTICE for copyright. */
package org.cryptacular.asn;
import java.io.IOException;
import org.bouncycastle.asn1.ASN1InputStream;
import org.bouncycastle.asn1.pkcs.EncryptedPrivateKeyInfo;
import org.bouncycastle.asn1.pkcs.PBEParameter;
import org.bouncycastle.asn1.pkcs.PBES2Parameters;
import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
import org.bouncycastle.crypto.params.AsymmetricKeyParameter;
import org.bouncycastle.crypto.util.PrivateKeyFactory;
import org.cryptacular.EncodingException;
import org.cryptacular.pbe.EncryptionScheme;
import org.cryptacular.pbe.PBES1Algorithm;
import org.cryptacular.pbe.PBES1EncryptionScheme;
import org.cryptacular.pbe.PBES2EncryptionScheme;
/**
* Decodes PEM or DER-encoded PKCS#8 private keys.
*
* @author Middleware Services
*/
public class PKCS8PrivateKeyDecoder extends AbstractPrivateKeyDecoder<AsymmetricKeyParameter>
{
@Override
protected byte[] decryptKey(final byte[] encrypted, final char[] password)
{
final EncryptionScheme scheme;
final EncryptedPrivateKeyInfo ki = EncryptedPrivateKeyInfo.getInstance(tryConvertPem(encrypted));
final AlgorithmIdentifier alg = ki.getEncryptionAlgorithm();
if (PKCSObjectIdentifiers.id_PBES2.equals(alg.getAlgorithm())) {
scheme = new PBES2EncryptionScheme(PBES2Parameters.getInstance(alg.getParameters()), password);
} else {
scheme = new PBES1EncryptionScheme(
PBES1Algorithm.fromOid(alg.getAlgorithm().getId()),
PBEParameter.getInstance(alg.getParameters()),
password);
}
return scheme.decrypt(ki.getEncryptedData());
}
@Override
protected AsymmetricKeyParameter decodeASN1(final byte[] encoded)
{
try {
return PrivateKeyFactory.createKey(new ASN1InputStream(encoded).readObject().getEncoded());
} catch (IOException e) {
throw new EncodingException("ASN.1 decoding error", e);
}
}
}