Пример #1
0
        private byte[] DeriveKeyEncryptionKey_v1(KeyBag item, string password)
        {
            byte[] result = default;

            using (var generator = new Rfc2898DeriveBytes(password, item.Salt, item.Iterations, HashAlgorithmName.SHA1))
            {
                result = generator.GetBytes(32);
            }

            return(result);
        }
Пример #2
0
        private static IReadOnlyDictionary <ProtectionClass, byte[]> UnwrapClassKeys(KeyBag item, byte[] kek)
        {
            var result = new Dictionary <ProtectionClass, byte[]>();

            foreach (var wrappedKey in item.WrappedKeys)
            {
                var key = UnwrapClassKey(wrappedKey, kek);
                if (key != default)
                {
                    result.Add(wrappedKey.ProtectionClass, key);
                }
            }

            return(result);
        }
Пример #3
0
        public void UnwrapClassKeysFromKeyBag(KeyBag keyBag, string password)
        {
            if (keyBag is null)
            {
                throw new ArgumentNullException(nameof(keyBag));
            }

            _logger.LogInformation("Unwrapping class keys");

            var kek = (keyBag.DataProtection is null)
                ? DeriveKeyEncryptionKey_v1(keyBag, password)
                : DeriveKeyEncryptionKey_v2(keyBag, password);

            _classKeys = UnwrapClassKeys(keyBag, kek);
        }
Пример #4
0
        private byte[] DeriveKeyEncryptionKey_v2(KeyBag item, string password)
        {
            byte[] result = default;

            using (var gen1 = new Rfc2898DeriveBytes(password, item.DataProtection.Dpsl, item.DataProtection.Dpic, HashAlgorithmName.SHA256))
            {
                var derivedPasscode = gen1.GetBytes(32);

                using (var gen2 = new Rfc2898DeriveBytes(derivedPasscode, item.Salt, item.Iterations, HashAlgorithmName.SHA1))
                {
                    result = gen2.GetBytes(32);
                }
            }

            return(result);
        }
Пример #5
0
        public static void SetValue(this KeyBag item, string blockIdentifier, ReadOnlySpan <byte> value)
        {
            switch (blockIdentifier)
            {
            case KeyBagConstants.VersionTag:
                item.Version = BinaryPrimitives.ReadInt32BigEndian(value);
                break;

            case KeyBagConstants.TypeTag:
                item.KeyBagType = (KeyBagType)BinaryPrimitives.ReadInt32BigEndian(value);
                break;

            case KeyBagConstants.UuidTag:
                item.Uuid = ReadGuidBigEndian(value);
                break;

            case KeyBagConstants.HmckTag:
                item.HMCK = value.ToArray();
                break;

            case KeyBagConstants.WrapTag:
                item.Wrap = BinaryPrimitives.ReadInt32BigEndian(value);
                break;

            case KeyBagConstants.SaltTag:
                item.Salt = value.ToArray();
                break;

            case KeyBagConstants.IterTag:
                item.Iterations = BinaryPrimitives.ReadInt32BigEndian(value);
                break;

            case KeyBagConstants.DpwtTag:
            case KeyBagConstants.DpicTag:
            case KeyBagConstants.DpslTag:
                SetDataProtectionValue(item, blockIdentifier, value);
                break;

            default:
                throw new InvalidDataException($"Unexpected block identifier \"{blockIdentifier}\"");
            }
        }
Пример #6
0
 public static void ConsoleWrite(this KeyBag item)
 {
     Console.WriteLine($"Version={item.Version}");
     Console.WriteLine($"KeyBagType={item.KeyBagType}");
     Console.WriteLine($"UUID={item.Uuid}");
     Console.WriteLine("HMCK=" + CommonHelpers.ByteArrayToDebugString(item.HMCK));
     Console.WriteLine($"WRAP={item.Wrap}");
     Console.WriteLine("SALT=" + CommonHelpers.ByteArrayToDebugString(item.Salt));
     Console.WriteLine($"ITER={item.Iterations}");
     if (item.DataProtection != null)
     {
         Console.WriteLine($"DPWT={item.DataProtection.Dpwt}");
         Console.WriteLine($"DPIC={item.DataProtection.Dpic}");
         Console.WriteLine($"DPSL={item.DataProtection.Dpsl}");
     }
     foreach (var key in item.WrappedKeys)
     {
         key.ConsoleWrite();
     }
 }
Пример #7
0
        private static void SetDataProtectionValue(KeyBag item, string blockIdentifier, ReadOnlySpan <byte> value)
        {
            if (item.DataProtection == null)
            {
                item.DataProtection = new DataProtectionKeyData();
            }
            switch (blockIdentifier)
            {
            case KeyBagConstants.DpwtTag:
                item.DataProtection.Dpwt = BinaryPrimitives.ReadInt32BigEndian(value);
                break;

            case KeyBagConstants.DpicTag:
                item.DataProtection.Dpic = BinaryPrimitives.ReadInt32BigEndian(value);
                break;

            case KeyBagConstants.DpslTag:
                item.DataProtection.Dpsl = value.ToArray();
                break;

            default:
                throw new InvalidDataException($"Unexpected block identifier \"{blockIdentifier}\"");
            }
        }
Пример #8
0
        public static KeyBag Read(byte[] data)
        {
            if (data is null)
            {
                throw new ArgumentNullException(nameof(data));
            }

            KeyBag result = default;

            var         state      = ReaderState.Invalid;
            KeyBagEntry currentKey = default;
            var         keys       = new List <KeyBagEntry>();
            var         length     = data.Length;
            var         position   = 0;

            while (position < length)
            {
                var blockIdentifier = Encoding.ASCII.GetString(data, position, 4);
                position += 4;

                var blockLength = BinaryPrimitives.ReadInt32BigEndian(data.AsSpan(position, 4));
                position += 4;

                var value = data.AsSpan(position, blockLength);

                if (state == ReaderState.Invalid)
                {
                    state = ReaderState.ReadHeader;
                }
                if (state == ReaderState.ReadHeader)
                {
                    if (result is null)
                    {
                        result = new KeyBag();
                    }
                    if (blockIdentifier == KeyBagConstants.UuidTag && result.Uuid != Guid.Empty)
                    {
                        state = ReaderState.ReadKeyBagEntry;
                    }
                    else
                    {
                        result.SetValue(blockIdentifier, value);
                    }
                }
                if (state == ReaderState.ReadKeyBagEntry)
                {
                    if (blockIdentifier == KeyBagConstants.UuidTag)
                    {
                        if (currentKey != null)
                        {
                            keys.Add(currentKey);
                        }
                        currentKey = new KeyBagEntry();
                    }

                    currentKey.SetValue(blockIdentifier, value);
                }
                position += blockLength;
            }
            if (result != null)
            {
                if (currentKey != null)
                {
                    keys.Add(currentKey);
                }
                result.WrappedKeys = keys.ToArray();
            }

            return(result);
        }