Beispiel #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;
        }
Beispiel #2
0
 public void MacIs48BytesLong()
 {
     byte[] data = CryptoRandom.NextBytesStatic(1227);
     byte[] key  = CryptoRandom.NextBytesStatic(32);
     using (Stream tempStream = new MemoryStream())
     {
         tempStream.Write(data, 0, data.Length);
         byte[] mac = MessageAuthenticationCodeValidator.CalculateMessageAuthenticationCode(key, tempStream);
         Assert.Equal(48, mac.Length);
     }
 }
Beispiel #3
0
 public void MacCanBeValidated()
 {
     byte[] data = CryptoRandom.NextBytesStatic(1227);
     byte[] key  = CryptoRandom.NextBytesStatic(32);
     using (Stream tempStream = new MemoryStream())
     {
         tempStream.Write(data, 0, data.Length);
         bool   error = false;
         byte[] mac   = MessageAuthenticationCodeValidator.CalculateMessageAuthenticationCode(key, tempStream);
         try
         {
             MessageAuthenticationCodeValidator.ValidateMessageAuthenticationCode(key, mac, tempStream);
         }
         catch (DataIntegrityValidationException)
         {
             error = true;
         }
         Assert.False(error);
     }
 }
Beispiel #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);
        }