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

package com.nimbusds.jose.crypto.impl;

import javax.crypto.spec.SecretKeySpec;
import java.security.PrivateKey;
import javax.crypto.Cipher;
import java.security.AlgorithmParameters;
import java.security.InvalidKeyException;
import java.security.Key;
import java.security.spec.AlgorithmParameterSpec;
import javax.crypto.spec.OAEPParameterSpec;
import javax.crypto.spec.PSource;
import com.nimbusds.jose.JOSEException;
import java.security.spec.MGF1ParameterSpec;
import java.security.Provider;
import com.nimbusds.jose.crypto.opts.CipherMode;
import javax.crypto.SecretKey;
import java.security.interfaces.RSAPublicKey;
import com.nimbusds.jose.shaded.jcip.ThreadSafe;

@ThreadSafe
public class RSA_OAEP_SHA2
{
    private static final String RSA_OEAP_256_JCA_ALG = "RSA/ECB/OAEPWithSHA-256AndMGF1Padding";
    private static final String RSA_OEAP_384_JCA_ALG = "RSA/ECB/OAEPWithSHA-384AndMGF1Padding";
    private static final String RSA_OEAP_512_JCA_ALG = "RSA/ECB/OAEPWithSHA-512AndMGF1Padding";
    private static final String SHA_256_JCA_ALG = "SHA-256";
    private static final String SHA_384_JCA_ALG = "SHA-384";
    private static final String SHA_512_JCA_ALG = "SHA-512";
    
    public static byte[] encryptCEK(final RSAPublicKey pub, final SecretKey cek, final int shaBitSize, final CipherMode mode, final Provider provider) throws JOSEException {
        assert mode == CipherMode.ENCRYPT_DECRYPT;
        String jcaAlgName;
        String jcaShaAlgName;
        MGF1ParameterSpec mgf1ParameterSpec;
        if (256 == shaBitSize) {
            jcaAlgName = "RSA/ECB/OAEPWithSHA-256AndMGF1Padding";
            jcaShaAlgName = "SHA-256";
            mgf1ParameterSpec = MGF1ParameterSpec.SHA256;
        }
        else if (384 == shaBitSize) {
            jcaAlgName = "RSA/ECB/OAEPWithSHA-384AndMGF1Padding";
            jcaShaAlgName = "SHA-384";
            mgf1ParameterSpec = MGF1ParameterSpec.SHA384;
        }
        else {
            if (512 != shaBitSize) {
                throw new JOSEException("Unsupported SHA-2 bit size: " + shaBitSize);
            }
            jcaAlgName = "RSA/ECB/OAEPWithSHA-512AndMGF1Padding";
            jcaShaAlgName = "SHA-512";
            mgf1ParameterSpec = MGF1ParameterSpec.SHA512;
        }
        try {
            final AlgorithmParameters algp = AlgorithmParametersHelper.getInstance("OAEP", provider);
            final AlgorithmParameterSpec paramSpec = new OAEPParameterSpec(jcaShaAlgName, "MGF1", mgf1ParameterSpec, PSource.PSpecified.DEFAULT);
            algp.init(paramSpec);
            final Cipher cipher = CipherHelper.getInstance(jcaAlgName, provider);
            cipher.init(mode.getForJWEEncrypter(), pub, algp);
            if (mode == CipherMode.WRAP_UNWRAP) {
                return cipher.wrap(cek);
            }
            return cipher.doFinal(cek.getEncoded());
        }
        catch (final InvalidKeyException e) {
            throw new JOSEException("Encryption failed due to invalid RSA key for SHA-" + shaBitSize + ": The RSA key may be too short, use a longer key", e);
        }
        catch (final Exception e2) {
            throw new JOSEException(e2.getMessage(), e2);
        }
    }
    
    public static SecretKey decryptCEK(final PrivateKey priv, final byte[] encryptedCEK, final int shaBitSize, final CipherMode mode, final Provider provider) throws JOSEException {
        assert mode == CipherMode.ENCRYPT_DECRYPT;
        String jcaAlgName;
        String jcaShaAlgName;
        MGF1ParameterSpec mgf1ParameterSpec;
        if (256 == shaBitSize) {
            jcaAlgName = "RSA/ECB/OAEPWithSHA-256AndMGF1Padding";
            jcaShaAlgName = "SHA-256";
            mgf1ParameterSpec = MGF1ParameterSpec.SHA256;
        }
        else if (384 == shaBitSize) {
            jcaAlgName = "RSA/ECB/OAEPWithSHA-384AndMGF1Padding";
            jcaShaAlgName = "SHA-384";
            mgf1ParameterSpec = MGF1ParameterSpec.SHA384;
        }
        else {
            if (512 != shaBitSize) {
                throw new JOSEException("Unsupported SHA-2 bit size: " + shaBitSize);
            }
            jcaAlgName = "RSA/ECB/OAEPWithSHA-512AndMGF1Padding";
            jcaShaAlgName = "SHA-512";
            mgf1ParameterSpec = MGF1ParameterSpec.SHA512;
        }
        try {
            final AlgorithmParameters algp = AlgorithmParametersHelper.getInstance("OAEP", provider);
            final AlgorithmParameterSpec paramSpec = new OAEPParameterSpec(jcaShaAlgName, "MGF1", mgf1ParameterSpec, PSource.PSpecified.DEFAULT);
            algp.init(paramSpec);
            final Cipher cipher = CipherHelper.getInstance(jcaAlgName, provider);
            cipher.init(mode.getForJWEDecrypter(), priv, algp);
            if (mode == CipherMode.WRAP_UNWRAP) {
                return (SecretKey)cipher.unwrap(encryptedCEK, "AES", 3);
            }
            return new SecretKeySpec(cipher.doFinal(encryptedCEK), "AES");
        }
        catch (final Exception e) {
            throw new JOSEException(e.getMessage(), e);
        }
    }
    
    private RSA_OAEP_SHA2() {
    }
}
