예제 #1
0
        /// <summary>
        /// Converts a signature to a signed packet. Take note that during this process,
        /// the signature will be verified based on the desired algorithm.
        /// </summary>
        /// <param name="signature">Signature to convert.</param>
        /// <param name="remoteIdentity">Identity of the sender of this signed packet. May not always be the signer.</param>
        /// <param name="signatureAlgorithm">Algorithm to verify the signature with.</param>
        /// <param name="packetFactory">Packet factory to create the packet from.</param>
        /// <returns>Signed packet.</returns>
        public static PacketSigned FromSignature(Signature signature, Identity remoteIdentity, SignatureAlgorithm signatureAlgorithm, PacketFactory packetFactory)
        {
            if (signatureAlgorithm == null)
            {
                throw new SecurityException("Null signature algorithm provided.");
            }

            MemoryStream signaturePacketBuffer = new MemoryStream(signature.Data);
            BinaryReader stream = new BinaryReader(signaturePacketBuffer);

            //Read the cryptographic salt from the packet, skipping it to advance forward.
            stream.ReadInt32();

            //Read the time the signature was created.
            DateTime signatureDate = new DateTime(stream.ReadInt64(), DateTimeKind.Utc);

            //Read the ID from the packet.
            byte packetId = stream.ReadByte();

            //Create the packet from the factory using the ID read.
            ReliableIM.Network.Protocol.Packet packet = packetFactory.CreateFromId(packetId);
            if (!(packet is PacketSigned))
            {
                throw new SecurityException("Packet type not acceptable.");
            }

            //Set the date time instance.
            ((PacketSigned)packet).dateTime = signatureDate;

            //Read the packet contents into the factory's packet.
            packet.Read(stream);

            //Verify the packet's signature against the given algorithm.
            if (!((PacketSigned)packet).VerifySignature(signatureAlgorithm, signature, remoteIdentity.Equals(signatureAlgorithm.Identity)))
            {
                throw new SecurityException("Signature verification failed.");
            }

            //Warning: At this point the signature has been verified, and authenticity
            //of the packet's origin (regardless of route) is no longer questioned.

            return((PacketSigned)packet);
        }