// This is the only method about exchange data between this software and AirVPN infrastructure. // We don't use SSL. Useless layer in our case, and we need to fetch hostname and direct IP that don't permit common-name match. // 'S' is the AES 256 bit one-time session key, crypted with a RSA 4096 public-key. // 'D' is the data from the client to our server, crypted with the AES. // The server answer is XML decrypted with the same AES session. public static XmlDocument FetchHost(string host, Dictionary <string, string> parameters) { // AES RijndaelManaged rijAlg = new RijndaelManaged(); rijAlg.KeySize = 256; rijAlg.GenerateKey(); rijAlg.GenerateIV(); // Generate S string airAuthPublicKey = ResourcesFiles.GetString("auth.xml"); StringReader sr = new System.IO.StringReader(airAuthPublicKey); System.Xml.Serialization.XmlSerializer xs = new System.Xml.Serialization.XmlSerializer(typeof(RSAParameters)); RSAParameters publicKey = (RSAParameters)xs.Deserialize(sr); RSACryptoServiceProvider csp = new RSACryptoServiceProvider(); csp.ImportParameters(publicKey); Dictionary <string, byte[]> assocParamS = new Dictionary <string, byte[]>(); assocParamS["key"] = rijAlg.Key; assocParamS["iv"] = rijAlg.IV; byte[] bytesParamS = csp.Encrypt(AssocToBytes(assocParamS), false); // Generate D byte[] aesDataIn = AssocToBytes(parameters); MemoryStream aesCryptStream = new MemoryStream(); ICryptoTransform aesEncryptor = rijAlg.CreateEncryptor(); CryptoStream aesCryptStream2 = new CryptoStream(aesCryptStream, aesEncryptor, CryptoStreamMode.Write); aesCryptStream2.Write(aesDataIn, 0, aesDataIn.Length); aesCryptStream2.FlushFinalBlock(); byte[] bytesParamD = aesCryptStream.ToArray(); // HTTP Fetch string url = "http://" + host + "?s=" + Uri.EscapeUriString(Base64Encode(bytesParamS)) + "&d=" + Uri.EscapeUriString(Base64Encode(bytesParamD)); byte[] fetchResponse = Engine.Instance.FetchUrl(url, "", 1, Engine.Instance.IsConnected()); // Decrypt answer MemoryStream aesDecryptStream = new MemoryStream(); ICryptoTransform aesDecryptor = rijAlg.CreateDecryptor(); CryptoStream aesDecryptStream2 = new CryptoStream(aesDecryptStream, aesDecryptor, CryptoStreamMode.Write); aesDecryptStream2.Write(fetchResponse, 0, fetchResponse.Length); aesDecryptStream2.FlushFinalBlock(); byte[] fetchResponsePlain = aesDecryptStream.ToArray(); string finalData = System.Text.Encoding.UTF8.GetString(fetchResponsePlain); XmlDocument doc = new XmlDocument(); doc.LoadXml(finalData); return(doc); }
public Storage() { EnsureDefaults(); XmlDocument DocManifestDefault = new XmlDocument(); DocManifestDefault.LoadXml(ResourcesFiles.GetString("manifest.xml")); Manifest = DocManifestDefault.DocumentElement; // Compute profile string profile = Get("profile"); string path = Get("path"); path = Platform.Instance.NormalizePath(path); if (path == "") { path = Platform.Instance.GetDefaultDataPath(); } if (profile.IndexOf(".") != -1) { // Profile must not have an extension. profile = profile.Substring(0, profile.IndexOf(".")); CommandLine.SystemEnvironment.Set("profile", profile); } if (Platform.Instance.IsPath(profile)) { // Is a path FileInfo fi = new FileInfo(Platform.Instance.NormalizePath(profile)); DataPath = fi.DirectoryName; profile = fi.Name; CommandLine.SystemEnvironment.Set("profile", profile); if (TestDataPath(DataPath, true) == false) { DataPath = ""; } } if (DataPath == "") { if (path == "home") { path = Platform.Instance.GetUserFolder(); } else if (path == "program") { path = Platform.Instance.GetProgramFolder(); } if (path != "") { DataPath = path; if (TestDataPath(DataPath, true) == false) { DataPath = ""; } } } if (DataPath == "") { DataPath = Platform.Instance.GetProgramFolder(); if (Utils.HasAccessToWrite(DataPath) == false) { DataPath = ""; } } if (DataPath == "") { DataPath = Platform.Instance.GetUserFolder(); } }