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

package com.google.crypto.tink.signature.internal;

import com.google.crypto.tink.subtle.Bytes;
import java.security.spec.AlgorithmParameterSpec;
import java.security.PrivateKey;
import java.security.Signature;
import com.google.crypto.tink.subtle.Validators;
import com.google.crypto.tink.AccessesPartialKey;
import com.google.crypto.tink.signature.RsaSsaPssParameters;
import java.security.spec.KeySpec;
import java.security.spec.RSAPrivateCrtKeySpec;
import com.google.crypto.tink.InsecureSecretKeyAccess;
import java.security.KeyFactory;
import java.security.NoSuchProviderException;
import java.security.GeneralSecurityException;
import com.google.crypto.tink.signature.RsaSsaPssPrivateKey;
import java.security.Provider;
import java.security.spec.PSSParameterSpec;
import java.security.interfaces.RSAPrivateCrtKey;
import com.google.crypto.tink.config.internal.TinkFipsUtil;
import com.google.errorprone.annotations.Immutable;
import com.google.crypto.tink.PublicKeySign;

@Immutable
public final class RsaSsaPssSignConscrypt implements PublicKeySign
{
    public static final TinkFipsUtil.AlgorithmFipsCompatibility FIPS;
    private static final byte[] EMPTY;
    private static final byte[] legacyMessageSuffix;
    private final RSAPrivateCrtKey privateKey;
    private final String signatureAlgorithm;
    private final PSSParameterSpec parameterSpec;
    private final byte[] outputPrefix;
    private final byte[] messageSuffix;
    private final Provider conscrypt;
    
    public static PublicKeySign create(final RsaSsaPssPrivateKey key) throws GeneralSecurityException {
        final Provider conscrypt = RsaSsaPssVerifyConscrypt.conscryptProviderOrNull();
        return createWithProvider(key, conscrypt);
    }
    
    @AccessesPartialKey
    public static PublicKeySign createWithProvider(final RsaSsaPssPrivateKey key, final Provider conscrypt) throws GeneralSecurityException {
        if (conscrypt == null) {
            throw new NoSuchProviderException("RSA SSA PSS using Conscrypt is not supported.");
        }
        final KeyFactory keyFactory = KeyFactory.getInstance("RSA", conscrypt);
        final RsaSsaPssParameters params = key.getParameters();
        final RSAPrivateCrtKey privateKey = (RSAPrivateCrtKey)keyFactory.generatePrivate(new RSAPrivateCrtKeySpec(key.getPublicKey().getModulus(), params.getPublicExponent(), key.getPrivateExponent().getBigInteger(InsecureSecretKeyAccess.get()), key.getPrimeP().getBigInteger(InsecureSecretKeyAccess.get()), key.getPrimeQ().getBigInteger(InsecureSecretKeyAccess.get()), key.getPrimeExponentP().getBigInteger(InsecureSecretKeyAccess.get()), key.getPrimeExponentQ().getBigInteger(InsecureSecretKeyAccess.get()), key.getCrtCoefficient().getBigInteger(InsecureSecretKeyAccess.get())));
        return new RsaSsaPssSignConscrypt(privateKey, params.getSigHashType(), params.getMgf1HashType(), params.getSaltLengthBytes(), key.getOutputPrefix().toByteArray(), params.getVariant().equals(RsaSsaPssParameters.Variant.LEGACY) ? RsaSsaPssSignConscrypt.legacyMessageSuffix : RsaSsaPssSignConscrypt.EMPTY, conscrypt);
    }
    
    private RsaSsaPssSignConscrypt(final RSAPrivateCrtKey privateKey, final RsaSsaPssParameters.HashType sigHash, final RsaSsaPssParameters.HashType mgf1Hash, final int saltLength, final byte[] outputPrefix, final byte[] messageSuffix, final Provider conscrypt) throws GeneralSecurityException {
        if (!RsaSsaPssSignConscrypt.FIPS.isCompatible()) {
            throw new GeneralSecurityException("Cannot use RSA PSS in FIPS-mode, as BoringCrypto module is not available.");
        }
        Validators.validateRsaModulusSize(privateKey.getModulus().bitLength());
        Validators.validateRsaPublicExponent(privateKey.getPublicExponent());
        this.privateKey = privateKey;
        this.signatureAlgorithm = RsaSsaPssVerifyConscrypt.getConscryptRsaSsaPssAlgo(sigHash);
        this.parameterSpec = RsaSsaPssVerifyConscrypt.getPssParameterSpec(sigHash, mgf1Hash, saltLength);
        this.outputPrefix = outputPrefix;
        this.messageSuffix = messageSuffix;
        this.conscrypt = conscrypt;
    }
    
    @Override
    public byte[] sign(final byte[] data) throws GeneralSecurityException {
        final Signature signer = Signature.getInstance(this.signatureAlgorithm, this.conscrypt);
        signer.initSign(this.privateKey);
        signer.setParameter(this.parameterSpec);
        signer.update(data);
        if (this.messageSuffix.length > 0) {
            signer.update(this.messageSuffix);
        }
        final byte[] signature = signer.sign();
        if (this.outputPrefix.length == 0) {
            return signature;
        }
        return Bytes.concat(new byte[][] { this.outputPrefix, signature });
    }
    
    static {
        FIPS = TinkFipsUtil.AlgorithmFipsCompatibility.ALGORITHM_REQUIRES_BORINGCRYPTO;
        EMPTY = new byte[0];
        legacyMessageSuffix = new byte[] { 0 };
    }
}
