mirror of
https://github.com/moparisthebest/open-keychain
synced 2024-11-06 17:25:05 -05:00
235 lines
7.7 KiB
Java
235 lines
7.7 KiB
Java
package javax.crypto;
|
|
|
|
import java.io.*;
|
|
|
|
import java.security.*;
|
|
import java.security.spec.*;
|
|
|
|
import org.spongycastle.asn1.ASN1InputStream;
|
|
import org.spongycastle.asn1.DEROutputStream;
|
|
import org.spongycastle.asn1.ASN1Sequence;
|
|
import org.spongycastle.asn1.DERObjectIdentifier;
|
|
import org.spongycastle.asn1.x509.AlgorithmIdentifier;
|
|
|
|
/**
|
|
* This class implements the <code>EncryptedPrivateKeyInfo</code> type
|
|
* as defined in PKCS #8.
|
|
* <p>Its ASN.1 definition is as follows:
|
|
*
|
|
* <pre>
|
|
* EncryptedPrivateKeyInfo ::= SEQUENCE {
|
|
* encryptionAlgorithm AlgorithmIdentifier,
|
|
* encryptedData OCTET STRING }
|
|
*
|
|
* AlgorithmIdentifier ::= SEQUENCE {
|
|
* algorithm OBJECT IDENTIFIER,
|
|
* parameters ANY DEFINED BY algorithm OPTIONAL }
|
|
* </pre>
|
|
*/
|
|
public class EncryptedPrivateKeyInfo
|
|
{
|
|
private org.spongycastle.asn1.pkcs.EncryptedPrivateKeyInfo infoObj;
|
|
private AlgorithmParameters algP;
|
|
|
|
/*
|
|
* Constructs (i.e., parses) an <code>EncryptedPrivateKeyInfo</code> from
|
|
* its ASN.1 encoding.
|
|
*
|
|
* @param encoded the ASN.1 encoding of this object.
|
|
* @exception NullPointerException if the <code>encoded</code> is null.
|
|
* @exception IOException if error occurs when parsing the ASN.1 encoding.
|
|
*/
|
|
public EncryptedPrivateKeyInfo(
|
|
byte[] encoded)
|
|
throws NullPointerException, IOException
|
|
{
|
|
if (encoded == null)
|
|
{
|
|
throw new NullPointerException("parameters null");
|
|
}
|
|
|
|
ByteArrayInputStream bIn = new ByteArrayInputStream(encoded);
|
|
ASN1InputStream dIn = new ASN1InputStream(bIn);
|
|
|
|
infoObj = org.spongycastle.asn1.pkcs.EncryptedPrivateKeyInfo.getInstance((ASN1Sequence)dIn.readObject());
|
|
|
|
try
|
|
{
|
|
algP = this.getParameters();
|
|
}
|
|
catch (NoSuchAlgorithmException e)
|
|
{
|
|
throw new IOException("can't create parameters: " + e.toString());
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Constructs an <code>EncryptedPrivateKeyInfo</code> from the
|
|
* encryption algorithm name and the encrypted data.
|
|
* <p>Note: the <code>encrypedData</code> is cloned when constructing
|
|
* this object.
|
|
* <p>
|
|
* If encryption algorithm has associated parameters use the constructor
|
|
* with AlgorithmParameters as the parameter.
|
|
*
|
|
* @param algName algorithm name.
|
|
* @param encryptedData encrypted data.
|
|
* @exception NullPointerException if <code>algName</code> or <code>encryptedData</code> is null.
|
|
* @exception IllegalArgumentException if <code>encryptedData</code> is empty, i.e. 0-length.
|
|
* @exception NoSuchAlgorithmException if the specified algName is not supported.
|
|
*/
|
|
public EncryptedPrivateKeyInfo(
|
|
String algName,
|
|
byte[] encryptedData)
|
|
throws NullPointerException, IllegalArgumentException, NoSuchAlgorithmException
|
|
{
|
|
if (algName == null || encryptedData == null)
|
|
{
|
|
throw new NullPointerException("parameters null");
|
|
}
|
|
|
|
org.spongycastle.asn1.x509.AlgorithmIdentifier kAlgId = new AlgorithmIdentifier(new DERObjectIdentifier(algName), null);
|
|
|
|
infoObj = new org.spongycastle.asn1.pkcs.EncryptedPrivateKeyInfo(kAlgId, (byte[])encryptedData.clone());
|
|
algP = this.getParameters();
|
|
}
|
|
|
|
/**
|
|
* Constructs an <code>EncryptedPrivateKeyInfo</code> from the
|
|
* encryption algorithm parameters and the encrypted data.
|
|
* <p>Note: the <code>encrypedData</code> is cloned when constructing
|
|
* this object.
|
|
*
|
|
* @param algParams the algorithm parameters for the encryption
|
|
* algorithm. <code>algParams.getEncoded()</code> should return
|
|
* the ASN.1 encoded bytes of the <code>parameters</code> field
|
|
* of the <code>AlgorithmIdentifer</code> component of the
|
|
* <code>EncryptedPrivateKeyInfo</code> type.
|
|
* @param encryptedData encrypted data.
|
|
* @exception NullPointerException if <code>algParams</code> or <code>encryptedData</code> is null.
|
|
* @exception IllegalArgumentException if <code>encryptedData</code> is empty, i.e. 0-length.
|
|
* @exception NoSuchAlgorithmException if the specified algName of the specified <code>algParams</code> parameter is not supported.
|
|
*/
|
|
public EncryptedPrivateKeyInfo(
|
|
AlgorithmParameters algParams,
|
|
byte[] encryptedData)
|
|
throws NullPointerException, IllegalArgumentException, NoSuchAlgorithmException
|
|
{
|
|
if (algParams == null || encryptedData == null)
|
|
{
|
|
throw new NullPointerException("parameters null");
|
|
}
|
|
|
|
org.spongycastle.asn1.x509.AlgorithmIdentifier kAlgId = null;
|
|
|
|
try
|
|
{
|
|
ByteArrayInputStream bIn = new ByteArrayInputStream(algParams.getEncoded());
|
|
ASN1InputStream dIn = new ASN1InputStream(bIn);
|
|
|
|
kAlgId = new AlgorithmIdentifier(
|
|
new DERObjectIdentifier(algParams.getAlgorithm()), dIn.readObject());
|
|
}
|
|
catch (IOException e)
|
|
{
|
|
throw new IllegalArgumentException("error in encoding: " + e.toString());
|
|
}
|
|
|
|
infoObj = new org.spongycastle.asn1.pkcs.EncryptedPrivateKeyInfo(kAlgId, (byte[])encryptedData.clone());
|
|
algP = this.getParameters();
|
|
}
|
|
|
|
/**
|
|
* Returns the encryption algorithm.
|
|
*
|
|
* @returns the algorithm name.
|
|
*/
|
|
public String getAlgName()
|
|
{
|
|
return infoObj.getEncryptionAlgorithm().getObjectId().getId();
|
|
}
|
|
|
|
private AlgorithmParameters getParameters()
|
|
throws NoSuchAlgorithmException
|
|
{
|
|
AlgorithmParameters ap = AlgorithmParameters.getInstance(this.getAlgName());
|
|
ByteArrayOutputStream bOut = new ByteArrayOutputStream();
|
|
DEROutputStream dOut = new DEROutputStream(bOut);
|
|
|
|
try
|
|
{
|
|
dOut.writeObject(infoObj.getEncryptionAlgorithm().getParameters());
|
|
dOut.close();
|
|
|
|
ap.init(bOut.toByteArray());
|
|
}
|
|
catch (IOException e)
|
|
{
|
|
throw new NoSuchAlgorithmException("unable to parse parameters");
|
|
}
|
|
|
|
return ap;
|
|
}
|
|
|
|
/**
|
|
* Returns the algorithm parameters used by the encryption algorithm.
|
|
*
|
|
* @returns the algorithm parameters.
|
|
*/
|
|
public AlgorithmParameters getAlgParameters()
|
|
{
|
|
return algP;
|
|
}
|
|
|
|
/**
|
|
* Returns a copy of the encrypted data.
|
|
*
|
|
* @returns a copy of the encrypted data.
|
|
*/
|
|
public byte[] getEncryptedData()
|
|
{
|
|
return infoObj.getEncryptedData();
|
|
}
|
|
|
|
/**
|
|
* Extract the enclosed PKCS8EncodedKeySpec object from the
|
|
* encrypted data and return it.
|
|
*
|
|
* @return the PKCS8EncodedKeySpec object.
|
|
* @exception InvalidKeySpecException if the given cipher is
|
|
* inappropriate for the encrypted data or the encrypted
|
|
* data is corrupted and cannot be decrypted.
|
|
*/
|
|
public PKCS8EncodedKeySpec getKeySpec(
|
|
Cipher c)
|
|
throws InvalidKeySpecException
|
|
{
|
|
try
|
|
{
|
|
return new PKCS8EncodedKeySpec(c.doFinal(this.getEncryptedData()));
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
throw new InvalidKeySpecException("can't get keySpec: " + e.toString());
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Returns the ASN.1 encoding of this object.
|
|
*
|
|
* @returns the ASN.1 encoding.
|
|
* @throws IOException if error occurs when constructing its ASN.1 encoding.
|
|
*/
|
|
public byte[] getEncoded()
|
|
throws IOException
|
|
{
|
|
ByteArrayOutputStream bOut = new ByteArrayOutputStream();
|
|
DEROutputStream dOut = new DEROutputStream(bOut);
|
|
|
|
dOut.writeObject(infoObj);
|
|
dOut.close();
|
|
|
|
return bOut.toByteArray();
|
|
}
|
|
}
|