Changeset View
Changeset View
Standalone View
Standalone View
b/g10/keydb.c
Context not available. | |||||
static int used_resources; | static int used_resources; | ||||
static void *primary_keyring=NULL; | static void *primary_keyring=NULL; | ||||
/* This is a simple cache used to return the last result of a | |||||
successful fingerprint search. This works only for keybox resources | |||||
because (due to lack of a copy_keyblock function) we need to store | |||||
an image of the keyblock which is fortunately instantly available | |||||
for keyboxes. */ | |||||
enum keyblock_cache_states { | |||||
KEYBLOCK_CACHE_EMPTY, | |||||
KEYBLOCK_CACHE_PREPARED, | |||||
KEYBLOCK_CACHE_FILLED | |||||
}; | |||||
struct keyblock_cache { | |||||
enum keyblock_cache_states state; | |||||
byte fpr[MAX_FINGERPRINT_LEN]; | |||||
iobuf_t iobuf; /* Image of the keyblock. */ | |||||
u32 *sigstatus; | |||||
int pk_no; | |||||
int uid_no; | |||||
}; | |||||
struct keydb_handle | struct keydb_handle | ||||
{ | { | ||||
/* When we locked all of the resources in ACTIVE (using keyring_lock | /* When we locked all of the resources in ACTIVE (using keyring_lock | ||||
Context not available. | |||||
/* The number of resources in ACTIVE. */ | /* The number of resources in ACTIVE. */ | ||||
int used; | int used; | ||||
/* Cache of the last found and parsed key block (only used for | |||||
keyboxes, not keyrings). */ | |||||
struct keyblock_cache keyblock_cache; | |||||
/* Copy of ALL_RESOURCES when keydb_new is called. */ | /* Copy of ALL_RESOURCES when keydb_new is called. */ | ||||
struct resource_item active[MAX_KEYDB_RESOURCES]; | struct resource_item active[MAX_KEYDB_RESOURCES]; | ||||
}; | }; | ||||
Context not available. | |||||
}; | }; | ||||
/* This is a simple cache used to return the last result of a | |||||
successful fingerprint search. This works only for keybox resources | |||||
because (due to lack of a copy_keyblock function) we need to store | |||||
an image of the keyblock which is fortunately instantly available | |||||
for keyboxes. */ | |||||
enum keyblock_cache_states { | |||||
KEYBLOCK_CACHE_EMPTY, | |||||
KEYBLOCK_CACHE_PREPARED, | |||||
KEYBLOCK_CACHE_FILLED | |||||
}; | |||||
struct { | |||||
enum keyblock_cache_states state; | |||||
byte fpr[MAX_FINGERPRINT_LEN]; | |||||
iobuf_t iobuf; /* Image of the keyblock. */ | |||||
u32 *sigstatus; | |||||
int pk_no; | |||||
int uid_no; | |||||
} keyblock_cache; | |||||
static int lock_all (KEYDB_HANDLE hd); | static int lock_all (KEYDB_HANDLE hd); | ||||
static void unlock_all (KEYDB_HANDLE hd); | static void unlock_all (KEYDB_HANDLE hd); | ||||
Context not available. | |||||
static void | static void | ||||
keyblock_cache_clear (void) | keyblock_cache_clear (struct keydb_handle *hd) | ||||
{ | { | ||||
keyblock_cache.state = KEYBLOCK_CACHE_EMPTY; | hd->keyblock_cache.state = KEYBLOCK_CACHE_EMPTY; | ||||
xfree (keyblock_cache.sigstatus); | xfree (hd->keyblock_cache.sigstatus); | ||||
keyblock_cache.sigstatus = NULL; | hd->keyblock_cache.sigstatus = NULL; | ||||
iobuf_close (keyblock_cache.iobuf); | iobuf_close (hd->keyblock_cache.iobuf); | ||||
keyblock_cache.iobuf = NULL; | hd->keyblock_cache.iobuf = NULL; | ||||
} | } | ||||
Context not available. | |||||
if (DBG_CLOCK) | if (DBG_CLOCK) | ||||
log_clock ("keydb_get_keybock enter"); | log_clock ("keydb_get_keybock enter"); | ||||
if (keyblock_cache.state == KEYBLOCK_CACHE_FILLED) | if (hd->keyblock_cache.state == KEYBLOCK_CACHE_FILLED) | ||||
{ | { | ||||
iobuf_seek (keyblock_cache.iobuf, 0); | iobuf_seek (hd->keyblock_cache.iobuf, 0); | ||||
err = parse_keyblock_image (keyblock_cache.iobuf, | err = parse_keyblock_image (hd->keyblock_cache.iobuf, | ||||
keyblock_cache.pk_no, | hd->keyblock_cache.pk_no, | ||||
keyblock_cache.uid_no, | hd->keyblock_cache.uid_no, | ||||
keyblock_cache.sigstatus, | hd->keyblock_cache.sigstatus, | ||||
ret_kb); | ret_kb); | ||||
if (err) | if (err) | ||||
keyblock_cache_clear (); | keyblock_cache_clear (hd); | ||||
if (DBG_CLOCK) | if (DBG_CLOCK) | ||||
log_clock (err? "keydb_get_keyblock leave (cached, failed)" | log_clock (err? "keydb_get_keyblock leave (cached, failed)" | ||||
: "keydb_get_keyblock leave (cached)"); | : "keydb_get_keyblock leave (cached)"); | ||||
Context not available. | |||||
{ | { | ||||
err = parse_keyblock_image (iobuf, pk_no, uid_no, sigstatus, | err = parse_keyblock_image (iobuf, pk_no, uid_no, sigstatus, | ||||
ret_kb); | ret_kb); | ||||
if (!err && keyblock_cache.state == KEYBLOCK_CACHE_PREPARED) | if (!err && hd->keyblock_cache.state == KEYBLOCK_CACHE_PREPARED) | ||||
{ | { | ||||
keyblock_cache.state = KEYBLOCK_CACHE_FILLED; | hd->keyblock_cache.state = KEYBLOCK_CACHE_FILLED; | ||||
keyblock_cache.sigstatus = sigstatus; | hd->keyblock_cache.sigstatus = sigstatus; | ||||
keyblock_cache.iobuf = iobuf; | hd->keyblock_cache.iobuf = iobuf; | ||||
keyblock_cache.pk_no = pk_no; | hd->keyblock_cache.pk_no = pk_no; | ||||
keyblock_cache.uid_no = uid_no; | hd->keyblock_cache.uid_no = uid_no; | ||||
} | } | ||||
else | else | ||||
{ | { | ||||
Context not available. | |||||
break; | break; | ||||
} | } | ||||
if (keyblock_cache.state != KEYBLOCK_CACHE_FILLED) | if (hd->keyblock_cache.state != KEYBLOCK_CACHE_FILLED) | ||||
keyblock_cache_clear (); | keyblock_cache_clear (hd); | ||||
if (DBG_CLOCK) | if (DBG_CLOCK) | ||||
log_clock (err? "keydb_get_keyblock leave (failed)" | log_clock (err? "keydb_get_keyblock leave (failed)" | ||||
Context not available. | |||||
return gpg_error (GPG_ERR_INV_ARG); | return gpg_error (GPG_ERR_INV_ARG); | ||||
kid_not_found_flush (); | kid_not_found_flush (); | ||||
keyblock_cache_clear (); | keyblock_cache_clear (hd); | ||||
if (hd->found < 0 || hd->found >= hd->used) | if (hd->found < 0 || hd->found >= hd->used) | ||||
return gpg_error (GPG_ERR_VALUE_NOT_FOUND); | return gpg_error (GPG_ERR_VALUE_NOT_FOUND); | ||||
Context not available. | |||||
return gpg_error (GPG_ERR_INV_ARG); | return gpg_error (GPG_ERR_INV_ARG); | ||||
kid_not_found_flush (); | kid_not_found_flush (); | ||||
keyblock_cache_clear (); | keyblock_cache_clear (hd); | ||||
if (opt.dry_run) | if (opt.dry_run) | ||||
return 0; | return 0; | ||||
Context not available. | |||||
return gpg_error (GPG_ERR_INV_ARG); | return gpg_error (GPG_ERR_INV_ARG); | ||||
kid_not_found_flush (); | kid_not_found_flush (); | ||||
keyblock_cache_clear (); | keyblock_cache_clear (hd); | ||||
if (hd->found < 0 || hd->found >= hd->used) | if (hd->found < 0 || hd->found >= hd->used) | ||||
return gpg_error (GPG_ERR_VALUE_NOT_FOUND); | return gpg_error (GPG_ERR_VALUE_NOT_FOUND); | ||||
Context not available. | |||||
{ | { | ||||
int i, rc; | int i, rc; | ||||
keyblock_cache_clear (); | |||||
for (i=0; i < used_resources; i++) | for (i=0; i < used_resources; i++) | ||||
{ | { | ||||
if (!keyring_is_writable (all_resources[i].token)) | if (!keyring_is_writable (all_resources[i].token)) | ||||
Context not available. | |||||
if (!hd) | if (!hd) | ||||
return gpg_error (GPG_ERR_INV_ARG); | return gpg_error (GPG_ERR_INV_ARG); | ||||
keyblock_cache_clear (); | keyblock_cache_clear (hd); | ||||
if (DBG_CLOCK) | if (DBG_CLOCK) | ||||
log_clock ("keydb_search_reset"); | log_clock ("keydb_search_reset"); | ||||
Context not available. | |||||
&& ndesc == 1 | && ndesc == 1 | ||||
&& (desc[0].mode == KEYDB_SEARCH_MODE_FPR20 | && (desc[0].mode == KEYDB_SEARCH_MODE_FPR20 | ||||
|| desc[0].mode == KEYDB_SEARCH_MODE_FPR) | || desc[0].mode == KEYDB_SEARCH_MODE_FPR) | ||||
&& keyblock_cache.state == KEYBLOCK_CACHE_FILLED | && hd->keyblock_cache.state == KEYBLOCK_CACHE_FILLED | ||||
&& !memcmp (keyblock_cache.fpr, desc[0].u.fpr, 20)) | && !memcmp (hd->keyblock_cache.fpr, desc[0].u.fpr, 20)) | ||||
{ | { | ||||
/* (DESCINDEX is already set). */ | /* (DESCINDEX is already set). */ | ||||
if (DBG_CLOCK) | if (DBG_CLOCK) | ||||
Context not available. | |||||
? gpg_error (GPG_ERR_NOT_FOUND) | ? gpg_error (GPG_ERR_NOT_FOUND) | ||||
: rc); | : rc); | ||||
keyblock_cache_clear (); | keyblock_cache_clear (hd); | ||||
if (!hd->no_caching | if (!hd->no_caching | ||||
&& !rc | && !rc | ||||
&& ndesc == 1 && (desc[0].mode == KEYDB_SEARCH_MODE_FPR20 | && ndesc == 1 && (desc[0].mode == KEYDB_SEARCH_MODE_FPR20 | ||||
|| desc[0].mode == KEYDB_SEARCH_MODE_FPR)) | || desc[0].mode == KEYDB_SEARCH_MODE_FPR)) | ||||
{ | { | ||||
keyblock_cache.state = KEYBLOCK_CACHE_PREPARED; | hd->keyblock_cache.state = KEYBLOCK_CACHE_PREPARED; | ||||
memcpy (keyblock_cache.fpr, desc[0].u.fpr, 20); | memcpy (hd->keyblock_cache.fpr, desc[0].u.fpr, 20); | ||||
} | } | ||||
if (gpg_err_code (rc) == GPG_ERR_NOT_FOUND | if (gpg_err_code (rc) == GPG_ERR_NOT_FOUND | ||||
Context not available. |