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

package com.google.crypto.tink.signature;

import com.google.crypto.tink.proto.KeyData;
import com.google.protobuf.MessageLite;
import com.google.protobuf.Parser;
import com.google.crypto.tink.internal.LegacyKeyManagerImpl;
import com.google.crypto.tink.subtle.RsaSsaPssVerifyJce;
import com.google.crypto.tink.subtle.RsaSsaPssSignJce;
import com.google.crypto.tink.internal.TinkBugException;
import com.google.crypto.tink.KeyTemplate;
import com.google.crypto.tink.internal.KeyManagerRegistry;
import com.google.crypto.tink.internal.MutableKeyCreationRegistry;
import com.google.crypto.tink.internal.MutablePrimitiveRegistry;
import com.google.crypto.tink.internal.MutableParametersRegistry;
import com.google.crypto.tink.signature.internal.RsaSsaPssProtoSerialization;
import java.util.Collections;
import java.util.HashMap;
import com.google.crypto.tink.Parameters;
import java.util.Map;
import com.google.crypto.tink.AccessesPartialKey;
import java.security.GeneralSecurityException;
import java.security.KeyPair;
import com.google.crypto.tink.util.SecretBigInteger;
import com.google.crypto.tink.InsecureSecretKeyAccess;
import java.security.interfaces.RSAPrivateCrtKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.AlgorithmParameterSpec;
import java.security.spec.RSAKeyGenParameterSpec;
import java.math.BigInteger;
import com.google.crypto.tink.subtle.EngineFactory;
import java.security.KeyPairGenerator;
import javax.annotation.Nullable;
import com.google.crypto.tink.config.internal.TinkFipsUtil;
import com.google.crypto.tink.internal.KeyCreator;
import com.google.crypto.tink.KeyManager;
import com.google.crypto.tink.PrivateKeyManager;
import com.google.crypto.tink.PublicKeyVerify;
import com.google.crypto.tink.PublicKeySign;
import com.google.crypto.tink.internal.PrimitiveConstructor;

public final class RsaSsaPssSignKeyManager
{
    private static final PrimitiveConstructor<RsaSsaPssPrivateKey, PublicKeySign> PUBLIC_KEY_SIGN_PRIMITIVE_CONSTRUCTOR;
    private static final PrimitiveConstructor<RsaSsaPssPublicKey, PublicKeyVerify> PUBLIC_KEY_VERIFY_PRIMITIVE_CONSTRUCTOR;
    private static final PrivateKeyManager<PublicKeySign> legacyPrivateKeyManager;
    private static final KeyManager<PublicKeyVerify> legacyPublicKeyManager;
    private static final KeyCreator<RsaSsaPssParameters> KEY_CREATOR;
    private static final TinkFipsUtil.AlgorithmFipsCompatibility FIPS;
    
    static String getKeyType() {
        return "type.googleapis.com/google.crypto.tink.RsaSsaPssPrivateKey";
    }
    
    @AccessesPartialKey
    private static RsaSsaPssPrivateKey createKey(final RsaSsaPssParameters parameters, @Nullable final Integer idRequirement) throws GeneralSecurityException {
        final KeyPairGenerator keyGen = EngineFactory.KEY_PAIR_GENERATOR.getInstance("RSA");
        final RSAKeyGenParameterSpec spec = new RSAKeyGenParameterSpec(parameters.getModulusSizeBits(), new BigInteger(1, parameters.getPublicExponent().toByteArray()));
        keyGen.initialize(spec);
        final KeyPair keyPair = keyGen.generateKeyPair();
        final RSAPublicKey pubKey = (RSAPublicKey)keyPair.getPublic();
        final RSAPrivateCrtKey privKey = (RSAPrivateCrtKey)keyPair.getPrivate();
        final RsaSsaPssPublicKey rsaSsaPssPublicKey = RsaSsaPssPublicKey.builder().setParameters(parameters).setModulus(pubKey.getModulus()).setIdRequirement(idRequirement).build();
        return RsaSsaPssPrivateKey.builder().setPublicKey(rsaSsaPssPublicKey).setPrimes(SecretBigInteger.fromBigInteger(privKey.getPrimeP(), InsecureSecretKeyAccess.get()), SecretBigInteger.fromBigInteger(privKey.getPrimeQ(), InsecureSecretKeyAccess.get())).setPrivateExponent(SecretBigInteger.fromBigInteger(privKey.getPrivateExponent(), InsecureSecretKeyAccess.get())).setPrimeExponents(SecretBigInteger.fromBigInteger(privKey.getPrimeExponentP(), InsecureSecretKeyAccess.get()), SecretBigInteger.fromBigInteger(privKey.getPrimeExponentQ(), InsecureSecretKeyAccess.get())).setCrtCoefficient(SecretBigInteger.fromBigInteger(privKey.getCrtCoefficient(), InsecureSecretKeyAccess.get())).build();
    }
    
    private static Map<String, Parameters> namedParameters() throws GeneralSecurityException {
        final Map<String, Parameters> result = new HashMap<String, Parameters>();
        result.put("RSA_SSA_PSS_3072_SHA256_F4", RsaSsaPssParameters.builder().setSigHashType(RsaSsaPssParameters.HashType.SHA256).setMgf1HashType(RsaSsaPssParameters.HashType.SHA256).setSaltLengthBytes(32).setModulusSizeBits(3072).setPublicExponent(RsaSsaPssParameters.F4).setVariant(RsaSsaPssParameters.Variant.TINK).build());
        result.put("RSA_SSA_PSS_3072_SHA256_F4_RAW", RsaSsaPssParameters.builder().setSigHashType(RsaSsaPssParameters.HashType.SHA256).setMgf1HashType(RsaSsaPssParameters.HashType.SHA256).setSaltLengthBytes(32).setModulusSizeBits(3072).setPublicExponent(RsaSsaPssParameters.F4).setVariant(RsaSsaPssParameters.Variant.NO_PREFIX).build());
        result.put("RSA_SSA_PSS_3072_SHA256_SHA256_32_F4", PredefinedSignatureParameters.RSA_SSA_PSS_3072_SHA256_SHA256_32_F4);
        result.put("RSA_SSA_PSS_4096_SHA512_F4", RsaSsaPssParameters.builder().setSigHashType(RsaSsaPssParameters.HashType.SHA512).setMgf1HashType(RsaSsaPssParameters.HashType.SHA512).setSaltLengthBytes(64).setModulusSizeBits(4096).setPublicExponent(RsaSsaPssParameters.F4).setVariant(RsaSsaPssParameters.Variant.TINK).build());
        result.put("RSA_SSA_PSS_4096_SHA512_F4_RAW", RsaSsaPssParameters.builder().setSigHashType(RsaSsaPssParameters.HashType.SHA512).setMgf1HashType(RsaSsaPssParameters.HashType.SHA512).setSaltLengthBytes(64).setModulusSizeBits(4096).setPublicExponent(RsaSsaPssParameters.F4).setVariant(RsaSsaPssParameters.Variant.NO_PREFIX).build());
        result.put("RSA_SSA_PSS_4096_SHA512_SHA512_64_F4", PredefinedSignatureParameters.RSA_SSA_PSS_4096_SHA512_SHA512_64_F4);
        return Collections.unmodifiableMap((Map<? extends String, ? extends Parameters>)result);
    }
    
    public static void registerPair(final boolean newKeyAllowed) throws GeneralSecurityException {
        if (!RsaSsaPssSignKeyManager.FIPS.isCompatible()) {
            throw new GeneralSecurityException("Can not use RSA SSA PSS in FIPS-mode, as BoringCrypto module is not available.");
        }
        RsaSsaPssProtoSerialization.register();
        MutableParametersRegistry.globalInstance().putAll(namedParameters());
        MutablePrimitiveRegistry.globalInstance().registerPrimitiveConstructor(RsaSsaPssSignKeyManager.PUBLIC_KEY_SIGN_PRIMITIVE_CONSTRUCTOR);
        MutablePrimitiveRegistry.globalInstance().registerPrimitiveConstructor(RsaSsaPssSignKeyManager.PUBLIC_KEY_VERIFY_PRIMITIVE_CONSTRUCTOR);
        MutableKeyCreationRegistry.globalInstance().add(RsaSsaPssSignKeyManager.KEY_CREATOR, RsaSsaPssParameters.class);
        KeyManagerRegistry.globalInstance().registerKeyManagerWithFipsCompatibility(RsaSsaPssSignKeyManager.legacyPrivateKeyManager, RsaSsaPssSignKeyManager.FIPS, newKeyAllowed);
        KeyManagerRegistry.globalInstance().registerKeyManagerWithFipsCompatibility(RsaSsaPssSignKeyManager.legacyPublicKeyManager, RsaSsaPssSignKeyManager.FIPS, false);
    }
    
    public static final KeyTemplate rsa3072PssSha256F4Template() {
        return TinkBugException.exceptionIsBug(() -> KeyTemplate.createFrom(RsaSsaPssParameters.builder().setSigHashType(RsaSsaPssParameters.HashType.SHA256).setMgf1HashType(RsaSsaPssParameters.HashType.SHA256).setSaltLengthBytes(32).setModulusSizeBits(3072).setPublicExponent(RsaSsaPssParameters.F4).setVariant(RsaSsaPssParameters.Variant.TINK).build()));
    }
    
    public static final KeyTemplate rawRsa3072PssSha256F4Template() {
        return TinkBugException.exceptionIsBug(() -> KeyTemplate.createFrom(RsaSsaPssParameters.builder().setSigHashType(RsaSsaPssParameters.HashType.SHA256).setMgf1HashType(RsaSsaPssParameters.HashType.SHA256).setSaltLengthBytes(32).setModulusSizeBits(3072).setPublicExponent(RsaSsaPssParameters.F4).setVariant(RsaSsaPssParameters.Variant.NO_PREFIX).build()));
    }
    
    public static final KeyTemplate rsa4096PssSha512F4Template() {
        return TinkBugException.exceptionIsBug(() -> KeyTemplate.createFrom(RsaSsaPssParameters.builder().setSigHashType(RsaSsaPssParameters.HashType.SHA512).setMgf1HashType(RsaSsaPssParameters.HashType.SHA512).setSaltLengthBytes(64).setModulusSizeBits(4096).setPublicExponent(RsaSsaPssParameters.F4).setVariant(RsaSsaPssParameters.Variant.TINK).build()));
    }
    
    public static final KeyTemplate rawRsa4096PssSha512F4Template() {
        return TinkBugException.exceptionIsBug(() -> KeyTemplate.createFrom(RsaSsaPssParameters.builder().setSigHashType(RsaSsaPssParameters.HashType.SHA512).setMgf1HashType(RsaSsaPssParameters.HashType.SHA512).setSaltLengthBytes(64).setModulusSizeBits(4096).setPublicExponent(RsaSsaPssParameters.F4).setVariant(RsaSsaPssParameters.Variant.NO_PREFIX).build()));
    }
    
    private RsaSsaPssSignKeyManager() {
    }
    
    static {
        PUBLIC_KEY_SIGN_PRIMITIVE_CONSTRUCTOR = PrimitiveConstructor.create(RsaSsaPssSignJce::create, RsaSsaPssPrivateKey.class, PublicKeySign.class);
        PUBLIC_KEY_VERIFY_PRIMITIVE_CONSTRUCTOR = PrimitiveConstructor.create(RsaSsaPssVerifyJce::create, RsaSsaPssPublicKey.class, PublicKeyVerify.class);
        legacyPrivateKeyManager = LegacyKeyManagerImpl.createPrivateKeyManager(getKeyType(), PublicKeySign.class, com.google.crypto.tink.proto.RsaSsaPssPrivateKey.parser());
        legacyPublicKeyManager = LegacyKeyManagerImpl.create(RsaSsaPssVerifyKeyManager.getKeyType(), PublicKeyVerify.class, KeyData.KeyMaterialType.ASYMMETRIC_PUBLIC, com.google.crypto.tink.proto.RsaSsaPssPublicKey.parser());
        KEY_CREATOR = RsaSsaPssSignKeyManager::createKey;
        FIPS = TinkFipsUtil.AlgorithmFipsCompatibility.ALGORITHM_REQUIRES_BORINGCRYPTO;
    }
}
