allow a key to be created with a known prefix (so that we can debug

birthday paradox problems).
This commit is contained in:
gardners 2016-04-28 16:39:06 +02:00
parent c78ee668d5
commit 14ed84dabc
4 changed files with 37 additions and 9 deletions

View File

@ -1298,12 +1298,23 @@ static int keyring_commit_identity(keyring_file *k, keyring_identity *id)
return 1;
}
int keyring_key_prefix_mismatch(keypair *kp, const char *prefix)
{
if (!prefix[0]) return 0;
char hex[5];
snprintf(hex,5,"%02x%02x",kp->public_key[0],kp->public_key[1]);
int r=strncasecmp(hex,prefix,strlen(prefix));
return r;
}
/* Create a new identity in the specified context (which supplies the keyring pin) with the
* specified PKR pin. The crypto_box and crypto_sign key pairs are automatically created, and the
* PKR is packed and written to a hithero unallocated slot which is then marked full. Requires an
* explicit call to keyring_commit()
*/
keyring_identity *keyring_create_identity(keyring_file *k, const char *pin)
keyring_identity *keyring_create_identity(keyring_file *k, const char *pin,
const char *prefix)
{
DEBUGF(keyring, "k=%p", k);
/* Check obvious abort conditions early */
@ -1326,14 +1337,28 @@ keyring_identity *keyring_create_identity(keyring_file *k, const char *pin)
goto kci_safeexit;
}
/* Allocate key pairs */
/* Allocate key pairs.
The prefix input allows rejection of keys until the public key matches a
given prefix. The prefix lenth is not allowed to be more than 16 bits to
prevent abuse and excessive compromising of security.
*/
unsigned ktype;
for (ktype = 1; ktype < NELS(keytypes); ++ktype) {
if (keytypes[ktype].creator) {
keypair *kp = keyring_alloc_keypair(ktype, 0);
keypair *kp = NULL;
while (kp==NULL) {
kp = keyring_alloc_keypair(ktype, 0);
if (kp == NULL)
goto kci_safeexit;
keytypes[ktype].creator(kp);
if (kp->public_key&&
keyring_key_prefix_mismatch(kp,prefix)) {
keyring_free_keypair(kp);
kp=NULL;
}
}
if (kp == NULL)
goto kci_safeexit;
keyring_identity_add_keypair(id, kp);
}
}
@ -1950,7 +1975,7 @@ int keyring_seed(keyring_file *k)
/* nothing to do if there is already an identity */
if (k->identities)
return 0;
keyring_identity *id=keyring_create_identity(k,"");
keyring_identity *id=keyring_create_identity(k,"","");
if (!id)
return WHY("Could not create new identity");
if (keyring_commit(k))

View File

@ -109,7 +109,8 @@ struct keypair *keyring_find_sas_private(keyring_file *k, keyring_identity *iden
int keyring_send_sas_request(struct subscriber *subscriber);
int keyring_commit(keyring_file *k);
keyring_identity *keyring_create_identity(keyring_file *k, const char *pin);
keyring_identity *keyring_create_identity(keyring_file *k, const char *pin,
const char *prefix);
int keyring_seed(keyring_file *k);
void keyring_identity_extract(const keyring_identity *id, const sid_t **sidp, const char **didp, const char **namep);
int keyring_load_from_dump(keyring_file *k, unsigned entry_pinc, const char **entry_pinv, FILE *input);

View File

@ -226,18 +226,20 @@ static int app_keyring_list2(const struct cli_parsed *parsed, struct cli_context
DEFINE_CMD(app_keyring_add, 0,
"Create a new identity in the keyring protected by the supplied PIN (empty PIN if not given)",
"keyring","add" KEYRING_PIN_OPTIONS,"[<pin>]");
"keyring","add" KEYRING_PIN_OPTIONS,"[<pin>]","[<prefix>]");
static int app_keyring_add(const struct cli_parsed *parsed, struct cli_context *context)
{
DEBUG_cli_parsed(verbose, parsed);
const char *pin;
cli_arg(parsed, "pin", &pin, NULL, "");
const char *prefix;
cli_arg(parsed, "prefix", &prefix, NULL, "");
keyring_file *k = keyring_open_instance_cli(parsed);
if (!k)
return -1;
keyring_enter_pin(k, pin);
const keyring_identity *id = keyring_create_identity(k, pin);
const keyring_identity *id = keyring_create_identity(k, pin, prefix);
if (id == NULL) {
keyring_free(k);
return WHY("Could not create new identity");

View File

@ -211,7 +211,7 @@ static int restful_keyring_add(httpd_request *r, const char *remainder)
if (*remainder)
return 404;
const char *pin = http_request_get_query_param(&r->http, "pin");
const keyring_identity *id = keyring_create_identity(keyring, pin ? pin : "");
const keyring_identity *id = keyring_create_identity(keyring, pin ? pin : "", "");
if (id == NULL)
return http_request_keyring_response(r, 500, "Could not create identity");
if (keyring_commit(keyring) == -1)