// 
// 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.EccCurvePoint;
import org.bouncycastle.asn1.teletrust.TeleTrusTNamedCurves;
import org.bouncycastle.asn1.nist.NISTNamedCurves;
import org.bouncycastle.oer.its.ieee1609dot2.basetypes.EccP384CurvePoint;
import org.bouncycastle.oer.its.ieee1609dot2.basetypes.Point384;
import org.bouncycastle.asn1.teletrust.TeleTrusTObjectIdentifiers;
import org.bouncycastle.asn1.ASN1Encodable;
import org.bouncycastle.oer.its.ieee1609dot2.basetypes.EccP256CurvePoint;
import org.bouncycastle.oer.its.ieee1609dot2.basetypes.Point256;
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.PublicVerificationKey;
import org.bouncycastle.jcajce.util.JcaJceHelper;
import org.bouncycastle.its.ITSPublicVerificationKey;

public class JcaITSPublicVerificationKey extends ITSPublicVerificationKey
{
    private final JcaJceHelper helper;
    
    JcaITSPublicVerificationKey(final PublicVerificationKey publicVerificationKey, final JcaJceHelper helper) {
        super(publicVerificationKey);
        this.helper = helper;
    }
    
    JcaITSPublicVerificationKey(final PublicKey publicKey, final JcaJceHelper helper) {
        super(fromKeyParameters((ECPublicKey)publicKey));
        this.helper = helper;
    }
    
    static PublicVerificationKey fromKeyParameters(final ECPublicKey ecPublicKey) {
        final ASN1ObjectIdentifier instance = ASN1ObjectIdentifier.getInstance(SubjectPublicKeyInfo.getInstance(ecPublicKey.getEncoded()).getAlgorithm().getParameters());
        if (instance.equals(SECObjectIdentifiers.secp256r1)) {
            return new PublicVerificationKey(0, EccP256CurvePoint.uncompressedP256(Point256.builder().setX(ecPublicKey.getW().getAffineX()).setY(ecPublicKey.getW().getAffineY()).createPoint256()));
        }
        if (instance.equals(TeleTrusTObjectIdentifiers.brainpoolP256r1)) {
            return new PublicVerificationKey(1, EccP256CurvePoint.uncompressedP256(Point256.builder().setX(ecPublicKey.getW().getAffineX()).setY(ecPublicKey.getW().getAffineY()).createPoint256()));
        }
        if (instance.equals(TeleTrusTObjectIdentifiers.brainpoolP384r1)) {
            return new PublicVerificationKey(2, EccP384CurvePoint.uncompressedP384(Point384.builder().setX(ecPublicKey.getW().getAffineX()).setY(ecPublicKey.getW().getAffineY()).createPoint384()));
        }
        throw new IllegalArgumentException("unknown curve in public encryption key");
    }
    
    public PublicKey getKey() {
        X9ECParameters x9ECParameters = null;
        switch (this.verificationKey.getChoice()) {
            case 0: {
                x9ECParameters = NISTNamedCurves.getByOID(SECObjectIdentifiers.secp256r1);
                break;
            }
            case 1: {
                x9ECParameters = TeleTrusTNamedCurves.getByOID(TeleTrusTObjectIdentifiers.brainpoolP256r1);
                break;
            }
            case 2: {
                x9ECParameters = TeleTrusTNamedCurves.getByOID(TeleTrusTObjectIdentifiers.brainpoolP384r1);
                break;
            }
            default: {
                throw new IllegalStateException("unknown key type");
            }
        }
        final ECCurve curve = x9ECParameters.getCurve();
        if (!(this.verificationKey.getPublicVerificationKey() instanceof EccCurvePoint)) {
            throw new IllegalStateException("extension to public verification key not supported");
        }
        final EccCurvePoint eccCurvePoint = (EccCurvePoint)this.verificationKey.getPublicVerificationKey();
        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 JcaITSPublicVerificationKey build(final PublicVerificationKey publicVerificationKey) {
            return new JcaITSPublicVerificationKey(publicVerificationKey, this.helper);
        }
        
        public JcaITSPublicVerificationKey build(final PublicKey publicKey) {
            return new JcaITSPublicVerificationKey(publicKey, this.helper);
        }
    }
}
