/* This is a little confusing so pay attention. new_key in this context is the new submitted key. old_key is the key we have in the database. Since we might have data that the new_key doesn't we merge into the old_key producing the "new new_key" that we want to store in the db in the old_key malloc'd region. */ int merge_keys(struct openPGP_pubkey *new_key, struct openPGP_pubkey *old_key) { struct user_id *walk_id_old = NULL; struct user_id *walk_id_new = NULL; struct user_id *next_id = NULL; struct user_id *last_id = NULL; unsigned int new_stuff = 0; unsigned int id_found = 0; int result = 0; #ifdef DEBUG fprintf(stderr,"Merge keys called.\n"); #endif walk_id_new = (struct user_id *)get_first_uid(new_key->ids); if(walk_id_new == NULL) { fprintf(stderr,_("merge_keys.c: get_first_uid failed and returned NULL.\n")); new_key->key_status = -1; return -1; } while(walk_id_new != NULL) { walk_id_old = (struct user_id *)get_first_uid(old_key->ids); while(walk_id_old != NULL) { if(strcmp(walk_id_new->id_data,walk_id_old->id_data) == 0) { id_found = 1; break; } walk_id_old = walk_id_old->next; } /* The ID was not found. So it is added to the key from the keyservers database */ if(!id_found) { #ifdef DEBUG fprintf(stderr,"New ID Found\n"); #endif new_stuff = 1; /* Append UID and Signatures */ last_id = (struct user_id *)get_last_uid(old_key->ids); if(last_id == NULL) { next_id = walk_id_new->next; extract_uid(walk_id_new); last_id = walk_id_new; last_id->next = NULL; } else { next_id = walk_id_new->next; extract_uid(walk_id_new); last_id->next = walk_id_new; last_id = walk_id_new; last_id->next = NULL; } } else { /* The ID is not new. So, we move on to merging the signature packets */ result = merge_signatures(walk_id_new, walk_id_old); if(result == -1) { fprintf(stderr,_("merge_keys.c: merge_signatures failure.\n")); new_key->key_status = -1; return -1; } else if(result == 1) { new_stuff = 1; } } if(!id_found) { walk_id_new = next_id; } else { id_found = 0; walk_id_new = walk_id_new->next; } } result = merge_subkeys(new_key->subkeys,old_key->subkeys); if(result == -1) { fprintf(stderr,_("merge_keys.c: merge_subkeys failure.\n")); new_key->key_status = -1; return -1; } else if(result == 1) { new_stuff = 1; } return new_stuff; }
static value_ptr extract_object(bplist_info_ptr bplist, uint64_t objectRef) { uint64_t offset; value_ptr result = NULL; uint8_t objectTag; if (objectRef >= bplist->object_count) { // Out-of-range object reference. bplist_log("Bad binary plist: object index is out of range.\n"); return NULL; } // Use cached object if it exists result = cache_lookup(bplist->cache, objectRef); if (result != NULL) return result; // Otherwise, find object in file. offset = read_offset(bplist, objectRef); if (offset > bplist->length) { // Out-of-range offset. bplist_log("Bad binary plist: object outside container.\n"); return NULL; } objectTag = *(bplist->data_bytes + offset); switch (objectTag & 0xF0) { case kTAG_SIMPLE: result = extract_simple(bplist, offset); break; case kTAG_INT: result = extract_int(bplist, offset); break; case kTAG_REAL: result = extract_real(bplist, offset); break; case kTAG_DATE: result = extract_date(bplist, offset); break; case kTAG_DATA: result = extract_data(bplist, offset); break; case kTAG_ASCIISTRING: result = extract_ascii_string(bplist, offset); break; case kTAG_UNICODESTRING: result = extract_unicode_string(bplist, offset); break; case kTAG_UID: result = extract_uid(bplist, offset); break; case kTAG_ARRAY: result = extract_array(bplist, offset); break; case kTAG_DICTIONARY: result = extract_dictionary(bplist, offset); break; default: // Unknown tag. bplist_log("Bad binary plist: unknown tag 0x%X.\n", (objectTag & 0x0F) >> 4); result = NULL; } // Cache and return result. if (result != NULL) cache_insert(&bplist->cache, objectRef, result); return result; }