package org.spongycastle.jce.provider; import java.io.IOException; import java.security.AlgorithmParametersSpi; import java.security.spec.AlgorithmParameterSpec; import java.security.spec.InvalidParameterSpecException; import javax.crypto.spec.PBEParameterSpec; import org.spongycastle.asn1.ASN1EncodableVector; import org.spongycastle.asn1.ASN1Encoding; import org.spongycastle.asn1.ASN1OctetString; import org.spongycastle.asn1.ASN1Primitive; import org.spongycastle.asn1.ASN1Sequence; import org.spongycastle.asn1.DERInteger; import org.spongycastle.asn1.DEROctetString; import org.spongycastle.asn1.DERSequence; import org.spongycastle.asn1.pkcs.PBKDF2Params; import org.spongycastle.asn1.pkcs.PKCS12PBEParams; import org.spongycastle.jce.spec.IESParameterSpec; public abstract class JDKAlgorithmParameters extends AlgorithmParametersSpi { protected boolean isASN1FormatString(String format) { return format == null || format.equals("ASN.1"); } protected AlgorithmParameterSpec engineGetParameterSpec( Class paramSpec) throws InvalidParameterSpecException { if (paramSpec == null) { throw new NullPointerException("argument to getParameterSpec must not be null"); } return localEngineGetParameterSpec(paramSpec); } protected abstract AlgorithmParameterSpec localEngineGetParameterSpec(Class paramSpec) throws InvalidParameterSpecException; public static class PBKDF2 extends JDKAlgorithmParameters { PBKDF2Params params; protected byte[] engineGetEncoded() { try { return params.getEncoded(ASN1Encoding.DER); } catch (IOException e) { throw new RuntimeException("Oooops! " + e.toString()); } } protected byte[] engineGetEncoded( String format) { if (isASN1FormatString(format)) { return engineGetEncoded(); } return null; } protected AlgorithmParameterSpec localEngineGetParameterSpec( Class paramSpec) throws InvalidParameterSpecException { if (paramSpec == PBEParameterSpec.class) { return new PBEParameterSpec(params.getSalt(), params.getIterationCount().intValue()); } throw new InvalidParameterSpecException("unknown parameter spec passed to PKCS12 PBE parameters object."); } protected void engineInit( AlgorithmParameterSpec paramSpec) throws InvalidParameterSpecException { if (!(paramSpec instanceof PBEParameterSpec)) { throw new InvalidParameterSpecException("PBEParameterSpec required to initialise a PKCS12 PBE parameters algorithm parameters object"); } PBEParameterSpec pbeSpec = (PBEParameterSpec)paramSpec; this.params = new PBKDF2Params(pbeSpec.getSalt(), pbeSpec.getIterationCount()); } protected void engineInit( byte[] params) throws IOException { this.params = PBKDF2Params.getInstance(ASN1Primitive.fromByteArray(params)); } protected void engineInit( byte[] params, String format) throws IOException { if (isASN1FormatString(format)) { engineInit(params); return; } throw new IOException("Unknown parameters format in PWRIKEK parameters object"); } protected String engineToString() { return "PBKDF2 Parameters"; } } public static class PKCS12PBE extends JDKAlgorithmParameters { PKCS12PBEParams params; protected byte[] engineGetEncoded() { try { return params.getEncoded(ASN1Encoding.DER); } catch (IOException e) { throw new RuntimeException("Oooops! " + e.toString()); } } protected byte[] engineGetEncoded( String format) { if (isASN1FormatString(format)) { return engineGetEncoded(); } return null; } protected AlgorithmParameterSpec localEngineGetParameterSpec( Class paramSpec) throws InvalidParameterSpecException { if (paramSpec == PBEParameterSpec.class) { return new PBEParameterSpec(params.getIV(), params.getIterations().intValue()); } throw new InvalidParameterSpecException("unknown parameter spec passed to PKCS12 PBE parameters object."); } protected void engineInit( AlgorithmParameterSpec paramSpec) throws InvalidParameterSpecException { if (!(paramSpec instanceof PBEParameterSpec)) { throw new InvalidParameterSpecException("PBEParameterSpec required to initialise a PKCS12 PBE parameters algorithm parameters object"); } PBEParameterSpec pbeSpec = (PBEParameterSpec)paramSpec; this.params = new PKCS12PBEParams(pbeSpec.getSalt(), pbeSpec.getIterationCount()); } protected void engineInit( byte[] params) throws IOException { this.params = PKCS12PBEParams.getInstance(ASN1Primitive.fromByteArray(params)); } protected void engineInit( byte[] params, String format) throws IOException { if (isASN1FormatString(format)) { engineInit(params); return; } throw new IOException("Unknown parameters format in PKCS12 PBE parameters object"); } protected String engineToString() { return "PKCS12 PBE Parameters"; } } public static class IES extends JDKAlgorithmParameters { IESParameterSpec currentSpec; /** * in the absence of a standard way of doing it this will do for * now... */ protected byte[] engineGetEncoded() { try { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(new DEROctetString(currentSpec.getDerivationV())); v.add(new DEROctetString(currentSpec.getEncodingV())); v.add(new DERInteger(currentSpec.getMacKeySize())); return new DERSequence(v).getEncoded(ASN1Encoding.DER); } catch (IOException e) { throw new RuntimeException("Error encoding IESParameters"); } } protected byte[] engineGetEncoded( String format) { if (isASN1FormatString(format) || format.equalsIgnoreCase("X.509")) { return engineGetEncoded(); } return null; } protected AlgorithmParameterSpec localEngineGetParameterSpec( Class paramSpec) throws InvalidParameterSpecException { if (paramSpec == IESParameterSpec.class) { return currentSpec; } throw new InvalidParameterSpecException("unknown parameter spec passed to ElGamal parameters object."); } protected void engineInit( AlgorithmParameterSpec paramSpec) throws InvalidParameterSpecException { if (!(paramSpec instanceof IESParameterSpec)) { throw new InvalidParameterSpecException("IESParameterSpec required to initialise a IES algorithm parameters object"); } this.currentSpec = (IESParameterSpec)paramSpec; } protected void engineInit( byte[] params) throws IOException { try { ASN1Sequence s = (ASN1Sequence)ASN1Primitive.fromByteArray(params); this.currentSpec = new IESParameterSpec( ((ASN1OctetString)s.getObjectAt(0)).getOctets(), ((ASN1OctetString)s.getObjectAt(0)).getOctets(), ((DERInteger)s.getObjectAt(0)).getValue().intValue()); } catch (ClassCastException e) { throw new IOException("Not a valid IES Parameter encoding."); } catch (ArrayIndexOutOfBoundsException e) { throw new IOException("Not a valid IES Parameter encoding."); } } protected void engineInit( byte[] params, String format) throws IOException { if (isASN1FormatString(format) || format.equalsIgnoreCase("X.509")) { engineInit(params); } else { throw new IOException("Unknown parameter format " + format); } } protected String engineToString() { return "IES Parameters"; } } }