// 
// Decompiled by Procyon v0.6.0
// 

package org.bouncycastle.its.jcajce;

import org.bouncycastle.jcajce.util.NamedJcaJceHelper;
import org.bouncycastle.jcajce.util.ProviderJcaJceHelper;
import java.security.Provider;
import org.bouncycastle.jcajce.util.DefaultJcaJceHelper;
import org.bouncycastle.math.ec.ECPoint;
import org.bouncycastle.math.ec.ECCurve;
import org.bouncycastle.asn1.x9.X9ECParameters;
import java.security.spec.KeySpec;
import java.security.spec.ECPublicKeySpec;
import org.bouncycastle.oer.its.ieee1609dot2.basetypes.EccP384CurvePoint;
import org.bouncycastle.asn1.teletrust.TeleTrusTNamedCurves;
import org.bouncycastle.asn1.nist.NISTNamedCurves;
import org.bouncycastle.asn1.teletrust.TeleTrusTObjectIdentifiers;
import org.bouncycastle.oer.its.ieee1609dot2.basetypes.EccCurvePoint;
import org.bouncycastle.oer.its.ieee1609dot2.basetypes.EccP256CurvePoint;
import org.bouncycastle.oer.its.ieee1609dot2.basetypes.BasePublicEncryptionKey;
import org.bouncycastle.oer.its.ieee1609dot2.basetypes.SymmAlgorithm;
import org.bouncycastle.asn1.ASN1Primitive;
import org.bouncycastle.asn1.sec.SECObjectIdentifiers;
import org.bouncycastle.asn1.ASN1ObjectIdentifier;
import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
import java.security.interfaces.ECPublicKey;
import java.security.PublicKey;
import org.bouncycastle.oer.its.ieee1609dot2.basetypes.PublicEncryptionKey;
import org.bouncycastle.jcajce.util.JcaJceHelper;
import org.bouncycastle.its.ITSPublicEncryptionKey;

public class JceITSPublicEncryptionKey extends ITSPublicEncryptionKey
{
    private final JcaJceHelper helper;
    
    JceITSPublicEncryptionKey(final PublicEncryptionKey publicEncryptionKey, final JcaJceHelper helper) {
        super(publicEncryptionKey);
        this.helper = helper;
    }
    
    JceITSPublicEncryptionKey(final PublicKey publicKey, final JcaJceHelper helper) {
        super(fromPublicKey(publicKey));
        this.helper = helper;
    }
    
    static PublicEncryptionKey fromPublicKey(final PublicKey publicKey) {
        if (!(publicKey instanceof ECPublicKey)) {
            throw new IllegalArgumentException("must be ECPublicKey instance");
        }
        final ECPublicKey ecPublicKey = (ECPublicKey)publicKey;
        final ASN1ObjectIdentifier instance = ASN1ObjectIdentifier.getInstance(SubjectPublicKeyInfo.getInstance(publicKey.getEncoded()).getAlgorithm().getParameters());
        if (instance.equals(SECObjectIdentifiers.secp256r1)) {
            return new PublicEncryptionKey(SymmAlgorithm.aes128Ccm, new BasePublicEncryptionKey.Builder().setChoice(0).setValue(EccP256CurvePoint.uncompressedP256(ecPublicKey.getW().getAffineX(), ecPublicKey.getW().getAffineY())).createBasePublicEncryptionKey());
        }
        if (instance.equals(TeleTrusTObjectIdentifiers.brainpoolP256r1)) {
            return new PublicEncryptionKey(SymmAlgorithm.aes128Ccm, new BasePublicEncryptionKey.Builder().setChoice(1).setValue(EccP256CurvePoint.uncompressedP256(ecPublicKey.getW().getAffineX(), ecPublicKey.getW().getAffineY())).createBasePublicEncryptionKey());
        }
        throw new IllegalArgumentException("unknown curve in public encryption key");
    }
    
    public PublicKey getKey() {
        final BasePublicEncryptionKey publicKey = this.encryptionKey.getPublicKey();
        X9ECParameters x9ECParameters = null;
        switch (publicKey.getChoice()) {
            case 0: {
                x9ECParameters = NISTNamedCurves.getByOID(SECObjectIdentifiers.secp256r1);
                break;
            }
            case 1: {
                x9ECParameters = TeleTrusTNamedCurves.getByOID(TeleTrusTObjectIdentifiers.brainpoolP256r1);
                break;
            }
            default: {
                throw new IllegalStateException("unknown key type");
            }
        }
        if (!(this.encryptionKey.getPublicKey().getBasePublicEncryptionKey() instanceof EccCurvePoint)) {
            throw new IllegalStateException("extension to public verification key not supported");
        }
        final EccCurvePoint eccCurvePoint = (EccCurvePoint)publicKey.getBasePublicEncryptionKey();
        final ECCurve curve = x9ECParameters.getCurve();
        byte[] array;
        if (eccCurvePoint instanceof EccP256CurvePoint) {
            array = eccCurvePoint.getEncodedPoint();
        }
        else {
            if (!(eccCurvePoint instanceof EccP384CurvePoint)) {
                throw new IllegalStateException("unknown key type");
            }
            array = eccCurvePoint.getEncodedPoint();
        }
        final ECPoint normalize = curve.decodePoint(array).normalize();
        try {
            return this.helper.createKeyFactory("EC").generatePublic(new ECPublicKeySpec(ECUtil.convertPoint(normalize), ECUtil.convertToSpec(x9ECParameters)));
        }
        catch (final Exception cause) {
            throw new IllegalStateException(cause.getMessage(), cause);
        }
    }
    
    public static class Builder
    {
        private JcaJceHelper helper;
        
        public Builder() {
            this.helper = new DefaultJcaJceHelper();
        }
        
        public Builder setProvider(final Provider provider) {
            this.helper = new ProviderJcaJceHelper(provider);
            return this;
        }
        
        public Builder setProvider(final String s) {
            this.helper = new NamedJcaJceHelper(s);
            return this;
        }
        
        public JceITSPublicEncryptionKey build(final PublicEncryptionKey publicEncryptionKey) {
            return new JceITSPublicEncryptionKey(publicEncryptionKey, this.helper);
        }
        
        public JceITSPublicEncryptionKey build(final PublicKey publicKey) {
            return new JceITSPublicEncryptionKey(publicKey, this.helper);
        }
    }
}
