Example #1
0
        /// <summary>
        /// Invokes the specified data.
        /// </summary>
        /// <typeparam name="TInput">The type of the input.</typeparam>
        /// <typeparam name="TOutput">The type of the output.</typeparam>
        /// <param name="uri">The URI.</param>
        /// <param name="data">The data.</param>
        /// <param name="rsaProvider">The RSA provider.</param>
        /// <param name="clientId">The client identifier.</param>
        /// <returns></returns>
        internal static TOutput Invoke <TInput, TOutput>(this Uri uri, ClassicVirtualSecuredRequestMessagePackage <TInput> data, RSACryptoServiceProvider rsaProvider, string clientId = null)
        {
            if (uri != null && data != null && rsaProvider != null)
            {
                try
                {
                    var httpRequest = uri.CreateHttpWebRequest(HttpConstants.HttpMethod.Post);

                    if (!string.IsNullOrWhiteSpace(clientId))
                    {
                        httpRequest.SafeSetHttpHeader(VirtualSecuredTransferProtocolConstants.headerKey_ClientId, clientId);
                    }

                    var aesKeys     = AesKeys.Create();
                    var aesProvider = aesKeys.CreateAesProvider();

                    var requestRawMessage = new VirtualSecuredRequestRawMessage
                    {
                        Data                  = Encoding.UTF8.GetBytes(data.ToJson(false)),
                        SchemaVersion         = _schemaVersion,
                        SymmetricPrimaryKey   = aesKeys.Key,
                        SymmetricSecondaryKey = aesKeys.InitializationVector
                    };

                    httpRequest.FillData(HttpConstants.HttpMethod.Post, PackToBytes(requestRawMessage, rsaProvider.GetRsaKeys().PublicKey, aesProvider));

                    var httpResult    = httpRequest.ReadResponseAsBytes();
                    var responseBytes = httpResult.Body;

                    var responseRawMessage = UnpackResponseFromBytes(responseBytes, rsaProvider, aesProvider);

                    if (httpResult.HttpStatusCode.IsOK())
                    {
                        return(Encoding.UTF8.GetString(responseRawMessage.Data).TryConvertJsonToObject <TOutput>());
                    }
                    else
                    {
                        var exception = Encoding.UTF8.GetString(responseRawMessage.Data).TryConvertJsonToObject <ExceptionInfo>();

                        if (exception != null)
                        {
                            throw exception.ToException().Handle(new { uri, data });
                        }
                        else
                        {
                            throw ExceptionFactory.CreateOperationException(new { uri, data });
                        }
                    }
                }
                catch (Exception ex)
                {
                    throw ex.Handle(new { uri, data });
                }
            }

            return(default(TOutput));
        }
Example #2
0
        /// <summary>
        /// Unpacks from bytes.
        /// </summary>
        /// <param name="requestBytes">The request bytes.</param>
        /// <param name="rsaProvider">The RSA provider.</param>
        /// <param name="aesProvider">The aes provider.</param>
        /// <returns></returns>
        public static VirtualSecuredRequestRawMessage UnpackRequestFromBytes(this byte[] requestBytes, RSACryptoServiceProvider rsaProvider, out RijndaelProvider aesProvider)
        {
            // Byte[] composition: [Schema Version]{1}[UTC Stamp]{4}[Encrypted Security Key Length Indication]{2+2}[Encrypted Security Key]{M+N}[Encrypted Body]{L}.
            aesProvider = null;

            try
            {
                rsaProvider.CheckNullObject(nameof(rsaProvider));
                requestBytes.CheckNullOrEmptyCollection(nameof(requestBytes));

                var result = new VirtualSecuredRequestRawMessage
                {
                    // Index1
                    SchemaVersion = Convert.ToInt32(requestBytes[0])
                };

                var currentIndex = 1;
                // Index2
                var stampBytes = requestBytes.Read(_stampIndicationByteLength, ref currentIndex);
                result.Stamp = GetUtcStampFromOffsetBytes(stampBytes);

                ValidateStamp(result.Stamp);

                // Index3
                var primaryKeyLengthBytes   = requestBytes.Read(_securityKeyIndicationByteLength, ref currentIndex);
                var primaryKeyLength        = BitConverter.ToUInt16(primaryKeyLengthBytes, 0);
                var secondaryKeyLengthBytes = requestBytes.Read(_securityKeyIndicationByteLength, ref currentIndex);
                var secondaryKeyLength      = BitConverter.ToUInt16(secondaryKeyLengthBytes, 0);

                // Index4
                var primaryKeyBytes = requestBytes.Read(primaryKeyLength, ref currentIndex);
                result.SymmetricPrimaryKey = rsaProvider.Decrypt(primaryKeyBytes, true);

                var secondaryKeyBytes = requestBytes.Read(secondaryKeyLength, ref currentIndex);
                result.SymmetricSecondaryKey = secondaryKeyBytes == null ? null : rsaProvider.Decrypt(secondaryKeyBytes, true);

                aesProvider = new AesKeys {
                    KeySize = dwKeySize, InitializationVector = result.SymmetricSecondaryKey, Key = result.SymmetricPrimaryKey
                }.CreateAesProvider();

                // Index5
                var dataBytes = requestBytes.SubArray(currentIndex);
                result.Data = aesProvider.DecryptAes(dataBytes);

                return(result);
            }
            catch (Exception ex)
            {
                throw ex.Handle();
            }
        }
Example #3
0
        /// <summary>
        /// Packs to bytes.
        /// </summary>
        /// <param name="requestMessage">The request message.</param>
        /// <param name="rsaPublicKey">The RSA public key.</param>
        /// <param name="aesProvider">The aes provider.</param>
        /// <returns></returns>
        public static byte[] PackToBytes(this VirtualSecuredRequestRawMessage requestMessage, CryptoKey rsaPublicKey, RijndaelProvider aesProvider)
        {
            // Byte[] composition: [Schema Version]{1}[UTC Stamp]{4}[Encrypted Security Key Length Indication]{2+2}[Encrypted Security Key]{M+N}[Encrypted Body]{L}.

            try
            {
                rsaPublicKey.CheckNullObject(nameof(rsaPublicKey));
                aesProvider.CheckNullObject(nameof(aesProvider));

                requestMessage.CheckNullObject(nameof(requestMessage));
                requestMessage.SymmetricPrimaryKey.CheckNullObject(nameof(requestMessage.SymmetricPrimaryKey));
                requestMessage.Stamp.CheckNullObject(nameof(requestMessage.Stamp));

                List <byte> result = new List <byte>(_packInitialCapacity)
                {
                    // index1: version.
                    Convert.ToByte(requestMessage.SchemaVersion)
                };

                // index2: Stamp.
                result.AddRange(GetStampBytes(requestMessage.Stamp ?? DateTime.UtcNow));

                // index3: Encrypted Security Key Length Indication.
                var encryptedSymmetricPrimaryKey   = EncodingOrSecurityExtension.RsaEncrypt(requestMessage.SymmetricPrimaryKey, rsaPublicKey);
                var encryptedSymmetricSecondaryKey = (requestMessage.SymmetricSecondaryKey.ByteValue == null) ? null : EncodingOrSecurityExtension.RsaEncrypt(requestMessage.SymmetricSecondaryKey, rsaPublicKey);
                result.AddRange(BitConverter.GetBytes((UInt16)encryptedSymmetricPrimaryKey.Length));
                result.AddRange(BitConverter.GetBytes((UInt16)encryptedSymmetricSecondaryKey.Length));

                // index4: Encrypted Security Key
                result.AddRange(encryptedSymmetricPrimaryKey);
                if (encryptedSymmetricSecondaryKey.HasItem())
                {
                    result.AddRange(encryptedSymmetricSecondaryKey);
                }

                // index5: Encrypted content
                result.AddRange(aesProvider.EncryptAes(requestMessage.Data));

                return(result.ToArray());
            }
            catch (Exception ex)
            {
                throw ex.Handle();
            }
        }