/// <summary>
        /// Creates a new wire message.
        /// </summary>
        /// <param name="messageType">Message type name</param>
        /// <param name="serializedMessage">Serialized message</param>
        /// <param name="serializer">Serializer used to serialize the signed content</param>
        /// <param name="keyPair">RSA key pair to be used for creating a RSA signature for the message data</param>
        /// <param name="sharedSecret">Shared secret (wire message will be not encrypted, if null)</param>
        /// <param name="error">Species whether the wire message is in error state</param>
        /// <param name="uniqueCallKey">Unique key to correlate RPC call</param>
        /// <returns>The created wire message</returns>
        /// <exception cref="ArgumentException">Thrown if the message type is left empty.</exception>
        public WireMessage CreateWireMessage(
            string messageType,
            byte[] serializedMessage,
            ISerializerAdapter serializer,
            RsaKeyPair keyPair   = null,
            byte[] sharedSecret  = null,
            bool error           = false,
            byte[] uniqueCallKey = null)
        {
            if (string.IsNullOrWhiteSpace(messageType))
            {
                throw new ArgumentException("Message type must not be empty.", nameof(messageType));
            }

            byte[] iv =
                sharedSecret == null
                    ? new byte[0]
                    : AesEncryption.GenerateIv();

            byte[] rawContent;

            if (keyPair != null && sharedSecret != null)
            {
                var signedMessageData =
                    new SignedMessageData()
                {
                    MessageRawData = serializedMessage,
                    Signature      =
                        RsaSignature.CreateSignature(
                            keySize: keyPair.KeySize,
                            sendersPrivateKeyBlob: keyPair.PrivateKey,
                            rawData: serializedMessage)
                };

                rawContent = serializer.Serialize(typeof(SignedMessageData), signedMessageData);
            }
            else
            {
                rawContent = serializedMessage;
            }

            byte[] messageContent =
                sharedSecret == null
                    ? rawContent
                    : AesEncryption.Encrypt(
                    dataToEncrypt: rawContent,
                    sharedSecret: sharedSecret,
                    iv: iv);

            return
                (new WireMessage()
            {
                MessageType = messageType,
                Data = messageContent,
                Iv = iv,
                Error = error,
                UniqueCallKey = uniqueCallKey
            });
        }
Beispiel #2
0
        public void CanCreateVerifyableSignature()
        {
            var payload   = new byte[] { 1, 2, 3 };
            var key       = RSA.Create();
            var signature = new RsaSignature(payload, key);

            Assert.True(signature.Verify(payload, key.ExportRSAPublicKey()));
        }
Beispiel #3
0
 static RsaCertificate createWithEmbeddedDataAndSignature(
     RSAParameters?parameters        = null,
     IEnumerable <byte> embeddedData = null, bool makeEmbeddedDataNull = false,
     RsaSignature signature          = null, bool makeSignatureNull    = false)
 => new RsaCertificate(
     parameters: parameters ?? ScenarioRsa.DefaultRsaParameters,
     embeddedData: embeddedData ?? (makeEmbeddedDataNull ? null : ScenarioRsa.DefaultEmbeddedData),
     signature: signature ?? (makeSignatureNull ? null : ScenarioRsa.DefaultSignature));
Beispiel #4
0
        public void CannotVerifySignatureWithWrongKey()
        {
            var payload   = new byte[] { 1, 2, 3 };
            var key       = RSA.Create();
            var otherKey  = RSA.Create();
            var signature = new RsaSignature(payload, key);

            Assert.False(signature.Verify(payload, otherKey.ExportRSAPublicKey()));
        }
Beispiel #5
0
        public void CannotVerifySignatureWithWrongPayload()
        {
            var payload1  = new byte[] { 1, 2, 3 };
            var payload2  = new byte[] { 2, 3, 4 };
            var key       = RSA.Create();
            var signature = new RsaSignature(payload1, key);

            Assert.False(signature.Verify(payload2, key.ExportRSAPublicKey()));
        }
Beispiel #6
0
                public void GenerateAndSignCallback_Should_StoreSignature()
                {
                    // Arrange
                    var signature = new RsaSignature(ScenarioRsa.DefaultSignerCertificate.Hash, new byte[] { 0x11, 0x11, 0x11, 0x11 });

                    // Act
                    var key = RsaKey.Generate((_hash) => signature);

                    // Assert
                    key.Signature.Should().BeSameAs(signature);
                    key.Signature.Should().BeSameAs(((IKey)key).Signature);
                }
Beispiel #7
0
                public void GenerateWithEmbeddedDataHashAndSignCallback_Should_StoreSignature()
                {
                    // Arrange
                    var embeddedData = ScenarioRsa.DefaultEmbeddedData;
                    var signature    = new RsaSignature(ScenarioRsa.DefaultSignerCertificate.Hash, new byte[] { 0x11, 0x11, 0x11, 0x11 });

                    // Act
                    var key = RsaKey.Generate(embeddedData: embeddedData, signKeyCallback: (_hash) => signature);

                    // Assert
                    key.EmbeddedData.SequenceEqual(embeddedData).Should().BeTrue();
                    key.Signature.Should().BeSameAs(signature);
                }
Beispiel #8
0
                public void SameParametersAndSignature_ShouldReturn_True()
                {
                    // Arrange
                    var signature    = new RsaSignature(Sha512Hash.Compute(new byte[] { 0x00 }), new byte[] { 0x01 });
                    var certificate1 = new RsaCertificate(
                        parameters: ScenarioRsa1.RsaParameters,
                        signature: signature);
                    var certificate2 = new RsaCertificate(
                        parameters: ScenarioRsa1.RsaParameters,
                        signature: signature);

                    // Act
                    // Assert
                    certificate1.Equals(certificate2).Should().BeTrue();
                }
Beispiel #9
0
        public Message FormMessageFor(PubKey receiversKey, string message)
        {
            var messageNums = m_converter.ToNumbers(message).ToList();

            var encoded   = RsaUtility.Encode(messageNums, receiversKey).ToList();
            var signature = RsaSignature.MakeSignature(message, m_converter, m_sigSecret).ToList();

            var m = Message.FromNumbers(encoded, signature);

            _ReleaseList(messageNums);
            _ReleaseList(encoded);
            _ReleaseList(signature);

            return(m);
        }
Beispiel #10
0
 static ScenarioRsa()
 {
     DefaultData                 = new byte[] { 0x00, 0x01, 0x02, 0x03 };
     DefaultDataHash             = Sha512Hash.Compute(DefaultData);
     DefaultEmbeddedData         = new byte[] { 0xff, 0xee, 0xdd, 0xcc };
     DefaultKey                  = RsaKey.Generate();
     DefaultRsa                  = DefaultKey.CreateRsa();
     DefaultRsaParameters        = DefaultRsa.ExportParameters(true);
     DefaultCertificateSignature = new RsaSignature(Sha512Hash.Compute(new byte[] { 0x12, 0x34, 0xaa, 0xbb }), new byte[] { 0xa1, 0xb2, 0xc3, 0xd4 });
     DefaultCertificate          = new RsaCertificate(DefaultRsaParameters, DefaultCertificateSignature);
     DefaultSignerKey            = RsaKey.Generate();
     DefaultSignerCertificate    = (RsaCertificate)DefaultSignerKey.DeriveCertificate();
     DefaultSignatureData        = new byte[] { 0x1f, 0x2f, 0x3f, 0x4f };
     DefaultSignature            = new RsaSignature(DefaultSignerCertificate.Hash, DefaultSignatureData);
     DefaultChain                = new ChainOfTrust(DefaultSignerCertificate);
 }
Beispiel #11
0
        public string ReceiveMessageFrom(SignCertificate senderCertificate, Message received, out bool signatureIsOk)
        {
            var messageNums        = received.GetMessage().ToList();
            var messageDecodedNums = RsaUtility.Decode(messageNums, m_decodingKey).ToList();

            string message = m_converter.FromNumbers(messageDecodedNums);

            var signatureNums = received.GetSignature();

            signatureIsOk = RsaSignature.SignatureIsValid(message, signatureNums, m_converter, senderCertificate);

            _ReleaseList(messageNums);
            _ReleaseList(messageDecodedNums);
            _ReleaseList(signatureNums);

            return(message);
        }
        /// <summary>
        /// Gets decrypted data from a wire message.
        /// </summary>
        /// <param name="message">Wire message</param>
        /// <param name="serializer">Serializer used to deserialized the signed content</param>
        /// <param name="sharedSecret">Shared secret (null, if the wire message is not encrypted)</param>
        /// <param name="sendersPublicKeyBlob">Public key of the sender used for RSA signature verification</param>
        /// <param name="sendersPublicKeySize">Sender's public key size</param>
        /// <returns>Decrypted raw data</returns>
        public byte[] GetDecryptedMessageData(
            WireMessage message,
            ISerializerAdapter serializer,
            byte[] sharedSecret         = null,
            byte[] sendersPublicKeyBlob = null,
            int sendersPublicKeySize    = 0)
        {
            if (message.Iv.Length > 0 && sharedSecret != null)
            {
                var decryptedRawData =
                    AesEncryption.Decrypt(
                        encryptedData: message.Data,
                        sharedSecret: sharedSecret,
                        iv: message.Iv);

                var signedMessageData = serializer.Deserialize <SignedMessageData>(decryptedRawData);

                if (sendersPublicKeyBlob != null && signedMessageData.Signature != null)
                {
                    if (RsaSignature.VerifySignature(
                            keySize: sendersPublicKeySize,
                            sendersPublicKeyBlob: sendersPublicKeyBlob,
                            rawData: signedMessageData.MessageRawData,
                            signature: signedMessageData.Signature))
                    {
                        return(signedMessageData.MessageRawData);
                    }
                    else
                    {
                        throw new SecurityException("Verification of message signature failed.");
                    }
                }
                else
                {
                    return(decryptedRawData);
                }
            }
            else
            {
                return(message.Data);
            }
        }
Beispiel #13
0
        public void VerifySignature_should_return_true_if_signature_is_valid()
        {
            int keySize = 4096;
            var keyPair = new RsaKeyPair(keySize);

            var data = Encoding.UTF8.GetBytes("Test");

            var signature =
                RsaSignature.CreateSignature(
                    keySize: keySize,
                    sendersPrivateKeyBlob: keyPair.PrivateKey,
                    rawData: data);

            var result =
                RsaSignature.VerifySignature(
                    keySize: keySize,
                    sendersPublicKeyBlob: keyPair.PublicKey,
                    rawData: data,
                    signature: signature);

            Assert.Equal(512, signature.Length);
            Assert.True(result);
        }
Beispiel #14
0
        /// <summary>
        /// Processes a complete handshake message from server.
        /// </summary>
        /// <param name="message">Deserialized WireMessage that contains a plain or encrypted Session ID</param>
        private void ProcessCompleteHandshakeMessage(WireMessage message)
        {
            if (MessageEncryption)
            {
                var signedMessageData =
                    Serializer.Deserialize <SignedMessageData>(message.Data);

                var encryptedSecret =
                    Serializer.Deserialize <EncryptedSecret>(signedMessageData.MessageRawData);

                _serverPublicKeyBlob = encryptedSecret.SendersPublicKeyBlob;

                if (!RsaSignature.VerifySignature(
                        keySize: _keyPair?.KeySize ?? 0,
                        sendersPublicKeyBlob: _serverPublicKeyBlob,
                        rawData: signedMessageData.MessageRawData,
                        signature: signedMessageData.Signature))
                {
                    throw new SecurityException("Verification of message signature failed.");
                }

                _sessionId =
                    new Guid(
                        RsaKeyExchange.DecrpytSecret(
                            keySize: _config.KeySize,
                            // ReSharper disable once PossibleNullReferenceException
                            receiversPrivateKeyBlob: _keyPair.PrivateKey,
                            encryptedSecret: encryptedSecret));
            }
            else
            {
                _sessionId = new Guid(message.Data);
            }

            _handshakeCompletedWaitHandle.Set();
        }
Beispiel #15
0
        private void Work()
        {
            IsNoActionRunning = false;

            try
            {
                #region Checks for chosen file

                //Check whether file id is int

                if (!int.TryParse(ChosenFileId, out int FileId))
                {
                    IsCompleted = false;
                    StateText   = "Wrong File id!";
                    return;
                }

                //Check whether file id is correct

                if ((FileId >= FilesLoaded.Count()) || (FileId < 0))
                {
                    IsCompleted = false;
                    StateText   = "Wrong File id!";
                    return;
                }

                if (string.IsNullOrEmpty(ChosenAction))
                {
                    return;
                }

                string FilePath = string.Empty;

                //Load file path

                foreach (var item in FilesLoaded)
                {
                    if (item.Id == FileId)
                    {
                        FilePath = item.FileRealName;
                        break;
                    }
                }

                //if file id points to empty record

                if (string.IsNullOrWhiteSpace(FilePath))
                {
                    IsCompleted = false;
                    StateText   = "File id is wrong.";
                    return;
                }

                // if file was deleted after loading

                if (!File.Exists(FilePath))
                {
                    IsCompleted = false;
                    StateText   = "File doesnt exist.";
                    return;
                }

                if (Path.GetExtension(FilePath) != ".txt")
                {
                    IsCompleted = false;
                    StateText   = "Text files should be used only...";
                    return;
                }

                #endregion

                var hashFuncChosen = HashFunctionsDict[ChosenSignature];

                BigInteger p = 0, q = 0, secretKey = 0;

                if (!IsKeysAutoGenerating)
                {
                    #region Checks for user input

                    if (!BigInteger.TryParse(PublicKeyParam1, out p))
                    {
                        IsCompleted = false;
                        StateText   = "Wrong p value";
                        return;
                    }


                    if (!BigInteger.TryParse(PublicKeyParam2, out q))
                    {
                        IsCompleted = false;
                        StateText   = "Wrong q value";
                        return;
                    }

                    if (!BigInteger.TryParse(SecretKey, out secretKey))
                    {
                        IsCompleted = false;
                        StateText   = "Wrong secret key value";
                        return;
                    }

                    #endregion
                }
                else
                { //if secret key couldn't meet the requerements here, should regenerate the numbers.
                    p           = RandomNumbersGenerator.GeneratePrime(15 * 8);
                    OutputText += $"P : {p.ToString()} ";
                    q           = RandomNumbersGenerator.GeneratePrime(15 * 8);
                    OutputText += Environment.NewLine + $"Q : {q.ToString()} ";
                    secretKey   = RandomNumbersGenerator.GeneratePrime(15 * 8);
                    OutputText += Environment.NewLine + $"Secret Key : {secretKey.ToString()} ";
                }


                var signatureInstance = new RsaSignature(p, q, secretKey, hashFuncChosen, IsCorrectnessChecksEnabled);

                if (ChosenAction == "Sign a message")
                {
                    var result = signatureInstance.Sign(FilePath);
                    OutputText += Environment.NewLine + $"Result of signing Is: {result.Item1.ToString()}"
                                  + Environment.NewLine + $"Hash in decimal is :{result.Item2.ToString()}"
                                  + Environment.NewLine + $"Hash in hex is :{result.Item2.ToString("X")}";
                }

                if (ChosenAction == "Signature check")
                {
                    if (signatureInstance.CheckSignature(FilePath))
                    {
                        OutputText = "Digital signature is right!";
                    }
                    else
                    {
                        OutputText = "Digital signature is corrupted!";
                    }
                }

                StateText = "Action completed.";

                IsCompleted = true;
            }
            catch (ArgumentException ex)
            {
                StateText   = ex.Message;
                IsCompleted = false;
            }
            catch (OutOfMemoryException)
            {
                StateText   = "Memory limit was exceeded.";
                IsCompleted = false;
            }
            catch (IOException IoExc)
            {
                StateText   = IoExc.Message;
                IsCompleted = false;
            }
            finally
            { IsNoActionRunning = true; }
        }
Beispiel #16
0
        /// <summary>
        /// Creates a new instance of the RemotingSession class.
        /// </summary>
        /// <param name="keySize">Key size of the RSA keys for asymmetric encryption</param>
        /// <param name="clientPublicKey">Public key of this session's client</param>
        /// <param name="server">Server instance, that hosts this session</param>
        /// <param name="rawMessageTransport">Component, that does the raw message transport (send and receive)</param>
        internal RemotingSession(int keySize, byte[] clientPublicKey, IRemotingServer server,
                                 IRawMessageTransport rawMessageTransport)
        {
            _sessionId             = Guid.NewGuid();
            _lastActivityTimestamp = DateTime.Now;
            _isAuthenticated       = false;
            _keyPair  = new RsaKeyPair(keySize);
            CreatedOn = DateTime.Now;
            _remoteDelegateInvocationEventAggregator = new RemoteDelegateInvocationEventAggregator();
            _server = server ?? throw new ArgumentNullException(nameof(server));
            _delegateProxyFactory = _server.ServiceRegistry.GetService <IDelegateProxyFactory>();
            _delegateProxyCache   = new ConcurrentDictionary <Guid, IDelegateProxy>();
            _rawMessageTransport  = rawMessageTransport ?? throw new ArgumentNullException(nameof(rawMessageTransport));
            _clientPublicKeyBlob  = clientPublicKey;

            _rawMessageTransport.ReceiveMessage += OnReceiveMessage;
            _rawMessageTransport.ErrorOccured   += OnErrorOccured;

            MessageEncryption = clientPublicKey != null;

            WireMessage completeHandshakeMessage;

            if (MessageEncryption)
            {
                var encryptedSessionId =
                    RsaKeyExchange.EncryptSecret(
                        keySize: _server.SessionRepository.KeySize,
                        receiversPublicKeyBlob: clientPublicKey,
                        secretToEncrypt: _sessionId.ToByteArray(),
                        sendersPublicKeyBlob: _keyPair.PublicKey);

                var rawContent = _server.Serializer.Serialize(encryptedSessionId);

                var signedMessageData =
                    new SignedMessageData()
                {
                    MessageRawData = rawContent,
                    Signature      =
                        RsaSignature.CreateSignature(
                            keySize: keySize,
                            sendersPrivateKeyBlob: _keyPair.PrivateKey,
                            rawData: rawContent)
                };

                var rawData = _server.Serializer.Serialize(typeof(SignedMessageData), signedMessageData);

                completeHandshakeMessage =
                    new WireMessage
                {
                    MessageType = "complete_handshake",
                    Data        = rawData
                };
            }
            else
            {
                completeHandshakeMessage =
                    new WireMessage
                {
                    MessageType = "complete_handshake",
                    Data        = _sessionId.ToByteArray()
                };
            }

            _remoteDelegateInvocationEventAggregator.RemoteDelegateInvocationNeeded +=
                (delegateType, uniqueCallKey, handlerKey, arguments) =>
            {
                var sharedSecret =
                    MessageEncryption
                            ? _sessionId.ToByteArray()
                            : null;

                var remoteDelegateInvocationMessage =
                    new RemoteDelegateInvocationMessage
                {
                    UniqueCallKey     = uniqueCallKey,
                    HandlerKey        = handlerKey,
                    DelegateArguments = arguments
                };

                var remoteDelegateInvocationWebsocketMessage =
                    _server.MessageEncryptionManager
                    .CreateWireMessage(
                        serializedMessage: _server.Serializer.Serialize(remoteDelegateInvocationMessage),
                        serializer: _server.Serializer,
                        sharedSecret: sharedSecret,
                        keyPair: _keyPair,
                        messageType: "invoke");

                // Invoke remote delegate on client
                _rawMessageTransport.SendMessage(
                    _server.Serializer.Serialize(remoteDelegateInvocationWebsocketMessage));

                return(null);
            };

            _rawMessageTransport.SendMessage(_server.Serializer.Serialize(completeHandshakeMessage));
        }
Beispiel #17
0
 static RsaCertificate createWithSignature(
     RSAParameters?parameters = null,
     RsaSignature signature   = null, bool makeSignatureNull = false)
 => new RsaCertificate(
     parameters: parameters ?? ScenarioRsa.DefaultRsaParameters,
     signature: signature ?? (makeSignatureNull ? null : ScenarioRsa.DefaultSignature));