[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)); } }
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)); }
/// <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); }
// 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); } }
/// <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); } }