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

package com.nimbusds.jose.crypto;

import java.security.SignatureException;
import java.security.InvalidKeyException;
import com.nimbusds.jose.crypto.impl.RSASSA;
import com.nimbusds.jose.ActionRequiredForJWSCompletionException;
import java.security.Signature;
import com.nimbusds.jose.CompletableJWSObjectSigning;
import com.nimbusds.jose.crypto.opts.UserAuthenticationRequired;
import com.nimbusds.jose.util.Base64URL;
import com.nimbusds.jose.JWSHeader;
import com.nimbusds.jose.crypto.impl.RSAKeyUtils;
import com.nimbusds.jose.JOSEException;
import com.nimbusds.jose.jwk.RSAKey;
import com.nimbusds.jose.Option;
import com.nimbusds.jose.crypto.opts.OptionUtils;
import java.security.interfaces.RSAPrivateKey;
import java.util.Collections;
import com.nimbusds.jose.crypto.opts.AllowWeakRSAKey;
import com.nimbusds.jose.JWSSignerOption;
import java.util.Set;
import java.security.PrivateKey;
import com.nimbusds.jose.shaded.jcip.ThreadSafe;
import com.nimbusds.jose.JWSSigner;
import com.nimbusds.jose.crypto.impl.RSASSAProvider;

@ThreadSafe
public class RSASSASigner extends RSASSAProvider implements JWSSigner
{
    private final PrivateKey privateKey;
    private final Set<JWSSignerOption> opts;
    
    public RSASSASigner(final PrivateKey privateKey) {
        this(privateKey, false);
    }
    
    @Deprecated
    public RSASSASigner(final PrivateKey privateKey, final boolean allowWeakKey) {
        this(privateKey, (Set<JWSSignerOption>)(allowWeakKey ? Collections.singleton(AllowWeakRSAKey.getInstance()) : Collections.emptySet()));
    }
    
    public RSASSASigner(final PrivateKey privateKey, final Set<JWSSignerOption> opts) {
        if (privateKey instanceof RSAPrivateKey || "RSA".equalsIgnoreCase(privateKey.getAlgorithm())) {
            OptionUtils.ensureMinRSAPrivateKeySize(this.privateKey = privateKey, this.opts = ((opts != null) ? opts : Collections.emptySet()));
            return;
        }
        throw new IllegalArgumentException("The private key algorithm must be RSA");
    }
    
    public RSASSASigner(final RSAKey rsaJWK) throws JOSEException {
        this(rsaJWK, Collections.emptySet());
    }
    
    @Deprecated
    public RSASSASigner(final RSAKey rsaJWK, final boolean allowWeakKey) throws JOSEException {
        this(RSAKeyUtils.toRSAPrivateKey(rsaJWK), allowWeakKey);
    }
    
    public RSASSASigner(final RSAKey rsaJWK, final Set<JWSSignerOption> opts) throws JOSEException {
        this(RSAKeyUtils.toRSAPrivateKey(rsaJWK), opts);
    }
    
    public PrivateKey getPrivateKey() {
        return this.privateKey;
    }
    
    @Override
    public Base64URL sign(final JWSHeader header, final byte[] signingInput) throws JOSEException {
        final Signature signer = this.getInitiatedSignature(header);
        if (this.opts.contains(UserAuthenticationRequired.getInstance())) {
            throw new ActionRequiredForJWSCompletionException("Authenticate user to complete signing", UserAuthenticationRequired.getInstance(), new CompletableJWSObjectSigning() {
                @Override
                public Signature getInitializedSignature() {
                    return signer;
                }
                
                @Override
                public Base64URL complete() throws JOSEException {
                    return RSASSASigner.this.sign(signingInput, signer);
                }
            });
        }
        return this.sign(signingInput, signer);
    }
    
    private Signature getInitiatedSignature(final JWSHeader header) throws JOSEException {
        final Signature signer = RSASSA.getSignerAndVerifier(header.getAlgorithm(), this.getJCAContext().getProvider());
        try {
            signer.initSign(this.privateKey);
        }
        catch (final InvalidKeyException e) {
            throw new JOSEException("Invalid private RSA key: " + e.getMessage(), e);
        }
        return signer;
    }
    
    private Base64URL sign(final byte[] signingInput, final Signature signer) throws JOSEException {
        try {
            signer.update(signingInput);
            return Base64URL.encode(signer.sign());
        }
        catch (final SignatureException e) {
            throw new JOSEException("RSA signature exception: " + e.getMessage(), e);
        }
    }
}
