All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.bouncycastle.jcajce.provider.ProvGOST3410 Maven / Gradle / Ivy

Go to download

The FIPS 140-3 Bouncy Castle Crypto package is a Java implementation of cryptographic algorithms certified to FIPS 140-3 level 1. This jar contains JCE provider and low-level API for the BC-FJA version 2.0.0, FIPS Certificate #4743. Please see certificate for certified platform details.

There is a newer version: 2.0.0
Show newest version
package org.bouncycastle.jcajce.provider;

import java.io.IOException;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.InvalidParameterException;
import java.security.Key;
import java.security.KeyPair;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.SecureRandom;
import java.security.spec.AlgorithmParameterSpec;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.KeySpec;

import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers;
import org.bouncycastle.asn1.pkcs.PrivateKeyInfo;
import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
import org.bouncycastle.crypto.Algorithm;
import org.bouncycastle.crypto.AsymmetricKeyPairGenerator;
import org.bouncycastle.crypto.asymmetric.AsymmetricGOST3410PrivateKey;
import org.bouncycastle.crypto.asymmetric.AsymmetricGOST3410PublicKey;
import org.bouncycastle.crypto.asymmetric.AsymmetricKeyPair;
import org.bouncycastle.crypto.asymmetric.GOST3410DomainParameters;
import org.bouncycastle.crypto.asymmetric.GOST3410Parameters;
import org.bouncycastle.crypto.general.GOST3410;
import org.bouncycastle.jcajce.interfaces.GOST3410PrivateKey;
import org.bouncycastle.jcajce.interfaces.GOST3410PublicKey;
import org.bouncycastle.jcajce.spec.GOST3410DomainParameterSpec;
import org.bouncycastle.jcajce.spec.GOST3410ParameterSpec;
import org.bouncycastle.jcajce.spec.GOST3410PrivateKeySpec;
import org.bouncycastle.jcajce.spec.GOST3410PublicKeySpec;

class ProvGOST3410
    extends AsymmetricAlgorithmProvider
{
    private static final String PREFIX = "org.bouncycastle.jcajce.provider.asymmetric" + ".gost.";

    private static final PublicKeyConverter publicKeyConverter = new PublicKeyConverter()
    {
        public AsymmetricGOST3410PublicKey convertKey(Algorithm algorithm, PublicKey key)
            throws InvalidKeyException
        {
            if (key instanceof GOST3410PublicKey)
            {
                if (key instanceof ProvGOST3410PublicKey)
                {
                    return ((ProvGOST3410PublicKey)key).getBaseKey();
                }

                return new ProvGOST3410PublicKey(algorithm, (GOST3410PublicKey)key).getBaseKey();
            }
            else
            {
                // see if we can build a key from key.getEncoded()
                try
                {
                    return new AsymmetricGOST3410PublicKey(algorithm, SubjectPublicKeyInfo.getInstance(Utils.getKeyEncoding(key)));
                }
                catch (Exception e)
                {
                    throw new InvalidKeyException("Cannot identify GOST3410 public key: " + e.getMessage(), e);
                }
            }
        }
    };

    private static final PrivateKeyConverter privateKeyConverter = new PrivateKeyConverter()
    {
        public AsymmetricGOST3410PrivateKey convertKey(Algorithm algorithm, PrivateKey key)
            throws InvalidKeyException
        {
            if (key instanceof GOST3410PrivateKey)
            {
                if (key instanceof ProvGOST3410PrivateKey)
                {
                    return ((ProvGOST3410PrivateKey)key).getBaseKey();
                }

                return new ProvGOST3410PrivateKey(algorithm, (GOST3410PrivateKey)key).getBaseKey();
            }
            else
            {
                // see if we can build a key from key.getEncoded()
                try
                {
                    return new AsymmetricGOST3410PrivateKey(algorithm, PrivateKeyInfo.getInstance(Utils.getKeyEncoding(key)));
                }
                catch (Exception e)
                {
                    throw new InvalidKeyException("Cannot identify GOST3410 private key: " + e.getMessage(), e);
                }
            }
        }
    };

    public void configure(final BouncyCastleFipsProvider provider)
    {
        provider.addAlgorithmImplementation("KeyPairGenerator.GOST3410", PREFIX + "KeyPairGeneratorSpi", new GuardedEngineCreator(new EngineCreator()
        {
            public Object createInstance(Object constructorParameter)
            {
                return new KeyPairGenerator(provider);
            }
        }));
        provider.addAlias("Alg.Alias.KeyPairGenerator.GOST-3410", "GOST3410");
        provider.addAlias("Alg.Alias.KeyPairGenerator.GOST-3410-94", "GOST3410");

        provider.addAlgorithmImplementation("KeyFactory.GOST3410", PREFIX + "KeyFactorySpi", new GuardedEngineCreator(new EngineCreator()
        {
            public Object createInstance(Object constructorParameter)
            {
                return new GOST3410KeyFactory();
            }
        }));

        provider.addAlias("Alg.Alias.KeyFactory.GOST-3410", "GOST3410");
        provider.addAlias("Alg.Alias.KeyFactory.GOST-3410-94", "GOST3410");

        registerOid(provider, CryptoProObjectIdentifiers.gostR3410_94, "GOST3410", new GOST3410KeyFactory());

        provider.addAlgorithmImplementation("Signature.GOST3410", PREFIX + "SignatureSpi", new GuardedEngineCreator(new EngineCreator()
        {
            public Object createInstance(Object constructorParameter)
            {
                return new BaseSignature(provider, new GOST3410.SignatureOperatorFactory(), publicKeyConverter, privateKeyConverter, GOST3410.GOST3410);
            }
        }));

        provider.addAlias("Signature", "GOST3410", "GOST3411WITHGOST3410", "GOST-3410", "GOST-3410-94");
        provider.addAlias("Signature", "GOST3410", CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_94);
    }

    static class KeyPairGenerator
        extends java.security.KeyPairGenerator
    {
        private final BouncyCastleFipsProvider fipsProvider;
        private GOST3410Parameters params;
        private AsymmetricKeyPairGenerator engine;

        private SecureRandom random;
        private boolean initialised = false;

        public KeyPairGenerator(BouncyCastleFipsProvider fipsProvider)
        {
            super("GOST3410");
            this.fipsProvider = fipsProvider;
            this.random = fipsProvider.getDefaultSecureRandom();
        }

        public void initialize(
            int strength)
        {
            initialize(strength, fipsProvider.getDefaultSecureRandom());
        }

        public void initialize(
            int strength,
            SecureRandom random)
        {
            throw new InvalidParameterException("GOST3410 KeyPairGenerator needs to be initialized with a GOST3410ParameterSpec");
        }

        private void init(
            GOST3410ParameterSpec gParams,
            SecureRandom random)
        {
            if (!(gParams.getDomainParametersSpec() instanceof GOST3410DomainParameterSpec))
            {
                throw new InvalidParameterException("GOST3410 KeyPairGenerator needs to be initialized with a GOST3410ParameterSpec");
            }

            params = GOST3410Util.convertToParams((GOST3410ParameterSpec)gParams);
            engine = new GOST3410.KeyPairGenerator(new GOST3410.KeyGenParameters(params), random);
            initialised = true;
        }

        public void initialize(
            AlgorithmParameterSpec params)
            throws InvalidAlgorithmParameterException
        {
            initialize(params, fipsProvider.getDefaultSecureRandom());
        }

        public void initialize(
            AlgorithmParameterSpec params,
            SecureRandom random)
            throws InvalidAlgorithmParameterException
        {
            if (!(params instanceof GOST3410ParameterSpec))
            {
                throw new InvalidAlgorithmParameterException("AlgorithmParameterSpec not recognized: " + params.getClass().getName());
            }

            init((GOST3410ParameterSpec)params, random);
        }

        public KeyPair generateKeyPair()
        {
            if (!initialised)
            {
                init(new GOST3410ParameterSpec(new GOST3410Parameters(CryptoProObjectIdentifiers.gostR3410_94_CryptoPro_A, CryptoProObjectIdentifiers.gostR3411)), random);
            }

            AsymmetricKeyPair pair = engine.generateKeyPair();
            AsymmetricGOST3410PublicKey pub = (AsymmetricGOST3410PublicKey)pair.getPublicKey();
            AsymmetricGOST3410PrivateKey priv = (AsymmetricGOST3410PrivateKey)pair.getPrivateKey();

            return new KeyPair(new ProvGOST3410PublicKey(pub), new ProvGOST3410PrivateKey(priv));
        }
    }

    static class GOST3410KeyFactory
        extends BaseKeyFactory
    {
        public GOST3410KeyFactory()
        {
        }

        protected KeySpec engineGetKeySpec(
            Key key,
            Class spec)
            throws InvalidKeySpecException
        {
            if (spec == null)
            {
                throw new InvalidKeySpecException("null spec is invalid");
            }

            if (spec.isAssignableFrom(GOST3410PublicKeySpec.class) && key instanceof GOST3410PublicKey)
            {
                GOST3410PublicKey k = (GOST3410PublicKey)key;

                return new GOST3410PublicKeySpec(k.getY(), k.getParams());
            }
            else if (spec.isAssignableFrom(GOST3410PrivateKeySpec.class) && key instanceof GOST3410PrivateKey)
            {
                GOST3410PrivateKey k = (GOST3410PrivateKey)key;

                return new GOST3410PrivateKeySpec(k.getX(), k.getParams());
            }

            return super.engineGetKeySpec(key, spec);
        }

        protected Key engineTranslateKey(
            Key key)
            throws InvalidKeyException
        {
            if (key instanceof PublicKey)
            {
                return new ProvGOST3410PublicKey(publicKeyConverter.convertKey(GOST3410.ALGORITHM, (PublicKey)key));
            }
            else if (key instanceof PrivateKey)
            {
                return new ProvGOST3410PrivateKey(privateKeyConverter.convertKey(GOST3410.ALGORITHM, (PrivateKey)key));
            }

            if (key != null)
            {
                throw new InvalidKeyException("Key type unrecognized: " + key.getClass().getName());
            }

            throw new InvalidKeyException("Key is null");
        }

        protected PrivateKey engineGeneratePrivate(
            KeySpec keySpec)
            throws InvalidKeySpecException
        {
            if (keySpec instanceof GOST3410PrivateKeySpec)
            {
                return new ProvGOST3410PrivateKey(GOST3410.ALGORITHM, (GOST3410PrivateKeySpec)keySpec);
            }

            return super.engineGeneratePrivate(keySpec);
        }

        protected PublicKey engineGeneratePublic(
            KeySpec keySpec)
            throws InvalidKeySpecException
        {
            if (keySpec instanceof GOST3410PublicKeySpec)
            {
                return new ProvGOST3410PublicKey(GOST3410.ALGORITHM, (GOST3410PublicKeySpec)keySpec);
            }

            return super.engineGeneratePublic(keySpec);
        }

        public PrivateKey generatePrivate(PrivateKeyInfo keyInfo)
            throws IOException
        {
            return new ProvGOST3410PrivateKey(new AsymmetricGOST3410PrivateKey(GOST3410.ALGORITHM, keyInfo));
        }

        public PublicKey generatePublic(SubjectPublicKeyInfo keyInfo)
            throws IOException
        {
            return new ProvGOST3410PublicKey(new AsymmetricGOST3410PublicKey(GOST3410.ALGORITHM, keyInfo));
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy