void Key_file::Entry::load (std::istream& in) { while (true) { uint32_t field_id; if (!read_be32(in, field_id)) { throw Malformed(); } if (field_id == KEY_FIELD_END) { break; } uint32_t field_len; if (!read_be32(in, field_len)) { throw Malformed(); } if (field_id == KEY_FIELD_VERSION) { if (field_len != 4) { throw Malformed(); } if (!read_be32(in, version)) { throw Malformed(); } } else if (field_id == KEY_FIELD_AES_KEY) { if (field_len != AES_KEY_LEN) { throw Malformed(); } in.read(reinterpret_cast<char*>(aes_key), AES_KEY_LEN); if (in.gcount() != AES_KEY_LEN) { throw Malformed(); } } else if (field_id == KEY_FIELD_HMAC_KEY) { if (field_len != HMAC_KEY_LEN) { throw Malformed(); } in.read(reinterpret_cast<char*>(hmac_key), HMAC_KEY_LEN); if (in.gcount() != HMAC_KEY_LEN) { throw Malformed(); } } else if (field_id & 1) { // unknown critical field throw Incompatible(); } else { // unknown non-critical field - safe to ignore if (field_len > MAX_FIELD_LEN) { throw Malformed(); } in.ignore(field_len); if (in.gcount() != static_cast<std::streamsize>(field_len)) { throw Malformed(); } } } }
void Key_file::load (std::istream& in) { unsigned char preamble[16]; in.read(reinterpret_cast<char*>(preamble), 16); if (in.gcount() != 16) { throw Malformed(); } if (std::memcmp(preamble, "\0GITCRYPTKEY", 12) != 0) { throw Malformed(); } if (load_be32(preamble + 12) != FORMAT_VERSION) { throw Incompatible(); } load_header(in); while (in.peek() != -1) { Entry entry; entry.load(in); add(entry); } }
void Key_file::Entry::load_legacy (uint32_t arg_version, std::istream& in) { version = arg_version; // First comes the AES key in.read(reinterpret_cast<char*>(aes_key), AES_KEY_LEN); if (in.gcount() != AES_KEY_LEN) { throw Malformed(); } // Then the HMAC key in.read(reinterpret_cast<char*>(hmac_key), HMAC_KEY_LEN); if (in.gcount() != HMAC_KEY_LEN) { throw Malformed(); } if (in.peek() != -1) { // Trailing data is a good indication that we are not actually reading a // legacy key file. (This is important to check since legacy key files // did not have any sort of file header.) throw Malformed(); } }
void Key_file::load_header (std::istream& in) { while (true) { uint32_t field_id; if (!read_be32(in, field_id)) { throw Malformed(); } if (field_id == HEADER_FIELD_END) { break; } uint32_t field_len; if (!read_be32(in, field_len)) { throw Malformed(); } if (field_id == HEADER_FIELD_KEY_NAME) { if (field_len > KEY_NAME_MAX_LEN) { throw Malformed(); } if (field_len == 0) { // special case field_len==0 to avoid possible undefined behavior // edge cases with an empty std::vector (particularly, &bytes[0]). key_name.clear(); } else { std::vector<char> bytes(field_len); in.read(&bytes[0], field_len); if (in.gcount() != static_cast<std::streamsize>(field_len)) { throw Malformed(); } key_name.assign(&bytes[0], field_len); } if (!validate_key_name(key_name.c_str())) { key_name.clear(); throw Malformed(); } } else if (field_id & 1) { // unknown critical field throw Incompatible(); } else { // unknown non-critical field - safe to ignore if (field_len > MAX_FIELD_LEN) { throw Malformed(); } in.ignore(field_len); if (in.gcount() != static_cast<std::streamsize>(field_len)) { throw Malformed(); } } } }
void RegexpMatcherManager::Modify (const QString& title, const QString& newBody) { if (!IsRegexpValid (title) || !IsRegexpValid (newBody)) throw Malformed ("Regexp is malformed"); items_t::iterator found = std::find_if (Items_.begin (), Items_.end (), boost::bind (boost::function<bool (const RegexpMatcherManager::RegexpItem&, const QString)> (&RegexpMatcherManager::RegexpItem::IsEqual), _1, title)); if (found == Items_.end ()) throw NotFound ("Regexp user tried to modify doesn't exist in the RegexpMatcherManager"); found->Body_ = newBody; int dst = std::distance (Items_.begin (), found); emit dataChanged (index (dst, 1), index (dst, 1)); ScheduleSave (); }
void RegexpMatcherManager::Add (const QString& title, const QString& body) { if (!IsRegexpValid (title) || !IsRegexpValid (body)) throw Malformed ("Regexp is malformed"); items_t::const_iterator found = std::find_if (Items_.begin (), Items_.end (), boost::bind (boost::function<bool (const RegexpMatcherManager::RegexpItem&, const QString)> (&RegexpMatcherManager::RegexpItem::IsEqual), _1, title)); if (found != Items_.end ()) throw AlreadyExists ("Regexp user tries to add already exists in the RegexpMatcherManager"); beginInsertRows (QModelIndex (), rowCount (), rowCount ()); Items_.push_back (RegexpItem (title, body)); endInsertRows (); ScheduleSave (); }