/// <summary> /// Gets the object data in a serialised, encrypted byte stream. /// The byte stream is encrypted using the user's logon credentials. /// </summary> /// <returns>Byte array containing the serialised encrypted data</returns> private byte [] getData() { // Create a new object clone of this object for serialization. StackHashLicenseData tempLicenseData = new StackHashLicenseData(this); // Create an output memory stream - this will grow as data is written. MemoryStream ms = new MemoryStream(); MD5 md5 = null; try { // Construct a BinaryFormatter and use it to serialize the data to the stream. BinaryFormatter formatter = new BinaryFormatter(); formatter.Serialize(ms, tempLicenseData); // Encrypt the data in memory using the user's logon credentials. byte [] data = EncryptInMemoryData(ms.GetBuffer(), DataProtectionScope.LocalMachine); // Add a checksum to the start of the data. MD5 returns a 16 byte hash. md5 = new MD5CryptoServiceProvider(); byte[] hash = md5.ComputeHash(data); int totalSize = 16 + data.Length; byte[] outBuffer = new byte[totalSize]; int nextByte = 0; for (int i = 0; i < 16; i++) { outBuffer[nextByte++] = hash[i]; } for (int i = 0; i < data.Length; i++) { outBuffer[nextByte++] = data[i]; } // Return the buffer. return(outBuffer); } finally { if (md5 != null) { md5.Dispose(); } if (ms != null) { ms.Dispose(); } } }
/// <summary> /// Copy constructor. /// </summary> /// <param name="licenseData">License data to copy.</param> public StackHashLicenseData(StackHashLicenseData licenseData) { if (licenseData == null) { throw new ArgumentNullException("licenseData"); } m_LicenseDefined = licenseData.LicenseDefined; m_LicenseId = licenseData.LicenseId; m_CompanyName = licenseData.CompanyName; m_DepartmentName = licenseData.DepartmentName; m_MaxEvents = licenseData.MaxEvents; m_MaxSeats = licenseData.MaxSeats; m_ExpiryUTC = licenseData.ExpiryUtc; m_IsTrialLicense = licenseData.IsTrialLicense; }
/// <summary> /// Loads the license data from the specified location. /// </summary> /// <param name="fileName">File to load the license data from.</param> /// <returns></returns> public static StackHashLicenseData Load(String fileName) { if (fileName == null) { throw new ArgumentNullException("fileName"); } if (!File.Exists(fileName)) { throw new ArgumentException("File does not exist: " + fileName, "fileName"); } FileStream licenseFile = new FileStream(fileName, FileMode.Open, FileAccess.Read); StackHashLicenseData licenseData = null; try { byte[] bytes = new byte[licenseFile.Length]; licenseFile.Read(bytes, 0, (int)licenseFile.Length); licenseData = new StackHashLicenseData(bytes); if (!String.IsNullOrEmpty(licenseData.LicenseId)) { licenseData.LicenseDefined = true; } } finally { if (licenseFile != null) { licenseFile.Close(); } } return(licenseData); }
/// <summary> /// Constructor for the CuckuSecrets object. /// Initialises the instance using the data from a file which must have previously /// been previously created using GetData. /// </summary> /// <param name="fileData">Byte array - must be multiple of 16 bytes </param> /// <param name="saveRequired">True - caller should save the license file.</param> /// <exception cref="ArgumentException">Invalid data array</exception> public StackHashLicenseData(byte [] fileData) { if (fileData == null) { throw new ArgumentNullException("fileData"); } if (fileData.Length < 20) // TODO { throw new ArgumentException("fileData too small", "fileData"); } StackHashLicenseData tempLicenseData = null; // Check the checksum at the start of the data (first 16 bytes). MD5 md5 = new MD5CryptoServiceProvider(); try { byte[] hash = md5.ComputeHash(fileData, 16, fileData.Length - 16); for (int i = 0; i < hash.Length; i++) { if (hash[i] != fileData[i]) { throw new ArgumentException("fileData points to invalid data", "fileData"); } } // Create array with stripped checksum. byte[] newFileData = new byte[fileData.Length - hash.Length]; System.Array.Copy(fileData, hash.Length, newFileData, 0, fileData.Length - hash.Length); // Decrypt the data specified using the User's login credentials. // Note that the encryptor ensures the block will be a multiple of // 16 bytes as expected by DecryptInMemoryData. bool loadedLicenseData = false; try { newFileData = DecryptInMemoryData(newFileData, DataProtectionScope.LocalMachine); loadedLicenseData = true; } catch (CryptographicException) { } // License used to be encrypted with CurrentUser key. if (!loadedLicenseData) { newFileData = DecryptInMemoryData(newFileData, DataProtectionScope.CurrentUser); } // Create a memory stream based on the supplied buffer. MemoryStream ms = new MemoryStream(newFileData); try { // Construct a BinaryFormatter and use it to deserialize the data to a new object. BinaryFormatter formatter = new BinaryFormatter(); tempLicenseData = (StackHashLicenseData)formatter.Deserialize(ms); // Now copy the deserialised object. m_LicenseId = tempLicenseData.LicenseId; m_CompanyName = tempLicenseData.CompanyName; m_DepartmentName = tempLicenseData.DepartmentName; m_MaxEvents = tempLicenseData.MaxEvents; m_MaxSeats = tempLicenseData.MaxSeats; m_ExpiryUTC = tempLicenseData.ExpiryUtc; m_IsTrialLicense = tempLicenseData.IsTrialLicense; } finally { if (ms != null) { ms.Dispose(); } } } finally { md5.Dispose(); } }