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

package com.nimbusds.jose.crypto;

import com.nimbusds.jose.EncryptionMethod;
import com.nimbusds.jose.crypto.impl.ContentCryptoProvider;
import java.util.Collection;
import com.nimbusds.jose.crypto.impl.AlgorithmSupportMessage;
import com.nimbusds.jose.crypto.impl.RSA_OAEP_SHA2;
import com.nimbusds.jose.crypto.impl.RSA_OAEP;
import com.nimbusds.jose.util.Base64URL;
import com.nimbusds.jose.crypto.impl.RSA1_5;
import com.nimbusds.jose.JWEAlgorithm;
import com.nimbusds.jose.crypto.impl.JWEHeaderValidation;
import com.nimbusds.jose.crypto.opts.CipherMode;
import com.nimbusds.jose.crypto.impl.AAD;
import com.nimbusds.jose.JWECryptoParts;
import com.nimbusds.jose.JWEHeader;
import java.util.Objects;
import java.util.Collections;
import com.nimbusds.jose.JOSEException;
import com.nimbusds.jose.jwk.RSAKey;
import javax.crypto.SecretKey;
import com.nimbusds.jose.JWEEncrypterOption;
import java.util.Set;
import java.security.interfaces.RSAPublicKey;
import com.nimbusds.jose.shaded.jcip.ThreadSafe;
import com.nimbusds.jose.JWEEncrypter;
import com.nimbusds.jose.crypto.impl.RSACryptoProvider;

@ThreadSafe
public class RSAEncrypter extends RSACryptoProvider implements JWEEncrypter
{
    private final RSAPublicKey publicKey;
    private final Set<JWEEncrypterOption> opts;
    
    public RSAEncrypter(final RSAPublicKey publicKey) {
        this(publicKey, null);
    }
    
    public RSAEncrypter(final RSAKey rsaJWK) throws JOSEException {
        this(rsaJWK.toRSAPublicKey());
    }
    
    public RSAEncrypter(final RSAPublicKey publicKey, final SecretKey contentEncryptionKey) {
        this(publicKey, contentEncryptionKey, Collections.emptySet());
    }
    
    public RSAEncrypter(final RSAPublicKey publicKey, final SecretKey contentEncryptionKey, final Set<JWEEncrypterOption> opts) {
        super(contentEncryptionKey);
        this.publicKey = Objects.requireNonNull(publicKey);
        this.opts = ((opts != null) ? opts : Collections.emptySet());
    }
    
    public RSAPublicKey getPublicKey() {
        return this.publicKey;
    }
    
    @Deprecated
    public JWECryptoParts encrypt(final JWEHeader header, final byte[] clearText) throws JOSEException {
        return this.encrypt(header, clearText, AAD.compute(header));
    }
    
    private CipherMode resolveCipherModeForOAEP() {
        if (this.opts.contains(CipherMode.ENCRYPT_DECRYPT)) {
            return CipherMode.ENCRYPT_DECRYPT;
        }
        return CipherMode.WRAP_UNWRAP;
    }
    
    @Override
    public JWECryptoParts encrypt(final JWEHeader header, final byte[] clearText, final byte[] aad) throws JOSEException {
        final JWEAlgorithm alg = JWEHeaderValidation.getAlgorithmAndEnsureNotNull(header);
        final EncryptionMethod enc = header.getEncryptionMethod();
        final SecretKey cek = this.getCEK(enc);
        Base64URL encryptedKey;
        if (alg.equals(JWEAlgorithm.RSA1_5)) {
            encryptedKey = Base64URL.encode(RSA1_5.encryptCEK(this.publicKey, cek, this.getJCAContext().getKeyEncryptionProvider()));
        }
        else if (alg.equals(JWEAlgorithm.RSA_OAEP)) {
            encryptedKey = Base64URL.encode(RSA_OAEP.encryptCEK(this.publicKey, cek, this.resolveCipherModeForOAEP(), this.getJCAContext().getKeyEncryptionProvider()));
        }
        else if (alg.equals(JWEAlgorithm.RSA_OAEP_256)) {
            encryptedKey = Base64URL.encode(RSA_OAEP_SHA2.encryptCEK(this.publicKey, cek, 256, this.resolveCipherModeForOAEP(), this.getJCAContext().getKeyEncryptionProvider()));
        }
        else if (alg.equals(JWEAlgorithm.RSA_OAEP_384)) {
            encryptedKey = Base64URL.encode(RSA_OAEP_SHA2.encryptCEK(this.publicKey, cek, 384, this.resolveCipherModeForOAEP(), this.getJCAContext().getKeyEncryptionProvider()));
        }
        else {
            if (!alg.equals(JWEAlgorithm.RSA_OAEP_512)) {
                throw new JOSEException(AlgorithmSupportMessage.unsupportedJWEAlgorithm(alg, RSAEncrypter.SUPPORTED_ALGORITHMS));
            }
            encryptedKey = Base64URL.encode(RSA_OAEP_SHA2.encryptCEK(this.publicKey, cek, 512, this.resolveCipherModeForOAEP(), this.getJCAContext().getKeyEncryptionProvider()));
        }
        return ContentCryptoProvider.encrypt(header, clearText, aad, cek, encryptedKey, this.getJCAContext());
    }
}
