/// <summary> /// Decrypts authentication <see cref="Credentials" /> from a /// byte array using the specified public asymmetric private key and /// algorithm. /// </summary> /// <param name="encrypted">The encrypted credential bytes.</param> /// <param name="algorithm">The encryption algorithm.</param> /// <param name="key">The private key.</param> /// <returns>The decrypted <see cref="Credentials" />.</returns> /// <remarks> /// <note> /// The current implementation supports only the "RSA" provider. /// </note> /// </remarks> /// <exception cref="SecurityException">Thrown if the credentials are corrupt.</exception> public static Credentials DecryptCredentials(byte[] encrypted, string algorithm, string key) { try { var decrypted = Decrypt(algorithm, key, encrypted); using (var ms = new EnhancedMemoryStream(decrypted)) { string realm; string account; string password; if (ms.ReadInt32() != Crypto.CredentialMagic) { throw new SecurityException(Crypto.CorruptCredentialsMsg); } realm = ms.ReadString16(); account = ms.ReadString16(); password = ms.ReadString16(); return(new Credentials(realm, account, password)); } } catch (Exception e) { throw new SecurityException(Crypto.CorruptCredentialsMsg, e); } }
public void EnhancedMemoryStream_String() { var es = new EnhancedMemoryStream(); es.WriteString16(null); es.WriteString16("Hello World!"); es.WriteString16(new String('a', 45000)); es.Seek(0, SeekOrigin.Begin); Assert.IsNull(es.ReadString16()); Assert.AreEqual("Hello World!", es.ReadString16()); Assert.AreEqual(new String('a', 45000), es.ReadString16()); }
/// <summary> /// Decrypts and deserializes a message from a byte buffer. /// </summary> /// <param name="buffer">The buffer.</param> /// <param name="sharedKey">The shared encryption key.</param> /// <exception cref="FormatException">Thrown if the buffer does not contain a valid message.</exception> public DynDnsMessage(byte[] buffer, SymmetricKey sharedKey) { try { using (var ms = new EnhancedMemoryStream(Crypto.Decrypt(buffer, sharedKey))) { if (ms.ReadInt32Le() != Magic) { throw new Exception(); } this.Version = ms.ReadByte(); if (this.Version < FormatVer) { throw new FormatException(string.Format("DynDnsMessage version [{0}] is not supported.", this.Version)); } this.TimeStampUtc = new DateTime(ms.ReadInt64Le()); this.Flags = (DynDnsMessageFlag)ms.ReadInt32Le(); this.HostEntry = new DynDnsHostEntry(ms.ReadString16()); } } catch (Exception e) { throw new FormatException("Invalid Dynamic DNS message.", e); } }
/// <summary> /// Constructs a key chain by decrypting bytes returned by a previous /// call to <see cref="Encrypt" />. /// </summary> /// <param name="key">The <see cref="SymmetricKey" /> to be used for decrypting.</param> /// <param name="encrypted">The encrypted key chain.</param> /// <exception cref="CryptographicException">Thrown if the decrypted key chain is malformed.</exception> public KeyChain(SymmetricKey key, byte[] encrypted) { try { using (var ms = new EnhancedMemoryStream(Crypto.Decrypt(encrypted, key))) { if (ms.ReadInt32() != Magic) { throw new Exception(); } int count; count = ms.ReadInt32(); keys = new Dictionary <string, string>(count); for (int i = 0; i < count; i++) { Add(ms.ReadString16()); } } } catch (Exception e) { throw new CryptographicException("Key chain is malformed.", e); } }
/// <summary> /// Decrypts the password change parameters encrypted by <see cref="EncryptPasswordChange" />. /// </summary> /// <param name="encryptedPasswords">The encryoted password change parameters.</param> /// <param name="originalPassword">Returns as the original password.</param> /// <param name="newPassword">Returns as the new password.</param> /// <remarks> /// <note> /// This method is designed to provide a low level of security during development /// and testing, when the overhead of configuring SSL certificates is not worth /// the trouble. Do not rely on this method as your only mechanism for securing /// credentials during transmission in production environments. /// </note> /// </remarks> /// <exception cref="SecurityException">Thrown if the parameters are corrupt.</exception> public static void DecryptPasswordChange(byte[] encryptedPasswords, out string originalPassword, out string newPassword) { try { var decrypted = DecryptWithSalt8(encryptedPasswords, credentialsKey); using (var ms = new EnhancedMemoryStream(decrypted)) { if (ms.ReadInt32() != CredentialMagic) { throw new SecurityException(CorruptCredentialsMsg); } originalPassword = ms.ReadString16(); newPassword = ms.ReadString16(); } } catch (Exception e) { throw new SecurityException(CorruptCredentialsMsg, e); } }
public void EnhancedMemoryStream_VerifyBufLength() { var es = new EnhancedMemoryStream(); es.WriteInt16(5000); es.Seek(0, SeekOrigin.Begin); try { es.ReadBytes16(); Assert.Fail(); } catch { } es.Seek(0, SeekOrigin.Begin); try { es.ReadString16(); Assert.Fail(); } catch { } es.Seek(0, SeekOrigin.Begin); es.WriteInt32(500000); try { es.ReadBytes32(); Assert.Fail(); } catch { } es.Seek(0, SeekOrigin.Begin); try { es.ReadString32(); Assert.Fail(); } catch { } }
/// <summary> /// Attempts to acquire the global application lock. /// </summary> /// <remarks> /// <note> /// <see cref="Release" /> should be called promptly when the /// application terminates to release the lock. /// </note> /// </remarks> /// <exception cref="GlobalLockException">Thrown when there's a problem acquiring the lock.</exception> public unsafe void Lock() { EnhancedMemoryStream ms; byte *pMem; byte[] buf; Assembly assembly; string path; lock (syncLock) { if (initLock != null) { cLock++; // The lock is already acquired return; } try { // Use a global shared memory block to enforce the lock. assembly = Assembly.GetEntryAssembly(); if (assembly == null) { assembly = Assembly.GetCallingAssembly(); } path = Helper.StripFileScheme(assembly.CodeBase); ms = new EnhancedMemoryStream(4096); ms.WriteString16(path); initLock = new SharedMem(); initLock.Open("LT.Lock." + appName, 4096, SharedMem.OpenMode.CREATE_OPEN); pMem = initLock.Lock(); if (pMem[0] != 0 || pMem[1] != 0) { buf = new byte[initLock.Size]; for (int i = 0; i < buf.Length; i++) { buf[i] = pMem[i]; } ms = new EnhancedMemoryStream(buf); initLock.Unlock(); initLock.Close(); initLock = null; throw new GlobalLockException("Global lock is already acquired by [{0}].", ms.ReadString16()); } buf = ms.ToArray(); for (int i = 0; i < buf.Length; i++) { pMem[i] = buf[i]; } initLock.Unlock(); } catch (Exception e) { throw new GlobalLockException(e); } } cLock++; }
/// <summary> /// Decrypts a byte array encrypted using <see cref="Encrypt(string ,byte[],string,int,int,out SymmetricKey)" />. /// </summary> /// <param name="rsaKey">The decrypting RSA key as XML or as a secure key container name.</param> /// <param name="cipherText">The encrypted data.</param> /// <param name="symmetricKey">Returns as the symmetric encryption algorithm arguments.</param> /// <returns>The decrypted data.</returns> /// <exception cref="CryptographicException">Thrown is the encrypted data block is incorrectly formatted.</exception> /// <remarks> /// Note that applications should take some care to ensure that the <paramref name="symmetricKey" /> /// value return is disposed so that the symmetric encryption key will be cleared. /// </remarks> public static byte[] Decrypt(string rsaKey, byte[] cipherText, out SymmetricKey symmetricKey) { EnhancedMemoryStream input = new EnhancedMemoryStream(cipherText); EnhancedMemoryStream ms = new EnhancedMemoryStream(cipherText.Length); BlockDecryptor decryptor = null; byte[] symKey; byte[] symIV; string algorithm; try { // Read the header fields if (input.ReadInt32() != Magic) { throw new CryptographicException(BadFormatMsg); } if (input.ReadInt32() != 0) { throw new CryptographicException("Unsupported secure data format version."); } // Decrypt the encryption info ms.WriteBytesNoLen(AsymmetricCrypto.Decrypt(CryptoAlgorithm.RSA, rsaKey, input.ReadBytes16())); ms.Position = 0; algorithm = ms.ReadString16(); symKey = ms.ReadBytes16(); symIV = ms.ReadBytes16(); symmetricKey = new SymmetricKey(algorithm, symKey, symIV); decryptor = new BlockDecryptor(algorithm, symKey, symIV); // Decrypt the contents ms.SetLength(0); ms.WriteBytesNoLen(decryptor.Decrypt(input.ReadBytes32())); ms.Position = 0; if (ms.ReadInt32() != Magic) { throw new CryptographicException("Secure data content is corrupt."); } ms.Position += 8; // Skip over the salt return(ms.ReadBytes32()); } finally { if (decryptor != null) { decryptor.Dispose(); } input.Close(); ms.Close(); } }