Esempio n. 1
0
        internal static BimilItem Parse(BimilDocument document, byte[] buffer, int offset, int count)
        {
            if (count < 4)
            {
                throw new FormatException("Invalid buffer size.");
            }

            var res = new BimilItem(document);

            var currOffset = offset;

            while (currOffset < (offset + count))
            {
                var keyLength   = GetInt32(buffer, currOffset);
                var valueLength = GetInt32(buffer, currOffset + 4);
                var type        = (BimilRecordFormat)GetInt32(buffer, currOffset + 8);
                var key         = BimilValue.Parse(document, buffer, currOffset + 12, keyLength);
                var value       = BimilValue.Parse(document, buffer, currOffset + 12 + keyLength, valueLength);
                res.Records.Add(new BimilRecord(document, key.Text, value.Text, type));
                currOffset += 12 + keyLength + valueLength;
            }
            if (currOffset != (offset + count))
            {
                throw new FormatException("Invalid buffer content.");
            }

            return(res);
        }
Esempio n. 2
0
        /// <summary>
        /// Returns document.
        /// </summary>
        /// <param name="stream">Stream.</param>
        /// <param name="password">Password.</param>
        /// <exception cref="FormatException">Cannot parse document.</exception>
        public static BimilDocument Open(Stream stream, string password)
        {
            try {
                using (var timer = new Medo.Diagnostics.LifetimeWatch("Open")) {
                    var doc = new BimilDocument();

                    var salt = new byte[16];
                    stream.Read(salt, 0, 16);

                    doc.PasswordSalt = salt;

                    var deriveBytes = new Rfc2898DeriveBytes(UTF8Encoding.UTF8.GetBytes(password), doc.PasswordSalt, 4096);
                    doc.Crypto.Key = deriveBytes.GetBytes(16);
                    doc.Crypto.IV  = deriveBytes.GetBytes(16);

                    var encBuffer = new byte[stream.Length - 16];
                    stream.Read(encBuffer, 0, encBuffer.Length);

                    byte[] decBuffer;
                    using (var dec = doc.Crypto.CreateDecryptor()) {
                        decBuffer = dec.TransformFinalBlock(encBuffer, 0, encBuffer.Length);
                    }
                    if ((decBuffer[0] == 0x41) && (decBuffer[1] == 0x31) && (decBuffer[2] == 0x32) && (decBuffer[3] == 0x38))
                    {
                        if ((decBuffer[decBuffer.Length - 4] != 0x41) || (decBuffer[decBuffer.Length - 3] != 0x31) || (decBuffer[decBuffer.Length - 2] != 0x32) || (decBuffer[decBuffer.Length - 1] != 0x38))
                        {
                            throw new FormatException("Invalid secondary identifier.");
                        }
                        doc.Id = "A128";
                    }
                    else
                    {
                        throw new FormatException("Invalid primary identifier.");
                    }

                    var currOffset = 4;
                    while (currOffset < (decBuffer.Length - 4))
                    {
                        var itemLen = GetInt32(decBuffer, currOffset);
                        var item    = BimilItem.Parse(doc, decBuffer, currOffset + 4, itemLen);
                        doc.Items.Add(item);

                        currOffset += 4 + itemLen;
                    }

                    return(doc);
                }
            } catch (CryptographicException ex) {
                throw new FormatException("Cannot parse document.", ex);
            } catch (OverflowException ex) {
                throw new FormatException("Cannot parse document.", ex);
            } catch (SecurityException ex) {
                throw new FormatException("Cannot parse document.", ex);
            }
        }
Esempio n. 3
0
        internal static BimilValue Parse(BimilDocument document, byte[] buffer, int offset, int count)
        {
            var encBuffer = new byte[count];

            Buffer.BlockCopy(buffer, offset, encBuffer, 0, count);

            return(new BimilValue(document)
            {
                Bytes = encBuffer
            });
        }
Esempio n. 4
0
 /// <summary>
 /// Saves current document to stream using another password. Current document is not affected.
 /// </summary>
 /// <param name="stream">Stream.</param>
 /// <param name="newPassword">Password.</param>
 public void Save(Stream stream, string newPassword)
 {
     using (var newDoc = new BimilDocument(newPassword)) {
         foreach (var item in this.Items)
         {
             var newItem = newDoc.AddItem(item.Name, item.IconIndex);
             foreach (var record in item.Records)
             {
                 newItem.AddRecord(record.Key.Text, record.Value.Text, record.Format);
             }
         }
         newDoc.Save(stream);
     }
 }
Esempio n. 5
0
 internal BimilValue(BimilDocument document)
 {
     this.Document = document;
     this.Text     = "";
 }
Esempio n. 6
0
 internal BimilItem(BimilDocument document)
 {
     this.Document = document;
     this.Records  = new List <BimilRecord>();
 }