using System; using System.IO; using System.Security.Cryptography; using Gurock.SmartInspect; public class CryptoProtocol : FileProtocol { private string fIVOption; private string fKeyOption; private byte[] fKey; private byte[] fIV; protected override Stream GetStream(Stream stream) { if (this.fKey == null || this.fIV == null) { ThrowException("Invalid key or initialization vector"); } Rijndael rijndael = Rijndael.Create(); return new CryptoStream( stream, rijndael.CreateEncryptor(this.fKey, this.fIV), CryptoStreamMode.Write ); } protected byte[] GetHexadecimalBytes(string s) { if (s == null) { return null; } sbyte[] LOOKUP = { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, -1, -1, -1, -1, -1, -1, 10, 11, 12, 13, 14, 15 }; s = s.ToUpper(); if ((s.Length & 1) != 0) { return null; } byte[] b = new byte[s.Length / 2]; for (int i = 0; i < b.Length; i++) { char hiChar = s[i * 2]; char loChar = s[i * 2 + 1]; if (hiChar >= LOOKUP.Length || loChar >= LOOKUP.Length) { return null; } sbyte hi = LOOKUP[hiChar]; sbyte lo = LOOKUP[loChar]; if (hi == -1 || lo == -1) { return null; } b[i] = (byte) ((byte)hi << 4 | (byte)lo); } return b; } protected override string Name { get { return "crypto"; } } protected override bool IsValidOption(string name) { return name.Equals("key") || name.Equals("iv") || base.IsValidOption(name); } protected override void LoadOptions() { base.LoadOptions(); this.fKeyOption = GetStringOption("key", null); this.fKey = GetHexadecimalBytes(this.fKeyOption); this.fIVOption = GetStringOption("iv", null); this.fIV = GetHexadecimalBytes(this.fIVOption); } protected override void BuildOptions(ConnectionsBuilder builder) { base.BuildOptions(builder); builder.AddOption("key", this.fKeyOption); builder.AddOption("iv", this.fIVOption); } }