예제 #1
0
        [Test] public void Base32()
        {
            {
                var data = new byte[] { 0xff };
                var enc  = Base32Encoding.ToString(data);
                var dec  = Base32Encoding.ToBytes(enc);
                Assert.Equal(enc.Length, Base32Encoding.EncodedLength(data.Length));
                Assert.Equal(dec.Length, Base32Encoding.DecodedLength(enc));
                Assert.Equal(0, Array_.Compare(data, 0, data.Length, dec, 0, dec.Length));
            }
            {
                var data = new byte[256];
                for (int i = 0; i != data.Length; ++i)
                {
                    data[i] = (byte)i;
                }
                var enc = Base32Encoding.ToString(data);
                var dec = Base32Encoding.ToBytes(enc);
                Assert.Equal(enc.Length, Base32Encoding.EncodedLength(data.Length));
                Assert.Equal(dec.Length, Base32Encoding.DecodedLength(enc));
                Assert.Equal(0, Array_.Compare(data, 0, data.Length, dec, 0, dec.Length));
            }
            var rand = new Random(42);

            for (int i = 0; i != 100; ++i)
            {
                var data = new byte[rand.Next(16000)];
                rand.NextBytes(data);
                var enc = Base32Encoding.ToString(data);
                var dec = Base32Encoding.ToBytes(enc);
                Assert.Equal(enc.Length, Base32Encoding.EncodedLength(data.Length));
                Assert.Equal(dec.Length, Base32Encoding.DecodedLength(enc));
                Assert.Equal(0, Array_.Compare(data, 0, data.Length, dec, 0, dec.Length));
            }
        }
예제 #2
0
        public void ByteArrayCompare()
        {
            byte[] lhs = new byte[] { 1, 2, 3, 4, 5 };
            byte[] rhs = new byte[] { 3, 4, 5, 6, 7 };

            Assert.Equal(-1, Array_.Compare(lhs, 0, 5, rhs, 0, 5));
            Assert.Equal(0, Array_.Compare(lhs, 2, 3, rhs, 0, 3));
            Assert.Equal(1, Array_.Compare(lhs, 3, 2, rhs, 0, 2));
            Assert.Equal(-1, Array_.Compare(lhs, 2, 3, rhs, 0, 4));
            Assert.Equal(1, Array_.Compare(lhs, 2, 3, rhs, 0, 2));
        }
예제 #3
0
        /// <summary>Verify that a file has a valid signature</summary>
        public static bool Validate(string filepath, string public_key, bool thrw = true)
        {
            // Create the 'Crypto' service
            var alg = new RSACryptoServiceProvider();

            alg.FromXmlString(public_key);
            var key_size_bytes = alg.KeySize / 8;

            // Read the file into memory (no fancy streaming...)
            var filebuf = File.ReadAllBytes(filepath);
            var length  = filebuf.Length;

            // The total length of the signature in bytes
            var sig_length = key_size_bytes + SignatureId.Length;

            // Check whether the file has a signature
            if (length >= sig_length && Array_.Compare(
                    filebuf, length - sig_length, SignatureId.Length,
                    SignatureId, 0, SignatureId.Length) == 0)
            {
                length -= sig_length;
            }
            else
            {
                if (thrw)
                {
                    throw new VerificationException("File is not signed");
                }
                return(false);
            }

            // Validate the signature
            var  buf   = filebuf.Take(length).ToArray();
            var  sig   = filebuf.Skip(length + SignatureId.Length).Take(key_size_bytes).ToArray();
            bool valid = alg.VerifyData(buf, new SHA256CryptoServiceProvider(), sig);

            if (thrw && !valid)
            {
                throw new VerificationException("File signature incorrect");
            }
            return(valid);
        }
예제 #4
0
        // Disabled until 'GenerateRSAKeyPair' is upgraded [Test]
        public void SignFile()
        {
            // These would normally be stored as files and read into
            // a string using File.ReadAllText()
            Crypt.GenerateRSAKeyPair(out var pub, out var prv);

            const string filepath = "tmp.bin";
            var          data     = new byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };

            try
            {
                // Create a file to sign
                using (var fs = new FileStream(filepath, FileMode.Create, FileAccess.Write))
                    fs.Write(data, 0, data.Length);

                // Sign the file
                Crypt.SignFile(filepath, prv);

                // Check that the start of the file is the same
                var buf1 = File.ReadAllBytes(filepath);
                Assert.True(Array_.Compare(buf1, 0, data.Length, data, 0, data.Length) == 0);

                // Verify the signed file using the public key
                Assert.True(Crypt.Validate(filepath, pub));

                // Sign it again to make sure the function handles the case that the signature is already there
                Crypt.SignFile(filepath, prv);

                // Check that the whole file is the same
                var buf2 = File.ReadAllBytes(filepath);
                Assert.True(Array_.Compare(buf2, 0, buf2.Length, buf1, 0, buf1.Length) == 0);

                // Verify the signed file using the public key
                Assert.True(Crypt.Validate(filepath, pub));
            }
            finally
            {
                File.Delete(filepath);
            }
        }
예제 #5
0
        /// <summary>Attaches a signature to the end of a file</summary>
        public static void SignFile(string filepath, string private_key)
        {
            // Create the 'Crypto' service
            var alg = new RSACryptoServiceProvider();

            alg.FromXmlString(private_key);
            var key_size_bytes = alg.KeySize / 8;

            // Read the file into memory (no fancy streaming...)
            var filebuf = File.ReadAllBytes(filepath);
            var length  = filebuf.Length;

            // The total length of the signature in bytes
            var sig_length = key_size_bytes + SignatureId.Length;

            // Check whether the file has an existing signature
            // If so, shorten the length of file buf that's signed
            if (length >= sig_length && Array_.Compare(
                    filebuf, length - sig_length, SignatureId.Length,
                    SignatureId, 0, SignatureId.Length) == 0)
            {
                length -= sig_length;
            }

            // Generate the signature
            var buf = filebuf.Take(length).ToArray();
            var sig = alg.SignData(buf, new SHA256CryptoServiceProvider());

            // Append the signature to the end of the file
            using (var fs = new FileStream(filepath, FileMode.Open, FileAccess.Write))
            {
                fs.Seek(length, SeekOrigin.Begin);
                fs.Write(SignatureId, 0, SignatureId.Length);
                fs.Write(sig, 0, sig.Length);
            }
        }