private static SubjectPublicKeyInfo EncodePublicKey(GostKeyExchangeParameters transportParameters)
        {
            var asnEncoder = new Asn1BerEncodeBuffer();
            var publicKey  = new Asn1OctetString(transportParameters.PublicKey);

            publicKey.Encode(asnEncoder);

            var publicKeyValue = asnEncoder.MsgCopy;

            var publicKeyInfo = new SubjectPublicKeyInfo
            {
                SubjectPublicKey = new Asn1BitString(publicKeyValue.Length * 8, publicKeyValue)
            };

            var publicKeyParams = new GostR34102001PublicKeyParameters
            {
                PublicKeyParamSet  = Asn1ObjectIdentifier.FromOidString(transportParameters.PublicKeyParamSet),
                DigestParamSet     = Asn1ObjectIdentifier.FromOidString(transportParameters.DigestParamSet),
                EncryptionParamSet = CreateEncryptionParamSet(transportParameters.EncryptionParamSet)
            };

            asnEncoder.Reset();
            publicKeyParams.Encode(asnEncoder);

            var publicKeyAlgOid = new Asn1ObjectIdentifier(GostR34102001Constants.IdGostR34102001);

            publicKeyInfo.Algorithm = new AlgorithmIdentifier(publicKeyAlgOid, new Asn1OpenType(asnEncoder.MsgCopy));

            return(publicKeyInfo);
        }
 public GostKeyExchangeParameters(GostKeyExchangeParameters parameters)
 {
     DigestParamSet     = parameters.DigestParamSet;
     PublicKeyParamSet  = parameters.PublicKeyParamSet;
     EncryptionParamSet = parameters.EncryptionParamSet;
     PublicKey          = parameters.PublicKey;
     PrivateKey         = parameters.PrivateKey;
 }
 public GostKeyExchangeParameters(GostKeyExchangeParameters parameters)
 {
     DigestParamSet = parameters.DigestParamSet;
     PublicKeyParamSet = parameters.PublicKeyParamSet;
     EncryptionParamSet = parameters.EncryptionParamSet;
     PublicKey = parameters.PublicKey;
     PrivateKey = parameters.PrivateKey;
 }
        public Gost3410EphemeralAsymmetricAlgorithm(GostKeyExchangeParameters keyParameters)
        {
            if (keyParameters == null)
            {
                throw ExceptionUtility.ArgumentNull("keyParameters");
            }

            _provHandle = CryptoApiHelper.ProviderHandle.DangerousAddRef();
            _keyHandle = CryptoApiHelper.GenerateDhEphemeralKey(_provHandle, keyParameters.DigestParamSet, keyParameters.PublicKeyParamSet);
        }
        public void Decode(byte[] data)
        {
            if (data == null)
            {
                throw ExceptionUtility.ArgumentNull("data");
            }

            try
            {
                var asnDecoder = new Asn1BerDecodeBuffer(data);
                var keyTransport = new GostR3410KeyTransport();
                keyTransport.Decode(asnDecoder);

                SessionEncryptedKey = DecodeSessionKey(keyTransport);
                TransportParameters = DecodePublicKey(keyTransport);
            }
            catch (Exception exception)
            {
                throw ExceptionUtility.CryptographicException(exception, Resources.Asn1DecodeError, typeof(GostR3410KeyTransport).FullName);
            }
        }
        public void Decode(byte[] data)
        {
            if (data == null)
            {
                throw ExceptionUtility.ArgumentNull("data");
            }

            try
            {
                var asnDecoder   = new Asn1BerDecodeBuffer(data);
                var keyTransport = new GostR3410KeyTransport();
                keyTransport.Decode(asnDecoder);

                SessionEncryptedKey = DecodeSessionKey(keyTransport);
                TransportParameters = DecodePublicKey(keyTransport);
            }
            catch (Exception exception)
            {
                throw ExceptionUtility.CryptographicException(exception, Resources.Asn1DecodeError, typeof(GostR3410KeyTransport).FullName);
            }
        }
        public void Decode(byte[] data)
        {
            if (data == null)
            {
                throw ExceptionUtility.ArgumentNull("data");
            }

            try
            {
                var s     = Asn1Sequence.FromByteArray(data) as Asn1Sequence;
                var s0    = s[0] as Asn1Sequence;
                var s1    = (s[1] as Asn1TaggedObject).GetObject() as Asn1Sequence;
                var s11   = (s1[1] as Asn1TaggedObject).GetObject() as Asn1Sequence;
                var s1101 = (s11[0] as Asn1Sequence)[1] as Asn1Sequence;

                SessionEncryptedKey = new GostKeyExchangeInfo
                {
                    EncryptionParamSet = (s1[0] as DerObjectIdentifier).Id,
                    EncryptedKey       = (s0[0] as DerOctetString).GetOctets(),
                    Mac = (s0[1] as DerOctetString).GetOctets(),
                    Ukm = (s1[2] as DerOctetString).GetOctets()
                };
                TransportParameters = new GostKeyExchangeParameters
                {
                    PublicKeyParamSet  = (s1101[0] as DerObjectIdentifier).Id,
                    DigestParamSet     = (s1101[1] as DerObjectIdentifier).Id,
                    EncryptionParamSet = s1101.Count > 2 ? (s1101[2] as DerObjectIdentifier).Id : null,
                    PublicKey          = (DerOctetString.FromByteArray((s11[1] as DerBitString).GetBytes()) as DerOctetString).GetOctets(),
                    PrivateKey         = null
                };
            }
            catch (Exception exception)
            {
                throw ExceptionUtility.CryptographicException(exception, Resources.Asn1DecodeError, "GostR3410KeyTransportDecode");
            }
        }
        public override void ImportParameters(GostKeyExchangeParameters keyParameters)
        {
            if (keyParameters.PrivateKey != null)
            {
                throw ExceptionUtility.NotSupported(Resources.UserImportBulkKeyNotSupported);
            }

            _keyHandle.TryDispose();

            _providerHandle = CryptoApiHelper.ProviderHandle;
            _keyHandle = CryptoApiHelper.ImportPublicKey(_providerHandle, new GostKeyExchangeParameters(keyParameters));

            _isPublicKeyOnly = true;
        }
        public override GostKeyExchangeAlgorithmBase CreateKeyExchange(GostKeyExchangeParameters keyParameters)
        {
            GetKeyPair();

            return new GostKeyExchangeAlgorithm(_providerHandle, _keyHandle, new GostKeyExchangeParameters(keyParameters));
        }
 /// <summary>
 /// Импортирует (дешифрует) параметры ключа, используемого для создания общего секретного ключа.
 /// </summary>
 /// <param name="keyParameters">Параметры ключа, используемого для создания общего секретного ключа.</param>
 /// <exception cref="NotSupportedException"></exception>
 public override void ImportParameters(GostKeyExchangeParameters keyParameters)
 {
     throw ExceptionUtility.NotSupported(Resources.EphemKeyOperationNotSupported);
 }
        private static SubjectPublicKeyInfo EncodePublicKey(GostKeyExchangeParameters transportParameters)
        {
            var asnEncoder = new Asn1BerEncodeBuffer();
            var publicKey = new Asn1OctetString(transportParameters.PublicKey);
            publicKey.Encode(asnEncoder);

            var publicKeyValue = asnEncoder.MsgCopy;

            var publicKeyInfo = new SubjectPublicKeyInfo
                                {
                                    SubjectPublicKey = new Asn1BitString(publicKeyValue.Length * 8, publicKeyValue)
                                };

            var publicKeyParams = new GostR34102001PublicKeyParameters
                             {
                                 PublicKeyParamSet = Asn1ObjectIdentifier.FromOidString(transportParameters.PublicKeyParamSet),
                                 DigestParamSet = Asn1ObjectIdentifier.FromOidString(transportParameters.DigestParamSet),
                                 EncryptionParamSet = CreateEncryptionParamSet(transportParameters.EncryptionParamSet)
                             };

            asnEncoder.Reset();
            publicKeyParams.Encode(asnEncoder);

            var publicKeyAlgOid = new Asn1ObjectIdentifier(GostR34102001Constants.IdGostR34102001);
            publicKeyInfo.Algorithm = new AlgorithmIdentifier(publicKeyAlgOid, new Asn1OpenType(asnEncoder.MsgCopy));

            return publicKeyInfo;
        }
 /// <summary>
 /// Создает общий секретный ключ.
 /// </summary>
 /// <param name="keyParameters">Параметры открытого ключа, используемого для создания общего секретного ключа.</param>
 public abstract GostKeyExchangeAlgorithmBase CreateKeyExchange(GostKeyExchangeParameters keyParameters);
        private static string KeyParametersToXml(GostKeyExchangeParameters parameters)
        {
            var builder = new StringBuilder().AppendFormat("<{0}>", KeyValueXmlTag);

            if ((parameters.DigestParamSet != null) || (parameters.EncryptionParamSet != null) || (parameters.PublicKeyParamSet != null))
            {
                builder.AppendFormat("<{0}>", PublicKeyParametersXmlTag);
                builder.AppendFormat("<{0}>{1}{2}</{0}>", PublicKeyParamSetXmlTag, UrnOidXmlTerm, parameters.PublicKeyParamSet);
                builder.AppendFormat("<{0}>{1}{2}</{0}>", DigestParamSetXmlTag, UrnOidXmlTerm, parameters.DigestParamSet);

                if (parameters.EncryptionParamSet != null)
                {
                    builder.AppendFormat("<{0}>{1}{2}</{0}>", EncryptionParamSetXmlTag, UrnOidXmlTerm, parameters.EncryptionParamSet);
                }

                builder.AppendFormat("</{0}>", PublicKeyParametersXmlTag);
            }

            builder.AppendFormat("<{0}>{1}</{0}>", PublicKeyXmlTag, Convert.ToBase64String(parameters.PublicKey));

            if (parameters.PrivateKey != null)
            {
                builder.AppendFormat("<{0}>{1}</{0}>", PrivateKeyXmlTag, Convert.ToBase64String(parameters.PublicKey));
            }

            builder.AppendFormat("</{0}>", KeyValueXmlTag);

            return builder.ToString();
        }
        private static GostKeyExchangeParameters KeyParametersFromXml(string keyParametersXml)
        {
            var parameters = new GostKeyExchangeParameters();

            var keyValue = SecurityElement.FromString(keyParametersXml);

            if (keyValue == null)
            {
                throw ExceptionUtility.CryptographicException(Resources.InvalidFromXmlString, KeyValueXmlTag);
            }

            keyValue = SelectChildElement(keyValue, KeyValueXmlTag) ?? keyValue;

            var publicKeyParameters = SelectChildElement(keyValue, PublicKeyParametersXmlTag);

            if (publicKeyParameters != null)
            {
                var publicKeyParamSet = RemoveWhiteSpaces(SelectChildElementText(publicKeyParameters, PublicKeyParamSetXmlTag, false));

                if (!publicKeyParamSet.StartsWith(UrnOidXmlTerm, StringComparison.OrdinalIgnoreCase))
                {
                    throw ExceptionUtility.CryptographicException(Resources.InvalidFromXmlString, PublicKeyParamSetXmlTag);
                }

                parameters.PublicKeyParamSet = publicKeyParamSet.Substring(UrnOidXmlTerm.Length);

                var digestParamSet = RemoveWhiteSpaces(SelectChildElementText(publicKeyParameters, DigestParamSetXmlTag, false));

                if (!digestParamSet.StartsWith(UrnOidXmlTerm, StringComparison.OrdinalIgnoreCase))
                {
                    throw ExceptionUtility.CryptographicException(Resources.InvalidFromXmlString, DigestParamSetXmlTag);
                }

                parameters.DigestParamSet = digestParamSet.Substring(UrnOidXmlTerm.Length);

                var encryptionParamSet = SelectChildElementText(publicKeyParameters, EncryptionParamSetXmlTag, true);

                if (!string.IsNullOrEmpty(encryptionParamSet))
                {
                    encryptionParamSet = RemoveWhiteSpaces(encryptionParamSet);

                    if (!encryptionParamSet.StartsWith(UrnOidXmlTerm, StringComparison.OrdinalIgnoreCase))
                    {
                        throw ExceptionUtility.CryptographicException(Resources.InvalidFromXmlString, EncryptionParamSetXmlTag);
                    }

                    parameters.EncryptionParamSet = encryptionParamSet.Substring(UrnOidXmlTerm.Length);
                }
            }

            var publicKey = SelectChildElementText(keyValue, PublicKeyXmlTag, false);
            parameters.PublicKey = Convert.FromBase64String(RemoveWhiteSpaces(publicKey));

            var privateKey = SelectChildElementText(keyValue, PrivateKeyXmlTag, true);

            if (privateKey != null)
            {
                parameters.PrivateKey = Convert.FromBase64String(RemoveWhiteSpaces(privateKey));
            }

            return parameters;
        }
 /// <summary>
 /// Импортирует (дешифрует) параметры ключа, используемого для создания общего секретного ключа.
 /// </summary>
 /// <param name="keyParameters">Параметры ключа, используемого для создания общего секретного ключа.</param>
 public abstract void ImportParameters(GostKeyExchangeParameters keyParameters);
        public static AsymmetricAlgorithm GetPublicKeyAlgorithm(this X509Certificate2 certificate)
        {
            if (certificate == null)
            {
                throw ExceptionUtility.ArgumentNull("certificate");
            }

            var cspObject = new GostKeyExchangeParameters();
            cspObject.DecodeParameters(certificate.PublicKey.EncodedParameters.RawData);
            cspObject.DecodePublicKey(certificate.PublicKey.EncodedKeyValue.RawData);

            var cspBlobData = CryptoApiHelper.EncodePublicBlob(cspObject);

            var publicKey = new Gost3410AsymmetricAlgorithm();
            publicKey.ImportCspBlob(cspBlobData);

            return publicKey;
        }