예제 #1
0
        /// <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);
            }
        }
예제 #2
0
        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());
        }
예제 #3
0
        /// <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);
            }
        }
예제 #4
0
        /// <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);
            }
        }
예제 #5
0
        /// <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);
            }
        }
예제 #6
0
        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
            {
            }
        }
예제 #7
0
        /// <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++;
        }
예제 #8
0
        /// <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();
            }
        }