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

package com.google.crypto.tink.jwt;

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.internal.KeyManagerRegistry;
import com.google.crypto.tink.internal.MutableKeyCreationRegistry;
import com.google.crypto.tink.internal.MutableParametersRegistry;
import com.google.crypto.tink.internal.MutablePrimitiveRegistry;
import com.google.crypto.tink.jwt.internal.JwtRsaSsaPkcs1ProtoSerialization;
import java.util.Collections;
import java.util.HashMap;
import com.google.crypto.tink.Parameters;
import java.util.Map;
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 java.nio.charset.StandardCharsets;
import com.google.crypto.tink.PublicKeySign;
import com.google.crypto.tink.subtle.RsaSsaPkcs1SignJce;
import com.google.crypto.tink.AccessesPartialKey;
import java.security.GeneralSecurityException;
import com.google.crypto.tink.signature.RsaSsaPkcs1PrivateKey;
import com.google.crypto.tink.config.internal.TinkFipsUtil;
import com.google.crypto.tink.internal.KeyCreator;
import com.google.crypto.tink.internal.PrimitiveConstructor;
import com.google.crypto.tink.KeyManager;
import com.google.crypto.tink.PrivateKeyManager;

public final class JwtRsaSsaPkcs1SignKeyManager
{
    private static final PrivateKeyManager<Void> legacyPrivateKeyManager;
    private static final KeyManager<Void> legacyPublicKeyManager;
    private static final PrimitiveConstructor<JwtRsaSsaPkcs1PrivateKey, JwtPublicKeySign> PRIMITIVE_CONSTRUCTOR;
    private static final KeyCreator<JwtRsaSsaPkcs1Parameters> KEY_CREATOR;
    private static final TinkFipsUtil.AlgorithmFipsCompatibility FIPS;
    
    @AccessesPartialKey
    static RsaSsaPkcs1PrivateKey toRsaSsaPkcs1PrivateKey(final JwtRsaSsaPkcs1PrivateKey privateKey) throws GeneralSecurityException {
        return privateKey.getRsaSsaPkcs1PrivateKey();
    }
    
    static JwtPublicKeySign createFullPrimitive(final JwtRsaSsaPkcs1PrivateKey privateKey) throws GeneralSecurityException {
        final RsaSsaPkcs1PrivateKey rsaSsaPkcs1PrivateKey = toRsaSsaPkcs1PrivateKey(privateKey);
        final PublicKeySign signer = RsaSsaPkcs1SignJce.create(rsaSsaPkcs1PrivateKey);
        final String algorithm = privateKey.getParameters().getAlgorithm().getStandardName();
        return new JwtPublicKeySign() {
            @Override
            public String signAndEncode(final RawJwt rawJwt) throws GeneralSecurityException {
                final String unsignedCompact = JwtFormat.createUnsignedCompact(algorithm, privateKey.getPublicKey().getKid(), rawJwt);
                return JwtFormat.createSignedCompact(unsignedCompact, signer.sign(unsignedCompact.getBytes(StandardCharsets.US_ASCII)));
            }
        };
    }
    
    static String getKeyType() {
        return "type.googleapis.com/google.crypto.tink.JwtRsaSsaPkcs1PrivateKey";
    }
    
    @AccessesPartialKey
    private static JwtRsaSsaPkcs1PrivateKey createKey(final JwtRsaSsaPkcs1Parameters 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 JwtRsaSsaPkcs1PublicKey.Builder jwtRsaSsaPkcs1PublicKeyBuilder = JwtRsaSsaPkcs1PublicKey.builder().setParameters(parameters).setModulus(pubKey.getModulus());
        if (idRequirement != null) {
            jwtRsaSsaPkcs1PublicKeyBuilder.setIdRequirement(idRequirement);
        }
        final JwtRsaSsaPkcs1PublicKey jwtRsaSsaPkcs1PublicKey = jwtRsaSsaPkcs1PublicKeyBuilder.build();
        return JwtRsaSsaPkcs1PrivateKey.builder().setPublicKey(jwtRsaSsaPkcs1PublicKey).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("JWT_RS256_2048_F4_RAW", JwtRsaSsaPkcs1Parameters.builder().setModulusSizeBits(2048).setPublicExponent(JwtRsaSsaPkcs1Parameters.F4).setAlgorithm(JwtRsaSsaPkcs1Parameters.Algorithm.RS256).setKidStrategy(JwtRsaSsaPkcs1Parameters.KidStrategy.IGNORED).build());
        result.put("JWT_RS256_2048_F4", JwtRsaSsaPkcs1Parameters.builder().setModulusSizeBits(2048).setPublicExponent(JwtRsaSsaPkcs1Parameters.F4).setAlgorithm(JwtRsaSsaPkcs1Parameters.Algorithm.RS256).setKidStrategy(JwtRsaSsaPkcs1Parameters.KidStrategy.BASE64_ENCODED_KEY_ID).build());
        result.put("JWT_RS256_3072_F4_RAW", JwtRsaSsaPkcs1Parameters.builder().setModulusSizeBits(3072).setPublicExponent(JwtRsaSsaPkcs1Parameters.F4).setAlgorithm(JwtRsaSsaPkcs1Parameters.Algorithm.RS256).setKidStrategy(JwtRsaSsaPkcs1Parameters.KidStrategy.IGNORED).build());
        result.put("JWT_RS256_3072_F4", JwtRsaSsaPkcs1Parameters.builder().setModulusSizeBits(3072).setPublicExponent(JwtRsaSsaPkcs1Parameters.F4).setAlgorithm(JwtRsaSsaPkcs1Parameters.Algorithm.RS256).setKidStrategy(JwtRsaSsaPkcs1Parameters.KidStrategy.BASE64_ENCODED_KEY_ID).build());
        result.put("JWT_RS384_3072_F4_RAW", JwtRsaSsaPkcs1Parameters.builder().setModulusSizeBits(3072).setPublicExponent(JwtRsaSsaPkcs1Parameters.F4).setAlgorithm(JwtRsaSsaPkcs1Parameters.Algorithm.RS384).setKidStrategy(JwtRsaSsaPkcs1Parameters.KidStrategy.IGNORED).build());
        result.put("JWT_RS384_3072_F4", JwtRsaSsaPkcs1Parameters.builder().setModulusSizeBits(3072).setPublicExponent(JwtRsaSsaPkcs1Parameters.F4).setAlgorithm(JwtRsaSsaPkcs1Parameters.Algorithm.RS384).setKidStrategy(JwtRsaSsaPkcs1Parameters.KidStrategy.BASE64_ENCODED_KEY_ID).build());
        result.put("JWT_RS512_4096_F4_RAW", JwtRsaSsaPkcs1Parameters.builder().setModulusSizeBits(4096).setPublicExponent(JwtRsaSsaPkcs1Parameters.F4).setAlgorithm(JwtRsaSsaPkcs1Parameters.Algorithm.RS512).setKidStrategy(JwtRsaSsaPkcs1Parameters.KidStrategy.IGNORED).build());
        result.put("JWT_RS512_4096_F4", JwtRsaSsaPkcs1Parameters.builder().setModulusSizeBits(4096).setPublicExponent(JwtRsaSsaPkcs1Parameters.F4).setAlgorithm(JwtRsaSsaPkcs1Parameters.Algorithm.RS512).setKidStrategy(JwtRsaSsaPkcs1Parameters.KidStrategy.BASE64_ENCODED_KEY_ID).build());
        return Collections.unmodifiableMap((Map<? extends String, ? extends Parameters>)result);
    }
    
    public static void registerPair(final boolean newKeyAllowed) throws GeneralSecurityException {
        if (!JwtRsaSsaPkcs1SignKeyManager.FIPS.isCompatible()) {
            throw new GeneralSecurityException("Can not use RSA SSA PKCS1 in FIPS-mode, as BoringCrypto module is not available.");
        }
        JwtRsaSsaPkcs1ProtoSerialization.register();
        MutablePrimitiveRegistry.globalInstance().registerPrimitiveConstructor(JwtRsaSsaPkcs1VerifyKeyManager.PRIMITIVE_CONSTRUCTOR);
        MutablePrimitiveRegistry.globalInstance().registerPrimitiveConstructor(JwtRsaSsaPkcs1SignKeyManager.PRIMITIVE_CONSTRUCTOR);
        MutableParametersRegistry.globalInstance().putAll(namedParameters());
        MutableKeyCreationRegistry.globalInstance().add(JwtRsaSsaPkcs1SignKeyManager.KEY_CREATOR, JwtRsaSsaPkcs1Parameters.class);
        KeyManagerRegistry.globalInstance().registerKeyManagerWithFipsCompatibility(JwtRsaSsaPkcs1SignKeyManager.legacyPrivateKeyManager, JwtRsaSsaPkcs1SignKeyManager.FIPS, newKeyAllowed);
        KeyManagerRegistry.globalInstance().registerKeyManagerWithFipsCompatibility(JwtRsaSsaPkcs1SignKeyManager.legacyPublicKeyManager, JwtRsaSsaPkcs1SignKeyManager.FIPS, false);
    }
    
    private JwtRsaSsaPkcs1SignKeyManager() {
    }
    
    static {
        legacyPrivateKeyManager = LegacyKeyManagerImpl.createPrivateKeyManager(getKeyType(), Void.class, com.google.crypto.tink.proto.JwtRsaSsaPkcs1PrivateKey.parser());
        legacyPublicKeyManager = LegacyKeyManagerImpl.create(JwtRsaSsaPkcs1VerifyKeyManager.getKeyType(), Void.class, KeyData.KeyMaterialType.ASYMMETRIC_PUBLIC, com.google.crypto.tink.proto.JwtRsaSsaPkcs1PublicKey.parser());
        PRIMITIVE_CONSTRUCTOR = PrimitiveConstructor.create(JwtRsaSsaPkcs1SignKeyManager::createFullPrimitive, JwtRsaSsaPkcs1PrivateKey.class, JwtPublicKeySign.class);
        KEY_CREATOR = JwtRsaSsaPkcs1SignKeyManager::createKey;
        FIPS = TinkFipsUtil.AlgorithmFipsCompatibility.ALGORITHM_REQUIRES_BORINGCRYPTO;
    }
}
