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

package com.nimbusds.jose.crypto;

import java.util.Collections;
import java.util.LinkedHashSet;
import java.security.interfaces.ECPublicKey;
import com.nimbusds.jose.crypto.impl.ECDH;
import com.nimbusds.jose.crypto.utils.ECChecks;
import com.nimbusds.jose.crypto.impl.AAD;
import com.nimbusds.jose.util.Base64URL;
import com.nimbusds.jose.JWEHeader;
import javax.crypto.SecretKey;
import com.nimbusds.jose.jwk.ECKey;
import com.nimbusds.jose.JOSEException;
import java.security.interfaces.ECPrivateKey;
import com.nimbusds.jose.crypto.impl.CriticalHeaderParamsDeferral;
import java.security.PrivateKey;
import com.nimbusds.jose.jwk.Curve;
import java.util.Set;
import com.nimbusds.jose.CriticalHeaderParamsAware;
import com.nimbusds.jose.JWEDecrypter;
import com.nimbusds.jose.crypto.impl.ECDHCryptoProvider;

public class ECDHDecrypter extends ECDHCryptoProvider implements JWEDecrypter, CriticalHeaderParamsAware
{
    public static final Set<Curve> SUPPORTED_ELLIPTIC_CURVES;
    private final PrivateKey privateKey;
    private final CriticalHeaderParamsDeferral critPolicy;
    
    public ECDHDecrypter(final ECPrivateKey privateKey) throws JOSEException {
        this(privateKey, null);
    }
    
    public ECDHDecrypter(final ECKey ecJWK) throws JOSEException {
        super(ecJWK.getCurve(), null);
        this.critPolicy = new CriticalHeaderParamsDeferral();
        if (!ecJWK.isPrivate()) {
            throw new JOSEException("The EC JWK doesn't contain a private part");
        }
        this.privateKey = ecJWK.toECPrivateKey();
    }
    
    public ECDHDecrypter(final ECPrivateKey privateKey, final Set<String> defCritHeaders) throws JOSEException {
        this(privateKey, defCritHeaders, Curve.forECParameterSpec(privateKey.getParams()));
    }
    
    public ECDHDecrypter(final PrivateKey privateKey, final Set<String> defCritHeaders, final Curve curve) throws JOSEException {
        super(curve, null);
        (this.critPolicy = new CriticalHeaderParamsDeferral()).setDeferredCriticalHeaderParams(defCritHeaders);
        this.privateKey = privateKey;
    }
    
    public PrivateKey getPrivateKey() {
        return this.privateKey;
    }
    
    @Override
    public Set<Curve> supportedEllipticCurves() {
        return ECDHDecrypter.SUPPORTED_ELLIPTIC_CURVES;
    }
    
    @Override
    public Set<String> getProcessedCriticalHeaderParams() {
        return this.critPolicy.getProcessedCriticalHeaderParams();
    }
    
    @Override
    public Set<String> getDeferredCriticalHeaderParams() {
        return this.critPolicy.getProcessedCriticalHeaderParams();
    }
    
    @Deprecated
    public byte[] decrypt(final JWEHeader header, final Base64URL encryptedKey, final Base64URL iv, final Base64URL cipherText, final Base64URL authTag) throws JOSEException {
        return this.decrypt(header, encryptedKey, iv, cipherText, authTag, AAD.compute(header));
    }
    
    @Override
    public byte[] decrypt(final JWEHeader header, final Base64URL encryptedKey, final Base64URL iv, final Base64URL cipherText, final Base64URL authTag, final byte[] aad) throws JOSEException {
        this.critPolicy.ensureHeaderPasses(header);
        final ECKey ephemeralKey = (ECKey)header.getEphemeralPublicKey();
        if (ephemeralKey == null) {
            throw new JOSEException("Missing ephemeral public EC key \"epk\" JWE header parameter");
        }
        final ECPublicKey ephemeralPublicKey = ephemeralKey.toECPublicKey();
        if (this.getPrivateKey() instanceof ECPrivateKey) {
            final ECPrivateKey ecPrivateKey = (ECPrivateKey)this.getPrivateKey();
            if (!ECChecks.isPointOnCurve(ephemeralPublicKey, ecPrivateKey)) {
                throw new JOSEException("Invalid ephemeral public EC key: Point(s) not on the expected curve");
            }
        }
        else if (!ECChecks.isPointOnCurve(ephemeralPublicKey, this.getCurve().toECParameterSpec())) {
            throw new JOSEException("Invalid ephemeral public EC key: Point(s) not on the expected curve");
        }
        final SecretKey Z = ECDH.deriveSharedSecret(ephemeralPublicKey, this.privateKey, this.getJCAContext().getKeyEncryptionProvider());
        return this.decryptWithZ(header, aad, Z, encryptedKey, iv, cipherText, authTag);
    }
    
    static {
        final Set<Curve> curves = new LinkedHashSet<Curve>();
        curves.add(Curve.P_256);
        curves.add(Curve.P_384);
        curves.add(Curve.P_521);
        SUPPORTED_ELLIPTIC_CURVES = Collections.unmodifiableSet((Set<? extends Curve>)curves);
    }
}
