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_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(); } } } }
static IO_clp bindIO(IOOffer_cl *io_offer, HeapMod_cl *hmod, Heap_clp *heap) { IO_clp res; IOData_Shm *shm; if(io_offer != NULL) { if(*heap) { /* We have some memory => bind using it */ Type_Any any; IDCClientBinding_clp cb; shm = SEQ_NEW(IOData_Shm, 1, Pvs(heap)); SEQ_ELEM(shm, 0).buf.base = HeapMod$Where(hmod, *heap, &(SEQ_ELEM(shm, 0).buf.len)); SEQ_ELEM(shm, 0).param.attrs = 0; SEQ_ELEM(shm, 0).param.awidth = PAGE_WIDTH; SEQ_ELEM(shm, 0).param.pwidth = PAGE_WIDTH; cb = IOOffer$ExtBind(io_offer, shm, Pvs(gkpr), &any); if(!ISTYPE(&any, IO_clp)) { eprintf("udp_socket.c [bindIO]: IOOffer$ExtBind failed.\n"); if(cb) IDCClientBinding$Destroy(cb); RAISE_TypeSystem$Incompatible(); } res = NARROW (&any, IO_clp); } else { /* Just bind to offer and create a heap afterwards. */ res = IO_BIND(io_offer); shm = IO$QueryShm(res); if(SEQ_LEN(shm) != 1) eprintf("udp_socket.c [bindIO]: " "got > 1 data areas in channel!\n"); /* Ignore extra areas for now */ *heap = HeapMod$NewRaw(hmod, SEQ_ELEM(shm, 0).buf.base, SEQ_ELEM(shm, 0).buf.len); } return res; } return (IO_cl *)NULL; }
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); } }