Example #1
0
        public async Task WriteChecksAndEmbeddedDataAsync()
        {
            OutData.Position = 0;
            await OutData.WriteAsync(BitConverter.GetBytes(MagicNumber), 0, 4);

            await OutData.WriteAsync(BitConverter.GetBytes(DataVersionNumber), 0, 2);

            await OutData.WriteAsync(BitConverter.GetBytes(MinCompatibleDataVersionNumber), 0, 2);

            await OutData.WriteAsync(IV, 0, 16);

            await OutData.WriteAsync(Salt, 0, 32);

            var kcv = KeyCheckValueValidator.GenerateKeyCheckValue(Key);

            OutData.Write(kcv, 0, 19);

            long currentPosition = OutData.Position;
            var  mac             = MessageAuthenticationCodeValidator.CalculateMessageAuthenticationCode(Key, OutData, HeaderSize);

            Debug.Assert(currentPosition == OutData.Position, "Stream position is changed after generating MAC");
            await OutData.WriteAsync(mac, 0, 48);

            OutData.Position = 0;
        }
        public void AlteredKeyCheckValueIsNotValid()
        {
            byte[] key = CryptoRandom.NextBytesStatic(32);
            byte[] kcv = KeyCheckValueValidator.GenerateKeyCheckValue(key);
            if (key[0] > 120)
            {
                key[0]--;
            }
            else
            {
                key[0]++;
            }

            bool exceptionWasThrown = false;

            try
            {
                KeyCheckValueValidator.ValidateKeyCheckValue(key, kcv);
            }
            catch (KeyCheckValueValidationException)
            {
                exceptionWasThrown = true;
            }

            Assert.True(exceptionWasThrown, "Validation of KCV should have failed, but it didn't");
        }
        public void UnalteredKeyCheckValueIsValid()
        {
            byte[] key = CryptoRandom.NextBytesStatic(32);
            byte[] kcv = KeyCheckValueValidator.GenerateKeyCheckValue(key);

            bool exceptionWasThrown = false;

            try
            {
                KeyCheckValueValidator.ValidateKeyCheckValue(key, kcv);
            }
            catch (KeyCheckValueValidationException)
            {
                exceptionWasThrown = true;
            }

            Assert.False(exceptionWasThrown, "Validation of KCV has failed");
        }
Example #4
0
        private ValidationResult ReadAndValidateDataForDecryption(bool skipKeyCheck)
        {
            var result = new ValidationResult();

            // InData.Position = 0;
            if (InData.Length < HeaderSize)
            {
                result.SetException(DataFormatValidationException.DataValidationErrors.DataIsTooShort);
                return(result);
            }

            int   magic          = GetHeaderInt32(0);
            short dataVersion    = GetHeaderInt16(4);
            short minDataVersion = GetHeaderInt16(6);

            IV = GetIV();
            byte[] salt = GetHeaderBytes(24, 32);
            KeyCheckValue             = GetHeaderBytes(56, 19);
            MessageAuthenticationCode = GetHeaderBytes(75, 48);
            int additionalDataLength = GetHeaderInt32(123); // additional data not supported in this version

            if (EmbedSalt)
            {
                Salt = salt;
                Key  = new PasswordHasher().HashPassword(_password, salt);
            }
            else
            {
                salt = Salt;
            }

            if (magic != MagicNumber)
            {
                result.SetException(DataFormatValidationException.DataValidationErrors.InvalidMagicNumber);
                return(result);
            }
            result.DataFormatIsValid = true;

            if (minDataVersion != MinCompatibleDataVersionNumber)
            {
                result.SetException(DataFormatValidationException.DataValidationErrors.UnsupportedDataVersion);
                return(result);
            }
            result.DataFormatVersionIsValid = true;
            result.DataFormatVersionIsExact = dataVersion == DataVersionNumber;

            InData.Position = HeaderSize + additionalDataLength;
            HeaderTotalSize = (int)InData.Position;
            if (!skipKeyCheck)
            {
                bool kcvPass = KeyCheckValueValidator.ValidateKeyCheckValueInternal(Key, KeyCheckValue);
                if (!kcvPass)
                {
                    result.SetException(DataFormatValidationException.DataValidationErrors.KeyCheckValueValidationError);
                    return(result);
                }
            }

            result.KeyIsValid = true;

            if (!skipKeyCheck)
            {
                bool macIsValid = MessageAuthenticationCodeValidator.ValidateMessageAuthenticationCodeInternal(Key, MessageAuthenticationCode, InData, HeaderSize);
                if (!macIsValid)
                {
                    result.SetException(DataFormatValidationException.DataValidationErrors.DataIntegrityValidationError);
                    return(result);
                }
            }
            result.DataIntegrityIsValid = true;
            return(result);
        }
 public void KeyCheckValidIs19BytesLong()
 {
     byte[] key = CryptoRandom.NextBytesStatic(32);
     byte[] kcv = KeyCheckValueValidator.GenerateKeyCheckValue(key);
     Assert.True(kcv.Length == 19, "KCV is not 19 bytes long");
 }