/// <summary>
        /// Зашифровать информацию о ключе.
        /// </summary>
        public void Decode(byte[] data)
        {
            if (data == null)
            {
                throw ExceptionUtility.ArgumentNull(nameof(data));
            }

            try
            {
                var asnDecoder = new Asn1BerDecodeBuffer(data);
                var keyWrap    = new Gost_28147_89_KeyWrap();
                keyWrap.Decode(asnDecoder);

                EncryptionParamSet = keyWrap.EncryptedParams.EncryptionParamSet.Oid.Value;
                EncryptedKey       = keyWrap.EncryptedKey.EncryptedKey.Value;
                Mac = keyWrap.EncryptedKey.MacKey.Value;
                Ukm = keyWrap.EncryptedParams.Ukm.Value;
            }
            catch (Exception exception)
            {
                throw ExceptionUtility.CryptographicException(exception, Resources.Asn1DecodeError, nameof(Gost_28147_89_KeyWrap));
            }
        }
        public override int Encode(Asn1BerEncodeBuffer buffer, bool explicitTagging)
        {
            var len = 0;

            if (Ukm != null)
            {
                if (Ukm.Length != 8)
                {
                    throw ExceptionUtility.CryptographicException(Resources.Asn1ConsVioException, nameof(Ukm.Length), Ukm.Length);
                }

                len += Ukm.Encode(buffer, true);
            }

            len += EncryptionParamSet.Encode(buffer, true);

            if (explicitTagging)
            {
                len += buffer.EncodeTagAndLength(Asn1Tag.Sequence, len);
            }

            return(len);
        }
        public override void Decode(Asn1BerDecodeBuffer buffer, bool explicitTagging, int implicitLength)
        {
            var elemLength = explicitTagging ? MatchTag(buffer, Asn1Tag.Sequence) : implicitLength;

            EncryptionParamSet = null;
            ExtElement         = null;

            var context   = new Asn1BerDecodeContext(buffer, elemLength);
            var parsedLen = new IntHolder();

            if (!context.MatchElemTag(0, 0, ObjectIdentifierTypeCode, parsedLen, false))
            {
                throw ExceptionUtility.CryptographicException(Resources.Asn1MissingRequiredException, buffer.ByteCount);
            }

            EncryptionParamSet = new Gost_28147_89_ParamSet();
            EncryptionParamSet.Decode(buffer, true, parsedLen.Value);

            if (!context.Expired())
            {
                if (buffer.PeekTag().Equals(0, 0, ObjectIdentifierTypeCode))
                {
                    throw ExceptionUtility.CryptographicException(Resources.Asn1SeqOrderException);
                }

                ExtElement = new Asn1OpenExt();

                while (!context.Expired())
                {
                    ExtElement.DecodeComponent(buffer);
                }
            }
            else
            {
                ExtElement = null;
            }
        }
Пример #4
0
        public static byte[] StringToBcd(string str)
        {
            int  num2;
            var  buffer = new byte[(str.Length + 1) / 2];
            byte num    = 0;
            var  num3   = num2 = 0;

            while (num3 < str.Length)
            {
                var c    = char.ToUpper(str[num3]);
                var flag = char.IsDigit(c);

                if (!flag && ((c < 'A') || (c >= 'F')))
                {
                    throw ExceptionUtility.CryptographicException(Resources.Asn1ValueParseException, str, num3);
                }

                if ((num3 % 2) != 0)
                { // flag != null
                    num            = (byte)(num | ((byte)(((byte)((flag != false) ? (c - 0x30) : ((c - 0x41) + 10))) << 4)));
                    buffer[num2++] = num;
                }
                else
                {
                    num = flag ? ((byte)(c - '0')) : ((byte)((c - 'A') + 10));
                }

                num3++;
            }

            if ((num3 % 2) != 0)
            {
                buffer[num2++] = (byte)(num | 240);
            }

            return(buffer);
        }
Пример #5
0
        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");
            }
        }
Пример #6
0
        public override void Decode(Asn1BerDecodeBuffer buffer, bool explicitTagging, int implicitLength)
        {
            var elemLength = explicitTagging ? MatchTag(buffer, Asn1Tag.Sequence) : implicitLength;

            Init();

            var context   = new Asn1BerDecodeContext(buffer, elemLength);
            var parsedLen = new IntHolder();

            if (!context.MatchElemTag(0, 0, ObjectIdentifierTypeCode, parsedLen, false))
            {
                throw ExceptionUtility.CryptographicException(Resources.Asn1MissingRequiredException, buffer.ByteCount);
            }

            EncryptionParamSet = new Gost2814789ParamSet();
            EncryptionParamSet.Decode(buffer, true, parsedLen.Value);

            if (context.MatchElemTag(0x80, 0x20, EocTypeCode, parsedLen, true))
            {
                EphemeralPublicKey = new SubjectPublicKeyInfo();
                EphemeralPublicKey.Decode(buffer, false, parsedLen.Value);
            }

            if (!context.MatchElemTag(0, 0, OctetStringTypeCode, parsedLen, false))
            {
                throw ExceptionUtility.CryptographicException(Resources.Asn1MissingRequiredException, buffer.ByteCount);
            }

            Ukm = new Asn1OctetString();
            Ukm.Decode(buffer, true, parsedLen.Value);

            if (Ukm.Length != 8)
            {
                throw ExceptionUtility.CryptographicException(Resources.Asn1ConsVioException, "Ukm.Length", Ukm.Length);
            }
        }
Пример #7
0
        public static string DecodeEncryptionParamSet(byte[] data)
        {
            if (data == null)
            {
                throw ExceptionUtility.ArgumentNull("data");
            }

            string encryptionParamSet;

            try
            {
                var asnDecoder = new Asn1BerDecodeBuffer(data);
                var parameters = new Gost2814789BlobParameters();
                parameters.Decode(asnDecoder);

                encryptionParamSet = Asn1ObjectIdentifier.ToOidString(parameters.EncryptionParamSet);
            }
            catch (Exception exception)
            {
                throw ExceptionUtility.CryptographicException(exception, Resources.Asn1DecodeError, typeof(Gost2814789BlobParameters).FullName);
            }

            return(encryptionParamSet);
        }
        public override void Decode(Asn1BerDecodeBuffer buffer, bool explicitTagging, int implicitLength)
        {
            var elemLength = explicitTagging ? MatchTag(buffer, Asn1Tag.Sequence) : implicitLength;

            SessionEncryptedKey = null;
            TransportParams     = null;

            var context   = new Asn1BerDecodeContext(buffer, elemLength);
            var parsedLen = new IntHolder();

            if (!context.MatchElemTag(0, 0x20, SequenceTypeCode, parsedLen, false))
            {
                throw ExceptionUtility.CryptographicException(Resources.Asn1MissingRequiredException, buffer.ByteCount);
            }

            SessionEncryptedKey = new Gost_28147_89_EncryptedKey();
            SessionEncryptedKey.Decode(buffer, true, parsedLen.Value);

            if (context.MatchElemTag(0x80, 0x20, EocTypeCode, parsedLen, true))
            {
                TransportParams = new Gost_R3410_TransportParams();
                TransportParams.Decode(buffer, false, parsedLen.Value);
            }
        }
Пример #9
0
        public override void Decode(Asn1BerDecodeBuffer buffer, bool explicitTagging, int implicitLength)
        {
            var elemLength = explicitTagging ? MatchTag(buffer, Asn1Tag.Sequence) : implicitLength;

            Init();

            var context   = new Asn1BerDecodeContext(buffer, elemLength);
            var parsedLen = new IntHolder();

            if (!context.MatchElemTag(0, 0, OctetStringTypeCode, parsedLen, false))
            {
                throw ExceptionUtility.CryptographicException(Resources.Asn1MissingRequiredException, buffer.ByteCount);
            }

            EncryptedKey = new Gost2814789Key();
            EncryptedKey.Decode(buffer, true, parsedLen.Value);

            if (context.MatchElemTag(0x80, 0, EocTypeCode, parsedLen, true))
            {
                _maskKey = new Gost2814789Key();
                _maskKey.Decode(buffer, false, parsedLen.Value);
            }

            if (!context.MatchElemTag(0, 0, OctetStringTypeCode, parsedLen, false))
            {
                throw ExceptionUtility.CryptographicException(Resources.Asn1MissingRequiredException, buffer.ByteCount);
            }

            MacKey = new Gost2814789Mac();
            MacKey.Decode(buffer, true, parsedLen.Value);

            if (MacKey.Length != 4)
            {
                throw ExceptionUtility.CryptographicException(Resources.Asn1ConsVioException, "MacKey.Length", MacKey.Length);
            }
        }
Пример #10
0
        private void DecodePublicKey(Gost_R3410_KeyTransport keyTransport)
        {
            var publicKeyInfo   = keyTransport.TransportParams.EphemeralPublicKey;
            var publicKeyAlgOid = publicKeyInfo.Algorithm.Algorithm.Oid.Value;

            if (!publicKeyAlgOid.Equals(KeyAlgorithm.Value))
            {
                throw ExceptionUtility.CryptographicException(Resources.Asn1DecodeAlg, publicKeyAlgOid);
            }

            var choice = publicKeyInfo.Algorithm.Parameters as Asn1Choice;

            if (choice == null)
            {
                throw ExceptionUtility.CryptographicException(Resources.Asn1DecodeAlgorithmParameters);
            }

            var publicKeyParams = choice.GetElement() as Gost_R3410_PublicKeyParams;

            if (publicKeyParams == null)
            {
                throw ExceptionUtility.CryptographicException(Resources.Asn1DecodeAlgorithmParameters);
            }

            var asnDecoder = new Asn1BerDecodeBuffer(publicKeyInfo.SubjectPublicKey.Value);
            var publicKey  = new Asn1OctetString();

            publicKey.Decode(asnDecoder);

            TransportParameters = CreateKeyExchangeParams();
            TransportParameters.DigestParamSet     = publicKeyParams.DigestParamSet.Oid.Value;
            TransportParameters.PublicKeyParamSet  = publicKeyParams.PublicKeyParamSet.Oid.Value;
            TransportParameters.EncryptionParamSet = publicKeyParams.EncryptionParamSet?.Oid.Value;
            TransportParameters.PublicKey          = publicKey.Value;
            TransportParameters.PrivateKey         = null;
        }
        /// <summary>
        /// Расшифровать идентификатор OID параметров шифрования.
        /// </summary>
        public static string DecodeEncryptionParamSet(byte[] data)
        {
            if (data == null)
            {
                throw ExceptionUtility.ArgumentNull(nameof(data));
            }

            string encryptionParamSet;

            try
            {
                var asnDecoder = new Asn1BerDecodeBuffer(data);
                var parameters = new Gost_28147_89_BlobParams();
                parameters.Decode(asnDecoder);

                encryptionParamSet = parameters.EncryptionParamSet.Oid.Value;
            }
            catch (Exception exception)
            {
                throw ExceptionUtility.CryptographicException(exception, Resources.Asn1DecodeError, typeof(Gost_28147_89_BlobParams).FullName);
            }

            return(encryptionParamSet);
        }
Пример #12
0
        public static byte[] ParseString(string data, IntHolder numbits)
        {
            char ch;
            int  num;
            int  num2;
            int  num3;
            int  num4;
            int  num5;

            char ch2 = data[0];

            byte[] buffer;

            switch (ch2)
            {
            case '\'':
            case '"':
                if (!data.EndsWith("B"))
                {
                    if (data.EndsWith("H"))
                    {
                        var builder = new StringBuilder();
                        num3           = (data.Length - 3) * 4;
                        buffer         = AllocBitArray(num3);
                        builder.Length = 2;
                        num            = 1;
                        num2           = 0;
                        ch             = '\0';

                        while ((num < data.Length) && (ch != ch2))
                        {
                            ch = data[num++];

                            if (ch != ch2)
                            {
                                builder[0]     = ch;
                                ch             = (num >= data.Length) ? '0' : data[num];
                                builder[1]     = (ch == ch2) ? '0' : ch;
                                buffer[num2++] = (byte)Convert.ToInt32(builder.ToString(), 0x10);
                            }

                            num++;
                        }
                    }
                    else
                    {
                        if (data[data.Length - 1] != ch2)
                        {
                            throw ExceptionUtility.CryptographicException(Resources.Asn1ValueParseException, data, data.Length - 1);
                        }

                        num3   = (data.Length - 2) * 8;
                        buffer = AllocBitArray(num3);
                        num    = 1;
                        ch     = '\0';

                        while ((num < data.Length) && (ch != ch2))
                        {
                            ch = data[num];

                            if (ch != ch2)
                            {
                                buffer[num - 1] = (byte)ch;
                            }

                            num++;
                        }
                    }

                    return(SetNumBits(numbits, num3, buffer));
                }

                num3   = data.Length - 3;
                buffer = AllocBitArray(num3);
                num5   = 0x80;
                num    = 1;
                num4   = 0;
                num2   = 0;

                while (num < data.Length)
                {
                    ch = data[num];

                    if (ch == '1')
                    {
                        num4 |= num5;
                    }
                    else
                    {
                        if (ch == ch2)
                        {
                            break;
                        }
                        if (ch != '0')
                        {
                            ExceptionUtility.CryptographicException(Resources.Asn1ValueParseException, data, num);
                        }
                    }

                    num5 = num5 >> 1;

                    if (num5 == 0)
                    {
                        buffer[num2++] = (byte)num4;
                        num5           = 0x80;
                        num4           = 0;
                    }

                    num++;
                }
                break;

            default:
                num3   = data.Length * 8;
                buffer = AllocBitArray(num3);
                num    = 0;

                while (num < data.Length)
                {
                    ch          = data[num];
                    buffer[num] = (byte)ch;
                    num++;
                }

                return(SetNumBits(numbits, num3, buffer));
            }

            if (num5 != 0x80)
            {
                buffer[num2] = (byte)num4;
            }

            return(SetNumBits(numbits, num3, buffer));
        }
        public override SymmetricAlgorithm GetDecryptionKey(EncryptedData encryptedData, string symmetricAlgorithmUri)
        {
            if (encryptedData == null)
            {
                throw ExceptionUtility.ArgumentNull("encryptedData");
            }

            SymmetricAlgorithm decryptionKey = null;

            if (encryptedData.KeyInfo != null)
            {
                EncryptedKey encryptedKey = null;

                foreach (var keyInfo in encryptedData.KeyInfo)
                {
                    // Извлечение ключа по имени
                    if (keyInfo is KeyInfoName)
                    {
                        var keyName      = ((KeyInfoName)keyInfo).Value;
                        var keyAlgorithm = KeyNameMapping[keyName];

                        if (keyAlgorithm == null)
                        {
                            var nsManager = new XmlNamespaceManager(Document.NameTable);
                            nsManager.AddNamespace("enc", XmlEncNamespaceUrl);

                            var encryptedKeyNodes = Document.SelectNodes("//enc:EncryptedKey", nsManager);

                            if (encryptedKeyNodes != null)
                            {
                                foreach (XmlElement encryptedKeyNode in encryptedKeyNodes)
                                {
                                    var currentEncryptedKey = new EncryptedKey();
                                    currentEncryptedKey.LoadXml(encryptedKeyNode);

                                    if ((currentEncryptedKey.CarriedKeyName == keyName) && (currentEncryptedKey.Recipient == Recipient))
                                    {
                                        encryptedKey = currentEncryptedKey;
                                        break;
                                    }
                                }
                            }
                        }
                        else
                        {
                            decryptionKey = (SymmetricAlgorithm)keyAlgorithm;
                        }

                        break;
                    }

                    // Извлечение ключа по ссылке
                    if (keyInfo is KeyInfoRetrievalMethod)
                    {
                        var idValue   = GostXmlUtils.ExtractIdFromLocalUri(((KeyInfoRetrievalMethod)keyInfo).Uri);
                        var idElement = GetIdElement(Document, idValue);

                        if (idElement != null)
                        {
                            encryptedKey = new EncryptedKey();
                            encryptedKey.LoadXml(idElement);
                        }

                        break;
                    }

                    // Ключ в готовом виде
                    if (keyInfo is KeyInfoEncryptedKey)
                    {
                        encryptedKey = ((KeyInfoEncryptedKey)keyInfo).EncryptedKey;
                        break;
                    }
                }

                if (decryptionKey == null && encryptedKey != null)
                {
                    if (symmetricAlgorithmUri == null)
                    {
                        if (encryptedData.EncryptionMethod == null)
                        {
                            throw ExceptionUtility.CryptographicException(Resources.XmlMissingAlgorithm);
                        }

                        symmetricAlgorithmUri = encryptedData.EncryptionMethod.KeyAlgorithm;
                    }

                    decryptionKey = DecryptEncryptedKeyClass(encryptedKey, symmetricAlgorithmUri);
                }
            }

            return(decryptionKey);
        }
Пример #14
0
        public static int DecryptData(SafeKeyHandleImpl symKeyHandle, byte[] data, int dataOffset, int dataLength, ref byte[] decryptedData, int decryptedDataOffset, PaddingMode paddingMode, bool isDone)
        {
            if (dataOffset < 0)
            {
                throw ExceptionUtility.ArgumentOutOfRange(nameof(dataOffset));
            }

            if (dataLength < 0)
            {
                throw ExceptionUtility.ArgumentOutOfRange(nameof(dataLength));
            }

            if ((dataOffset > data.Length) || ((dataOffset + dataLength) > data.Length))
            {
                throw ExceptionUtility.ArgumentOutOfRange(nameof(dataOffset), Resources.InvalidDataOffset);
            }

            // Выровненные данные
            var dataAlignLength = (uint)dataLength;
            var dataAlign       = new byte[dataAlignLength];

            Array.Copy(data, dataOffset, dataAlign, 0L, dataAlignLength);

            // Расшифровка данных
            if (!CryptoApi.CryptDecrypt(symKeyHandle, SafeHashHandleImpl.InvalidHandle, false, 0, dataAlign, ref dataAlignLength))
            {
                throw CreateWin32Error();
            }

            var length = (int)dataAlignLength;

            if (isDone)
            {
                byte dataPaddingSize = 0;

                // Удаление дополнения данных в зависимости от настроек
                if (((paddingMode == PaddingMode.PKCS7) || (paddingMode == PaddingMode.ANSIX923)) || (paddingMode == PaddingMode.ISO10126))
                {
                    if (dataAlignLength < 8)
                    {
                        throw ExceptionUtility.CryptographicException(Constants.NTE_BAD_DATA);
                    }

                    // Размер дополнения находится в последнем байте
                    dataPaddingSize = dataAlign[(int)((IntPtr)(dataAlignLength - 1))];

                    if (dataPaddingSize > 8)
                    {
                        throw ExceptionUtility.CryptographicException(Constants.NTE_BAD_DATA);
                    }

                    // Проверка корректности дополнения данных
                    if (paddingMode == PaddingMode.PKCS7)
                    {
                        for (var paddingIndex = dataAlignLength - dataPaddingSize; paddingIndex < (dataAlignLength - 1); paddingIndex++)
                        {
                            if (dataAlign[paddingIndex] != dataPaddingSize)
                            {
                                throw ExceptionUtility.CryptographicException(Constants.NTE_BAD_DATA);
                            }
                        }
                    }
                    else if (paddingMode == PaddingMode.ANSIX923)
                    {
                        for (var paddingIndex = dataAlignLength - dataPaddingSize; paddingIndex < (dataAlignLength - 1); paddingIndex++)
                        {
                            if (dataAlign[paddingIndex] != 0)
                            {
                                throw ExceptionUtility.CryptographicException(Constants.NTE_BAD_DATA);
                            }
                        }
                    }
                }
                else if ((paddingMode != PaddingMode.None) && (paddingMode != PaddingMode.Zeros))
                {
                    throw ExceptionUtility.Argument(nameof(paddingMode), Resources.InvalidPaddingMode);
                }

                length -= dataPaddingSize;
            }

            if (decryptedData == null)
            {
                decryptedData = new byte[length];

                Array.Copy(dataAlign, 0, decryptedData, 0, length);
            }
            else
            {
                if (decryptedDataOffset < 0)
                {
                    throw ExceptionUtility.ArgumentOutOfRange(nameof(decryptedDataOffset));
                }

                if ((decryptedData.Length < length) || ((decryptedData.Length - length) < decryptedDataOffset))
                {
                    throw ExceptionUtility.ArgumentOutOfRange(nameof(decryptedData), Resources.InvalidDataOffset);
                }

                Array.Copy(dataAlign, 0, decryptedData, decryptedDataOffset, length);
            }

            return(length);
        }
Пример #15
0
        public static int EncryptData(ProviderType providerType, SafeKeyHandleImpl symKeyHandle, byte[] data, int dataOffset, int dataLength, ref byte[] encryptedData, int encryptedDataOffset, PaddingMode paddingMode, bool isDone, bool isStream)
        {
            if (dataOffset < 0)
            {
                throw ExceptionUtility.ArgumentOutOfRange(nameof(dataOffset));
            }

            if (dataLength < 0)
            {
                throw ExceptionUtility.ArgumentOutOfRange(nameof(dataLength));
            }

            if (dataOffset > data.Length)
            {
                throw ExceptionUtility.ArgumentOutOfRange(nameof(dataOffset), Resources.InvalidDataOffset);
            }

            var length = dataLength;

            if (isDone)
            {
                length += 8;
            }

            // Выровненные данные
            var dataAlignLength = (uint)dataLength;
            var dataAlignArray  = new byte[length];

            Array.Clear(dataAlignArray, 0, length);
            Array.Copy(data, dataOffset, dataAlignArray, 0, dataLength);

            if (isDone)
            {
                var dataPadding     = dataLength & 7;
                var dataPaddingSize = (byte)(8 - dataPadding);

                // Добпаление дополнения данных в зависимости от настроек
                switch (paddingMode)
                {
                case PaddingMode.None:
                    if ((dataPadding != 0) && !isStream)
                    {
                        throw ExceptionUtility.CryptographicException(Resources.EncryptInvalidDataSize);
                    }

                    break;

                case PaddingMode.Zeros:
                    if (dataPadding != 0)
                    {
                        dataAlignLength += dataPaddingSize;

                        // Дополнение заполняется нулевыми байтами
                    }

                    break;

                case PaddingMode.PKCS7:
                {
                    dataAlignLength += dataPaddingSize;

                    var paddingIndex = dataLength;

                    // Дополнение заполняется байтами, в каждый из которых записывается размер дополнения
                    while (paddingIndex < dataAlignLength)
                    {
                        dataAlignArray[paddingIndex++] = dataPaddingSize;
                    }
                }
                break;

                case PaddingMode.ANSIX923:
                {
                    dataAlignLength += dataPaddingSize;

                    // Дополнение заполняется нулевыми, кроме последнего - в него записывается размер дополнения
                    dataAlignArray[(int)((IntPtr)(dataAlignLength - 1))] = dataPaddingSize;
                }
                break;

                case PaddingMode.ISO10126:
                {
                    dataAlignLength += dataPaddingSize;

                    // Дополнение заполняется случайными байтами, кроме последнего - в него записывается размер дополнения
                    var randomPadding = new byte[dataPaddingSize - 1];
                    GetRandomNumberGenerator(providerType).GetBytes(randomPadding);
                    randomPadding.CopyTo(dataAlignArray, dataLength);
                    dataAlignArray[(int)((IntPtr)(dataAlignLength - 1))] = dataPaddingSize;
                }
                break;

                default:
                    throw ExceptionUtility.Argument(nameof(paddingMode), Resources.InvalidPaddingMode);
                }
            }

            // Шифрование данных
            if (!CryptoApi.CryptEncrypt(symKeyHandle, SafeHashHandleImpl.InvalidHandle, false, 0, dataAlignArray, ref dataAlignLength, (uint)length))
            {
                throw CreateWin32Error();
            }

            // Копирование результата шифрования данных

            if (encryptedData == null)
            {
                encryptedData = new byte[dataAlignLength];

                Array.Copy(dataAlignArray, 0L, encryptedData, 0L, dataAlignLength);
            }
            else
            {
                if (encryptedDataOffset < 0)
                {
                    throw ExceptionUtility.ArgumentOutOfRange(nameof(encryptedDataOffset));
                }

                if ((encryptedData.Length < dataAlignLength) || ((encryptedData.Length - dataAlignLength) < encryptedDataOffset))
                {
                    throw ExceptionUtility.ArgumentOutOfRange(nameof(encryptedDataOffset), Resources.InvalidDataOffset);
                }

                Array.Copy(dataAlignArray, 0L, encryptedData, encryptedDataOffset, dataAlignLength);
            }

            return((int)dataAlignLength);
        }
Пример #16
0
 private static CryptographicException CreateWin32Error()
 {
     return(ExceptionUtility.CryptographicException(Marshal.GetLastWin32Error()));
 }
Пример #17
0
        public override void ParseString(string data)
        {
            if (data == null)
            {
                throw ExceptionUtility.ArgumentNull("data");
            }

            Clear();

            var off = new IntHolder(0);

            try
            {
                YearValue  = ParseInt(data, off, 4);
                MonthValue = ParseInt(data, off, 2);
                DayValue   = ParseInt(data, off, 2);

                if (YearValue < 0)
                {
                    throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidYearValue, YearValue);
                }

                if ((MonthValue < 1) || (MonthValue > 12))
                {
                    throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidMonthValue, MonthValue);
                }

                int num = DaysInMonth[MonthValue];

                if (((MonthValue == 2) && ((YearValue % 4) == 0)) && (((YearValue % 100) != 0) || ((YearValue % 400) == 0)))
                {
                    num++;
                }

                if ((DayValue < 1) || (DayValue > num))
                {
                    throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidDayValue, DayValue);
                }

                var num2 = 0;

                if (!char.IsDigit(CharAt(data, off.Value)))
                {
                    throw ExceptionUtility.CryptographicException(Resources.Asn1HoursExpected);
                }

                HourValue = ParseInt(data, off, 2);
                num2++;

                if (char.IsDigit(CharAt(data, off.Value)))
                {
                    MinuteValue = ParseInt(data, off, 2);
                    num2++;

                    if (char.IsDigit(CharAt(data, off.Value)))
                    {
                        SecondValue = ParseInt(data, off, 2);
                        num2++;
                    }
                }

                if ((num2 >= 1) && ((HourValue < 0) || (HourValue > 0x17)))
                {
                    throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidHourValue, HourValue);
                }

                if ((num2 >= 2) && ((MinuteValue < 0) || (MinuteValue > 0x3b)))
                {
                    throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidMinuteValue, MinuteValue);
                }

                if ((num2 == 3) && ((SecondValue < 0) || (SecondValue > 0x3b)))
                {
                    throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidSecondValue, SecondValue);
                }

                var ch = CharAt(data, off.Value);

                if (DerRules && (ch == ','))
                {
                    throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidDecimalMark);
                }

                if ((ch == '.') || (ch == ','))
                {
                    off.Value++;

                    if (num2 != 3)
                    {
                        throw ExceptionUtility.CryptographicException(Resources.Asn1UnexpectedSymbol);
                    }

                    var length = 0;

                    while (char.IsDigit(CharAt(data, off.Value + length)))
                    {
                        length++;
                    }

                    if (length == 0)
                    {
                        throw ExceptionUtility.CryptographicException(Resources.Asn1UnexpectedSymbol);
                    }

                    SecFraction = data.Substring(off.Value, length);
                    off.Value  += length;
                }

                if (CharAt(data, off.Value) == 'Z')
                {
                    off.Value++;
                    UtcFlag = true;

                    if (off.Value != data.Length)
                    {
                        throw ExceptionUtility.CryptographicException(Resources.Asn1UnexpectedValuesAtEndOfString);
                    }
                }
                else
                {
                    if (DerRules)
                    {
                        throw ExceptionUtility.CryptographicException(Resources.Asn1UnexpectedZoneOffset);
                    }

                    UtcFlag = false;

                    var ch2 = CharAt(data, off.Value);

                    switch (ch2)
                    {
                    case '-':
                    case '+':
                        off.Value++;

                        if (!char.IsDigit(CharAt(data, off.Value)))
                        {
                            throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidDiffHour);
                        }

                        DiffHourValue = ParseInt(data, off, 2);

                        if (char.IsDigit(CharAt(data, off.Value)))
                        {
                            DiffMinValue = ParseInt(data, off, 2);
                        }

                        if ((DiffHourValue < 0) || (DiffHourValue > 12))
                        {
                            throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidDiffHourValue, DiffHourValue);
                        }

                        if ((DiffMinValue < 0) || (DiffMinValue > 0x3b))
                        {
                            throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidDiffMinuteValue, DiffMinValue);
                        }

                        if (ch2 == '-')
                        {
                            DiffHourValue = -DiffHourValue;
                            DiffMinValue  = -DiffMinValue;
                        }
                        break;
                    }
                }

                Parsed = true;

                if (data != Value)
                {
                    CompileString();
                }
            }
            catch (IndexOutOfRangeException)
            {
                throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidDateFormat);
            }
            catch (FormatException)
            {
                throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidNumberFormat);
            }
            catch (ArgumentException)
            {
                throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidDateFormat);
            }
        }
        public static Asn1ObjectIdentifier FromOidString(string value)
        {
            Asn1ObjectIdentifier identifier;

            if (value == null)
            {
                return(null);
            }

            var num = 1;

            foreach (var ch in value)
            {
                if (ch == '.')
                {
                    num++;
                }
            }

            var numArray = new int[num];
            var num2     = 0;

            num = 0;

            while (num2 < value.Length)
            {
                var c = value[num2];

                if (!char.IsDigit(c))
                {
                    throw ExceptionUtility.CryptographicException(Resources.Asn1EncodeErrorWithValue, typeof(Asn1ObjectIdentifier).FullName, value);
                }

                var num3 = 0;

                while (num2 < value.Length)
                {
                    c = value[num2++];

                    if (c == '.')
                    {
                        break;
                    }

                    if (!char.IsDigit(c))
                    {
                        throw ExceptionUtility.CryptographicException(Resources.Asn1EncodeErrorWithValue, typeof(Asn1ObjectIdentifier).FullName, value);
                    }

                    num3 = ((num3 * 10) + c) - 48;
                }

                numArray[num++] = num3;
            }

            try
            {
                identifier = new Asn1ObjectIdentifier(numArray);
            }
            catch (Exception exception)
            {
                throw ExceptionUtility.CryptographicException(exception, Resources.Asn1EncodeError, typeof(Asn1ObjectIdentifier).FullName);
            }

            return(identifier);
        }
Пример #19
0
        public override void Decode(Asn1BerDecodeBuffer buffer, bool explicitTagging, int implicitLength)
        {
            var elemLength = explicitTagging ? MatchTag(buffer, Tag) : implicitLength;
            var lastTag    = buffer.LastTag;

            if ((lastTag == null) || !lastTag.Constructed)
            {
                if (elemLength < 0)
                {
                    throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidLengthException);
                }

                if (elemLength != 0)
                {
                    var num8 = elemLength - 1;
                    var num7 = buffer.Read();

                    if (num7 < 0)
                    {
                        throw ExceptionUtility.CryptographicException(Resources.Asn1EndOfBufferException, buffer.ByteCount);
                    }

                    if ((num7 < 0) || (num7 > 7))
                    {
                        throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidFormatOfBitString, num7);
                    }

                    if ((num8 == 0) && (num7 != 0))
                    {
                        throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidLengthException);
                    }

                    NumBits = (num8 * 8) - num7;
                    Value   = new byte[num8];
                    buffer.Read(Value);
                }
                else
                {
                    NumBits = 0;
                    Value   = null;
                }
            }
            else
            {
                var num3   = 0;
                var offset = 0;
                var index  = -1;
                var num6   = 0;

                var context = new Asn1BerDecodeContext(buffer, elemLength);

                while (!context.Expired())
                {
                    var nbytes = MatchTag(buffer, Tag);

                    if (nbytes <= 0)
                    {
                        throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidFormatOfConstructedValue, buffer.ByteCount);
                    }

                    num3 += nbytes;

                    if (offset == 0)
                    {
                        AllocBitArray(num3 * 8);
                    }
                    else
                    {
                        ReallocBitArray(num3 * 8);
                    }

                    index = offset;
                    buffer.Read(Value, offset, nbytes);
                    offset = num3;
                }

                if (index >= 0)
                {
                    num6 = Value[index];

                    if (((offset - index) - 1) > 0)
                    {
                        Array.Copy(Value, index + 1, Value, index, (offset - index) - 1);
                    }

                    num3--;
                }

                if ((num6 < 0) || (num6 > 7))
                {
                    throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidFormatOfBitString, num6);
                }

                ReallocBitArray((num3 * 8) - num6);

                if (elemLength == Asn1Status.IndefiniteLength)
                {
                    MatchTag(buffer, Asn1Tag.Eoc);
                }
            }

            buffer.TypeCode = 3;
        }
Пример #20
0
        public override void Decode(Asn1BerDecodeBuffer buffer, bool explicitTagging, int implicitLength)
        {
            var length = explicitTagging ? MatchTag(buffer, Tag) : implicitLength;

            if (length == 0)
            {
                Value = 0.0;
            }
            else
            {
                var num2 = buffer.ReadByte();

                if (length == 1)
                {
                    switch (num2)
                    {
                    case PlusInfinity:
                        Value = double.PositiveInfinity;
                        return;

                    case MinusInfinity:
                        Value = double.NegativeInfinity;
                        return;
                    }

                    throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidFormatOfConstructedValue, buffer.ByteCount);
                }

                length--;

                if ((num2 & RealBinary) == 0)
                {
                    var num8 = length;
                    var num9 = 0;

                    var builder = new StringBuilder {
                        Length = num8
                    };

                    while (num8 > 0)
                    {
                        var num7 = buffer.Read();

                        if (num7 == -1)
                        {
                            throw ExceptionUtility.CryptographicException(Resources.Asn1EndOfBufferException, buffer.ByteCount);
                        }

                        builder[num9++] = (char)num7;
                        num8--;
                    }

                    var num10 = num2 & RealIso6093Mask;
                    var num11 = 0;

                    for (var i = 0; i < builder.Length; i++)
                    {
                        var ch = builder[i];

                        if ((num10 >= 2) && (ch == ','))
                        {
                            builder[i] = '.';
                            num11++;
                        }
                        else if (((num10 >= 1) && (((ch >= '0') && (ch <= '9')) || ((ch == '+') || (ch == '-')))) || (((num10 >= 2) && (ch == '.')) || ((num10 == 3) && ((ch == 'E') || (ch == 'e')))))
                        {
                            num11++;
                        }
                        else if ((num11 != 0) || (ch != ' '))
                        {
                            throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidFormatOfConstructedValue, buffer.ByteCount);
                        }
                    }
                    try
                    {
                        Value = double.Parse(builder.ToString());
                    }
                    catch (FormatException)
                    {
                        throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidFormatOfConstructedValue, buffer.ByteCount);
                    }
                }
                else
                {
                    int num6;
                    int num3;

                    switch ((num2 & RealExplenMask))
                    {
                    case RealExplen1:
                        num3 = 1;
                        break;

                    case RealExplen2:
                        num3 = 2;
                        break;

                    case RealExplen3:
                        num3 = 3;
                        break;

                    default:
                        num3 = buffer.ReadByte();
                        length--;
                        break;
                    }

                    var num4 = (int)Asn1RunTime.DecodeIntValue(buffer, num3, true);
                    length -= num3;

                    var num5 = Asn1RunTime.DecodeIntValue(buffer, length, false) * (1L << ((num2 & RealFactorMask) >> 2));

                    switch ((num2 & RealBaseMask))
                    {
                    case RealBase2:
                        num6 = 2;
                        break;

                    case RealBase8:
                        num6 = 8;
                        break;

                    case RealBase16:
                        num6 = 16;
                        break;

                    default:
                        throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidFormatOfConstructedValue, buffer.ByteCount);
                    }

                    Value = num5 * Math.Pow(num6, num4);

                    if ((num2 & PlusInfinity) != 0)
                    {
                        Value = -Value;
                    }
                }

                buffer.TypeCode = RealTypeCode;
            }
        }
Пример #21
0
        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);
        }
Пример #22
0
        protected override AsymmetricAlgorithm GetPublicKey()
        {
            if (KeyInfo == null)
            {
                throw ExceptionUtility.CryptographicException(Resources.XmlKeyInfoRequired);
            }

            if (X509Enumumerable != null)
            {
                var nextCertificatePublicKey = GetNextCertificatePublicKey();

                if (nextCertificatePublicKey != null)
                {
                    return(nextCertificatePublicKey);
                }
            }

            if (KeyInfoEnumerable == null)
            {
                KeyInfoEnumerable = KeyInfo.GetEnumerator();
            }

            var keyInfoEnum = KeyInfoEnumerable;

            while (keyInfoEnum.MoveNext())
            {
                var rsaKeyValue = keyInfoEnum.Current as RSAKeyValue;

                if (rsaKeyValue != null)
                {
                    return(rsaKeyValue.Key);
                }

                var dsaKeyValue = keyInfoEnum.Current as DSAKeyValue;

                if (dsaKeyValue != null)
                {
                    return(dsaKeyValue.Key);
                }

                var gostKeyValue = keyInfoEnum.Current as GostKeyValue;

                if (gostKeyValue != null)
                {
                    return(gostKeyValue.Key);
                }

                var keyInfoX509Data = keyInfoEnum.Current as KeyInfoX509Data;

                if (keyInfoX509Data != null)
                {
                    X509Collection = GostXmlUtils.BuildBagOfCertsVerification(keyInfoX509Data);

                    if (X509Collection.Count > 0)
                    {
                        X509Enumumerable = X509Collection.GetEnumerator();

                        var nextCertificatePublicKey = GetNextCertificatePublicKey();

                        if (nextCertificatePublicKey != null)
                        {
                            return(nextCertificatePublicKey);
                        }
                    }
                }
            }

            return(null);
        }
Пример #23
0
        protected virtual void Decode(Asn1BerDecodeBuffer buffer, bool explicitTagging, int implicitLength, Asn1Tag tag)
        {
            int num2;
            var elemLength = explicitTagging ? MatchTag(buffer, tag) : implicitLength;
            var num3       = elemLength;
            var num4       = 0;

            if (StringBuffer == null)
            {
                StringBuffer = new StringBuilder();
            }

            var lastTag = buffer.LastTag;

            if ((lastTag == null) || !lastTag.Constructed)
            {
                if (num3 < 0)
                {
                    throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidLengthException);
                }

                StringBuffer.Length = num3;

                while (num3 > 0)
                {
                    num2 = buffer.Read();

                    if (num2 == -1)
                    {
                        throw ExceptionUtility.CryptographicException(Resources.Asn1EndOfBufferException, buffer.ByteCount);
                    }

                    StringBuffer[num4++] = (char)num2;
                    num3--;
                }
            }
            else
            {
                var capacity = 0;
                var context  = new Asn1BerDecodeContext(buffer, elemLength);

                while (!context.Expired())
                {
                    var num5 = MatchTag(buffer, Asn1OctetString.Tag);

                    if (num5 <= 0)
                    {
                        throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidFormatOfConstructedValue, buffer.ByteCount);
                    }

                    capacity += num5;
                    StringBuffer.EnsureCapacity(capacity);

                    while (num5 > 0)
                    {
                        num2 = buffer.Read();

                        if (num2 == -1)
                        {
                            throw ExceptionUtility.CryptographicException(Resources.Asn1EndOfBufferException, buffer.ByteCount);
                        }

                        StringBuffer.Append((char)num2);
                        num5--;
                    }
                }

                if (elemLength == Asn1Status.IndefiniteLength)
                {
                    MatchTag(buffer, Asn1Tag.Eoc);
                }
            }

            Value           = StringBuffer.ToString();
            buffer.TypeCode = (short)tag.IdCode;
        }
        /// <summary>
        /// Возвращает параметры ключа на основе XML.
        /// </summary>
        public TKeyParams Deserialize(string keyParametersXml, TKeyParams parameters)
        {
            if (string.IsNullOrEmpty(keyParametersXml))
            {
                throw ExceptionUtility.ArgumentNull(nameof(keyParametersXml));
            }

            var keyValue = SecurityElement.FromString(keyParametersXml);

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

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

            var publicKeyParameters = SelectChildElement(keyValue, PublicKeyParametersTag);

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

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

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

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

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

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

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

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

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

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

            var publicKey = SelectChildElementText(keyValue, PublicKeyTag, false);

            parameters.PublicKey = Convert.FromBase64String(RemoveWhiteSpaces(publicKey));

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

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

            return(parameters);
        }