Пример #1
0
        /// <summary>
        /// Validates a client signature
        /// </summary>
        /// <param name="Data">Binary data being signed.</param>
        /// <param name="Signature">Digital signature</param>
        /// <returns>If the client signature is correct</returns>
        public bool ValidateSignature(byte[] Data, byte[] Signature)
        {
            if (!this.HasClientPublicKey)
            {
                return(false);
            }

            if (this.clientKeyName.StartsWith("RSA"))
            {
                if (!int.TryParse(this.clientKeyName.Substring(3), out int KeySize))
                {
                    return(false);
                }

                return(RsaEndpoint.Verify(Data, Signature, KeySize, this.clientPubKey));
            }
            else if (EndpointSecurity.TryCreateEndpoint(this.clientKeyName,
                                                        EndpointSecurity.IoTHarmonizationE2E, out IE2eEndpoint Endpoint) &&
                     Endpoint is EllipticCurveEndpoint LocalEc)
            {
                return(LocalEc.Verify(Data, this.clientPubKey, Signature));
            }
            else
            {
                return(false);
            }
        }
Пример #2
0
        /// <summary>
        /// Validates a client signature
        /// </summary>
        /// <param name="Data">Binary data being signed.</param>
        /// <param name="s1">First signature</param>
        /// <param name="s2">Second signature, if available.</param>
        /// <returns>If the client signature is correct</returns>
        public bool ValidateSignature(byte[] Data, byte[] s1, byte[] s2)
        {
            if (!this.HasClientPublicKey)
            {
                return(false);
            }

            if (this.clientKeyName.StartsWith("RSA"))
            {
                if (!int.TryParse(this.clientKeyName.Substring(3), out int KeySize))
                {
                    return(false);
                }

                return(RsaAes.Verify(Data, s1, KeySize, this.clientPubKey1, this.clientPubKey2));
            }
            else if (EndpointSecurity.TryCreateEndpoint(this.clientKeyName,
                                                        EndpointSecurity.IoTHarmonizationE2E, out IE2eEndpoint Endpoint) &&
                     Endpoint is EcAes256 EcAes256)
            {
                if (s2 == null)
                {
                    return(false);
                }

                return(EcAes256.Verify(Data, this.clientPubKey1, this.clientPubKey2, s1, s2, HashFunction.SHA256));
            }
            else
            {
                return(false);
            }
        }
Пример #3
0
        /// <summary>
        /// RSA / AES-256 hybrid cipher.
        /// </summary>
        /// <param name="KeySize">Size of key</param>
        /// <param name="Modulus">Modulus of RSA public key.</param>
        /// <param name="Exponent">Exponent of RSA public key.</param>
        /// <param name="LocalEndpoint">Local security endpoint, if available.</param>
        public RsaAes(int KeySize, byte[] Modulus, byte[] Exponent, EndpointSecurity LocalEndpoint)
            : base()
        {
            this.rsa         = RSA.Create();
            this.rsa.KeySize = KeySize;

            this.keySize       = KeySize;
            this.modulus       = Modulus;
            this.exponent      = Exponent;
            this.localEndpoint = LocalEndpoint;

            RSAParameters Param = new RSAParameters()
            {
                Modulus  = Modulus,
                Exponent = Exponent
            };

            this.rsa.ImportParameters(Param);
        }
Пример #4
0
 /// <summary>
 /// NIST P-224 Curve
 /// </summary>
 /// <param name="X">X-coordinate of remote public key.</param>
 /// <param name="Y">Y-coordinate of remote public key.</param>
 /// <param name="LocalEndpoint">Local security endpoint, if available.</param>
 public NistP224Aes(byte[] X, byte[] Y, EndpointSecurity LocalEndpoint)
     : base(X, Y, LocalEndpoint)
 {
 }
Пример #5
0
        /// <summary>
        /// Parses an identity from its XML representation
        /// </summary>
        /// <param name="Xml">XML representation</param>
        /// <returns>Legal identity</returns>
        public static LegalIdentity Parse(XmlElement Xml)
        {
            List <Property> Properties = new List <Property>();
            LegalIdentity   Result     = new LegalIdentity()
            {
                id = XML.Attribute(Xml, "id")
            };

            foreach (XmlNode N in Xml.ChildNodes)
            {
                if (N is XmlElement E)
                {
                    switch (E.LocalName)
                    {
                    case "clientPublicKey":
                        foreach (XmlNode N2 in E.ChildNodes)
                        {
                            if (N2 is XmlElement E2)
                            {
                                IE2eEndpoint Key = EndpointSecurity.ParseE2eKey(E2);
                                if (Key != null && Key.Namespace == EndpointSecurity.IoTHarmonizationE2E)
                                {
                                    if (Key is RsaAes RsaAes)
                                    {
                                        Result.clientKeyName = "RSA" + RsaAes.KeySize.ToString();
                                        Result.clientPubKey1 = RsaAes.Modulus;
                                        Result.clientPubKey2 = RsaAes.Exponent;
                                    }
                                    else if (Key is EcAes256 EcAes256)
                                    {
                                        Result.clientKeyName = Key.LocalName;
                                        Result.ClientPubKey1 = EcAes256.ToNetwork(EcAes256.PublicKey.X);
                                        Result.ClientPubKey2 = EcAes256.ToNetwork(EcAes256.PublicKey.Y);
                                    }
                                }
                            }
                        }
                        break;

                    case "property":
                        string Name  = XML.Attribute(E, "name");
                        string Value = XML.Attribute(E, "value");

                        Properties.Add(new Property(Name, Value));
                        break;

                    case "clientSignature":
                        foreach (XmlAttribute Attr in E.Attributes)
                        {
                            switch (Attr.Name)
                            {
                            case "s1":
                                Result.clientSignature1 = Convert.FromBase64String(Attr.Value);
                                break;

                            case "s2":
                                Result.clientSignature2 = Convert.FromBase64String(Attr.Value);
                                break;
                            }
                        }
                        break;

                    case "status":
                        foreach (XmlAttribute Attr in E.Attributes)
                        {
                            switch (Attr.Name)
                            {
                            case "provider":
                                Result.provider = Attr.Value;
                                break;

                            case "state":
                                if (Enum.TryParse <IdentityState>(Attr.Value, out IdentityState IdentityState))
                                {
                                    Result.state = IdentityState;
                                }
                                break;

                            case "created":
                                if (XML.TryParse(Attr.Value, out DateTime TP))
                                {
                                    Result.created = TP;
                                }
                                break;

                            case "updated":
                                if (XML.TryParse(Attr.Value, out TP))
                                {
                                    Result.updated = TP;
                                }
                                break;

                            case "from":
                                if (XML.TryParse(Attr.Value, out TP))
                                {
                                    Result.from = TP;
                                }
                                break;

                            case "to":
                                if (XML.TryParse(Attr.Value, out TP))
                                {
                                    Result.to = TP;
                                }
                                break;
                            }
                        }
                        break;

                    case "serverSignature":
                        foreach (XmlAttribute Attr in E.Attributes)
                        {
                            switch (Attr.Name)
                            {
                            case "s1":
                                Result.serverSignature1 = Convert.FromBase64String(Attr.Value);
                                break;

                            case "s2":
                                Result.serverSignature2 = Convert.FromBase64String(Attr.Value);
                                break;
                            }
                        }
                        break;
                    }
                }
            }

            Result.properties = Properties.ToArray();

            return(Result);
        }
Пример #6
0
 public override void PrepareClient2(XmppClient Client)
 {
     base.PrepareClient2(Client);
     this.endpointSecurity2 = new EndpointSecurity(this.client2, 128, this.endpoints2);
 }
Пример #7
0
 public override void PrepareClient1(XmppClient Client)
 {
     base.PrepareClient1(Client);
     this.endpointSecurity1 = new EndpointSecurity(this.client1, 128, this.endpoints1);
 }
Пример #8
0
        /// <summary>
        /// Signs files using an asymmetric cipher.
        ///
        /// Command line switches:
        ///
        /// -c NAME                Creates a new cipher object with random keys,
        ///                        given the name of the cipher.
        /// -l                     Lists supported cipher names.
        /// -keys                  Exports keys of selected cipher object.
        /// -pub KEY               Creates a new cipher object of the same type as
        ///                        the current one, using a public key. Such a
        ///                        cipher object can be used for validating
        ///                        signatures.
        /// -priv KEY              Creates a new cipher object of the same type as
        ///                        the current one, using a private key. Such a
        ///                        cipher can be used to create signatures.
        /// -o FILENAME            Directs output to the XML file FILENAME.
        /// -s FILENAME            Signs a file with the given filename.
        ///                        FILENAME can contain wildcards. This will
        ///                        generate one signature per file.
        /// -r                     If recursive search for files is to be used.
        /// -v FILENAME SIGNATURE  Validates a signature for the selected file.
        /// -?                     Help.
        /// </summary>
        static int Main(string[] args)
        {
            IE2eEndpoint Endpoint         = null;
            string       OutputFileName   = null;
            string       CurrentDirectory = Directory.GetCurrentDirectory();
            string       s;

            byte[]    Bin, Bin2;
            XmlWriter Output    = null;
            int       i         = 0;
            int       c         = args.Length;
            bool      Help      = false;
            bool      Recursive = false;

            try
            {
                Types.Initialize(
                    typeof(Program).Assembly,
                    typeof(IE2eEndpoint).Assembly,
                    typeof(EndpointSecurity).Assembly,
                    typeof(Security.EllipticCurves.EllipticCurve).Assembly);

                while (i < c)
                {
                    s = args[i++].ToLower();

                    switch (s)
                    {
                    case "-c":
                        if (i >= c)
                        {
                            throw new Exception("Missing cipher name.");
                        }

                        s = args[i++];
                        if (!EndpointSecurity.TryCreateEndpoint(s, EndpointSecurity.IoTHarmonizationE2E, out Endpoint))
                        {
                            throw new Exception("Algorithm not recognized: " + s);
                        }

                        break;

                    case "-l":

                        foreach (Type T in Types.GetTypesImplementingInterface(typeof(IE2eEndpoint)))
                        {
                            TypeInfo TI = T.GetTypeInfo();
                            if (TI.IsAbstract)
                            {
                                continue;
                            }

                            try
                            {
                                using (IE2eEndpoint Endpoint2 = (IE2eEndpoint)Activator.CreateInstance(T))
                                {
                                    if (Endpoint2.Namespace == EndpointSecurity.IoTHarmonizationE2E)
                                    {
                                        if (Output is null)
                                        {
                                            Console.Out.WriteLine(Endpoint2.LocalName);
                                        }
                                        else
                                        {
                                            Output.WriteElementString("Cipher", Namespace, Endpoint2.LocalName);
                                        }
                                    }
                                }
                            }
                            catch (Exception)
                            {
                                continue;
                            }
                        }
                        break;

                    case "-keys":
                        if (Endpoint is null)
                        {
                            throw new Exception("No cipher has been selected.");
                        }

                        if (Output is null)
                        {
                            Console.Out.WriteLine("Public Key: " + Endpoint.PublicKeyBase64);
                        }
                        else
                        {
                            Output.WriteElementString("PublicKey", Namespace, Endpoint.PublicKeyBase64);
                        }

                        if (Endpoint is EllipticCurveEndpoint EC)
                        {
                            s = EC.Curve.Export();
                            XmlDocument Doc = new XmlDocument()
                            {
                                PreserveWhitespace = true
                            };
                            Doc.LoadXml(s);
                            s = Doc.DocumentElement.GetAttribute("d");
                        }
                        else if (Endpoint is RsaEndpoint Rsa)
                        {
                            Bin = Rsa.Export(true);
                            s   = Convert.ToBase64String(Bin);
                        }
                        else
                        {
                            break;
                        }

                        if (Output is null)
                        {
                            Console.Out.WriteLine("Private Key: " + s);
                        }
                        else
                        {
                            Output.WriteElementString("PrivateKey", Namespace, s);
                        }

                        break;

                    case "-pub":
                        if (Endpoint is null)
                        {
                            throw new Exception("No cipher has been selected.");
                        }

                        if (i >= c)
                        {
                            throw new Exception("Missing public key.");
                        }

                        s = args[i++];

                        try
                        {
                            Bin = Convert.FromBase64String(s);
                        }
                        catch (Exception)
                        {
                            throw new Exception("Invalid public key.");
                        }

                        Endpoint = Endpoint.CreatePublic(Bin);
                        break;

                    case "-priv":
                        if (Endpoint is null)
                        {
                            throw new Exception("No cipher has been selected.");
                        }

                        if (i >= c)
                        {
                            throw new Exception("Missing private key.");
                        }

                        s = args[i++];

                        try
                        {
                            Bin = Convert.FromBase64String(s);
                        }
                        catch (Exception)
                        {
                            throw new Exception("Invalid private key.");
                        }

                        Endpoint = Endpoint.CreatePrivate(Bin);
                        break;

                    case "-o":
                        if (i >= c)
                        {
                            throw new Exception("Missing output file name.");
                        }

                        if (string.IsNullOrEmpty(OutputFileName))
                        {
                            OutputFileName = args[i++];
                        }
                        else
                        {
                            throw new Exception("Only one output file name allowed.");
                        }

                        XmlWriterSettings Settings = new XmlWriterSettings()
                        {
                            CloseOutput             = true,
                            ConformanceLevel        = ConformanceLevel.Document,
                            Encoding                = Encoding.UTF8,
                            Indent                  = true,
                            IndentChars             = "\t",
                            NewLineChars            = "\r\n",
                            NewLineHandling         = NewLineHandling.Entitize,
                            NewLineOnAttributes     = false,
                            OmitXmlDeclaration      = false,
                            WriteEndDocumentOnClose = true,
                            NamespaceHandling       = NamespaceHandling.OmitDuplicates
                        };

                        Output = XmlWriter.Create(OutputFileName, Settings);
                        Output.WriteStartDocument();
                        Output.WriteStartElement("Signatures", Namespace);
                        break;

                    case "-s":
                        if (Endpoint is null)
                        {
                            throw new Exception("No cipher has been selected.");
                        }

                        if (i >= c)
                        {
                            throw new Exception("Missing input file name.");
                        }

                        s = args[i++];

                        string[] FileNames;

                        if (s.Contains("*") || s.Contains("?"))
                        {
                            s = Path.Combine(CurrentDirectory, s);

                            string FileName = Path.GetFileName(s);
                            string Folder   = Path.GetDirectoryName(s);

                            FileNames = Directory.GetFiles(Folder, FileName, Recursive ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly);
                        }
                        else
                        {
                            FileNames = new string[] { s }
                        };

                        foreach (string FileName in FileNames)
                        {
                            using (FileStream f = File.OpenRead(FileName))
                            {
                                Bin = Endpoint.Sign(f);
                            }
                            s = Convert.ToBase64String(Bin);

                            if (Output is null)
                            {
                                Console.Out.WriteLine("Signature: " + s);
                            }
                            else
                            {
                                Output.WriteStartElement("Signature");
                                Output.WriteAttributeString("fileName", Path.GetRelativePath(CurrentDirectory, FileName));
                                Output.WriteValue(s);
                                Output.WriteEndElement();
                            }
                        }
                        break;

                    case "-v":
                        if (Endpoint is null)
                        {
                            throw new Exception("No cipher has been selected.");
                        }

                        if (i >= c)
                        {
                            throw new Exception("Missing input file name.");
                        }

                        s = args[i++];

                        Bin = File.ReadAllBytes(s);

                        if (i >= c)
                        {
                            throw new Exception("Missing signature.");
                        }

                        try
                        {
                            Bin2 = Convert.FromBase64String(args[i++]);
                        }
                        catch (Exception)
                        {
                            throw new Exception("Invalid signature.");
                        }

                        bool Valid = Endpoint.Verify(Bin, Bin2);

                        if (Output is null)
                        {
                            Console.Out.WriteLine("Valid: " + Valid.ToString());
                        }
                        else
                        {
                            Output.WriteStartElement("Valid");
                            Output.WriteAttributeString("fileName", Path.GetRelativePath(CurrentDirectory, s));
                            Output.WriteValue(Valid ? "true" : "false");
                            Output.WriteEndElement();
                        }
                        break;

                    case "-?":
                        Help = true;
                        break;

                    case "-r":
                        Recursive = true;
                        break;

                    default:
                        throw new Exception("Unrecognized switch: " + s);
                    }
                }

                if (Help || c == 0)
                {
                    Console.Out.WriteLine("Signs files using an asymmetric cipher.");
                    Console.Out.WriteLine();
                    Console.Out.WriteLine("Command line switches:");
                    Console.Out.WriteLine();
                    Console.Out.WriteLine("-c NAME                Creates a new cipher object with random keys,");
                    Console.Out.WriteLine("                       given the name of the cipher.");
                    Console.Out.WriteLine("-l                     Lists supported cipher names.");
                    Console.Out.WriteLine("-keys                  Exports keys of selected cipher object.");
                    Console.Out.WriteLine("-pub KEY               Creates a new cipher object of the same type as");
                    Console.Out.WriteLine("                       the current one, using a public key. Such a");
                    Console.Out.WriteLine("                       cipher object can be used for validating");
                    Console.Out.WriteLine("                       signatures.");
                    Console.Out.WriteLine("-priv KEY              Creates a new cipher object of the same type as");
                    Console.Out.WriteLine("                       the current one, using a private key. Such a");
                    Console.Out.WriteLine("                       cipher can be used to create signatures.");
                    Console.Out.WriteLine("-o FILENAME            Directs output to the XML file FILENAME.");
                    Console.Out.WriteLine("-s FILENAME            Signs a file with the given filename.");
                    Console.Out.WriteLine("                       FILENAME can contain wildcards. This will");
                    Console.Out.WriteLine("                       generate one signature per file.");
                    Console.Out.WriteLine("-r                     If recursive search for files is to be used.");
                    Console.Out.WriteLine("-v FILENAME SIGNATURE  Validates a signature for the selected file.");
                    Console.Out.WriteLine("-?                     Help.");
                }

                return(0);
            }
            catch (Exception ex)
            {
                Console.Out.WriteLine(ex.Message);
                return(-1);
            }
            finally
            {
                Output?.WriteEndElement();
                Output?.WriteEndDocument();
                Output?.Dispose();
            }
        }
Пример #9
0
        /// <summary>
        /// Parses an identity from its XML representation
        /// </summary>
        /// <param name="Xml">XML representation</param>
        /// <returns>Legal identity</returns>
        public static LegalIdentity Parse(XmlElement Xml)
        {
            List <Property>   Properties  = new List <Property>();
            List <Attachment> Attachments = new List <Attachment>();
            LegalIdentity     Result      = new LegalIdentity()
            {
                id = XML.Attribute(Xml, "id")
            };

            foreach (XmlNode N in Xml.ChildNodes)
            {
                if (N is XmlElement E)
                {
                    switch (E.LocalName)
                    {
                    case "clientPublicKey":
                        foreach (XmlNode N2 in E.ChildNodes)
                        {
                            if (N2 is XmlElement E2)
                            {
                                IE2eEndpoint Key = EndpointSecurity.ParseE2eKey(E2);
                                if (Key != null && Key.Namespace == EndpointSecurity.IoTHarmonizationE2E)
                                {
                                    Result.clientPubKey = Key.PublicKey;

                                    if (Key is RsaEndpoint RsaEndpoint)
                                    {
                                        Result.clientKeyName = "RSA" + RsaEndpoint.KeySize.ToString();
                                    }
                                    else
                                    {
                                        Result.clientKeyName = Key.LocalName;
                                    }
                                }
                            }
                        }
                        break;

                    case "property":
                        string Name  = XML.Attribute(E, "name");
                        string Value = XML.Attribute(E, "value");

                        Properties.Add(new Property(Name, Value));
                        break;

                    case "clientSignature":
                        Result.clientSignature = Convert.FromBase64String(E.InnerText);
                        break;


                    case "attachment":
                        Attachments.Add(new Attachment()
                        {
                            Id          = XML.Attribute(E, "id"),
                            LegalId     = Result.id,
                            ContentType = XML.Attribute(E, "contentType"),
                            FileName    = XML.Attribute(E, "fileName"),
                            Signature   = Convert.FromBase64String(XML.Attribute(E, "s")),
                            Timestamp   = XML.Attribute(E, "timestamp", DateTime.MinValue)
                        });
                        break;

                    case "status":
                        foreach (XmlAttribute Attr in E.Attributes)
                        {
                            switch (Attr.Name)
                            {
                            case "provider":
                                Result.provider = Attr.Value;
                                break;

                            case "state":
                                if (Enum.TryParse <IdentityState>(Attr.Value, out IdentityState IdentityState))
                                {
                                    Result.state = IdentityState;
                                }
                                break;

                            case "created":
                                if (XML.TryParse(Attr.Value, out DateTime TP))
                                {
                                    Result.created = TP;
                                }
                                break;

                            case "updated":
                                if (XML.TryParse(Attr.Value, out TP))
                                {
                                    Result.updated = TP;
                                }
                                break;

                            case "from":
                                if (XML.TryParse(Attr.Value, out TP))
                                {
                                    Result.from = TP;
                                }
                                break;

                            case "to":
                                if (XML.TryParse(Attr.Value, out TP))
                                {
                                    Result.to = TP;
                                }
                                break;
                            }
                        }
                        break;

                    case "serverSignature":
                        Result.serverSignature = Convert.FromBase64String(E.InnerText);
                        break;

                    case "attachmentRef":
                        string AttachmentId = XML.Attribute(E, "attachmentId");
                        string Url          = XML.Attribute(E, "url");

                        foreach (Attachment Attachment in Attachments)
                        {
                            if (Attachment.Id == AttachmentId)
                            {
                                Attachment.Url = Url;
                                break;
                            }
                        }
                        break;
                    }
                }
            }

            Result.properties  = Properties.ToArray();
            Result.attachments = Attachments.ToArray();

            return(Result);
        }
Пример #10
0
 /// <summary>
 /// Abstract base class for Elliptic Curve / AES-256 hybrid ciphers.s
 /// </summary>
 /// <param name="X">X-coordinate of remote public key.</param>
 /// <param name="Y">Y-coordinate of remote public key.</param>
 /// <param name="LocalEndpoint">Local security endpoint, if available.</param>
 public EcAes256(byte[] X, byte[] Y, EndpointSecurity LocalEndpoint)
     : base()
 {
     this.publicKey     = new PointOnCurve(FromNetwork(X), FromNetwork(Y));
     this.localEndpoint = LocalEndpoint;
 }