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

package com.nimbusds.jose.crypto;

import com.nimbusds.jose.crypto.impl.ContentCryptoProvider;
import java.util.Collection;
import com.nimbusds.jose.crypto.impl.AlgorithmSupportMessage;
import com.nimbusds.jose.JWEAlgorithm;
import com.nimbusds.jose.crypto.impl.JWEHeaderValidation;
import com.nimbusds.jose.JOSEException;
import com.nimbusds.jose.crypto.impl.AAD;
import com.nimbusds.jose.util.Base64URL;
import com.nimbusds.jose.JWEHeader;
import java.util.Set;
import com.nimbusds.jose.jwk.OctetSequenceKey;
import javax.crypto.spec.SecretKeySpec;
import com.nimbusds.jose.KeyLengthException;
import javax.crypto.SecretKey;
import com.nimbusds.jose.crypto.impl.CriticalHeaderParamsDeferral;
import com.nimbusds.jose.shaded.jcip.ThreadSafe;
import com.nimbusds.jose.CriticalHeaderParamsAware;
import com.nimbusds.jose.JWEDecrypter;
import com.nimbusds.jose.crypto.impl.DirectCryptoProvider;

@ThreadSafe
public class DirectDecrypter extends DirectCryptoProvider implements JWEDecrypter, CriticalHeaderParamsAware
{
    private final boolean promiscuousMode;
    private final CriticalHeaderParamsDeferral critPolicy;
    
    public DirectDecrypter(final SecretKey key) throws KeyLengthException {
        this(key, false);
    }
    
    public DirectDecrypter(final SecretKey key, final boolean promiscuousMode) throws KeyLengthException {
        super(key);
        this.critPolicy = new CriticalHeaderParamsDeferral();
        this.promiscuousMode = promiscuousMode;
    }
    
    public DirectDecrypter(final byte[] keyBytes) throws KeyLengthException {
        this(new SecretKeySpec(keyBytes, "AES"), false);
    }
    
    public DirectDecrypter(final OctetSequenceKey octJWK) throws KeyLengthException {
        this(octJWK.toSecretKey("AES"));
    }
    
    public DirectDecrypter(final SecretKey key, final Set<String> defCritHeaders) throws KeyLengthException {
        this(key, defCritHeaders, false);
    }
    
    public DirectDecrypter(final SecretKey key, final Set<String> defCritHeaders, final boolean promiscuousMode) throws KeyLengthException {
        super(key);
        (this.critPolicy = new CriticalHeaderParamsDeferral()).setDeferredCriticalHeaderParams(defCritHeaders);
        this.promiscuousMode = promiscuousMode;
    }
    
    @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 {
        if (!this.promiscuousMode) {
            final JWEAlgorithm alg = JWEHeaderValidation.getAlgorithmAndEnsureNotNull(header);
            if (!alg.equals(JWEAlgorithm.DIR)) {
                throw new JOSEException(AlgorithmSupportMessage.unsupportedJWEAlgorithm(alg, DirectDecrypter.SUPPORTED_ALGORITHMS));
            }
            if (encryptedKey != null) {
                throw new JOSEException("Unexpected present JWE encrypted key");
            }
        }
        if (iv == null) {
            throw new JOSEException("Unexpected present JWE initialization vector (IV)");
        }
        if (authTag == null) {
            throw new JOSEException("Missing JWE authentication tag");
        }
        this.critPolicy.ensureHeaderPasses(header);
        return ContentCryptoProvider.decrypt(header, aad, null, iv, cipherText, authTag, this.getKey(), this.getJCAContext());
    }
}
