Commit 227378eb authored by Niels Möller's avatar Niels Möller
Browse files

* src/spki_commands.c (make_pkcs5_decrypt): Deleted function.

(do_spki_decrypt): Deleted function.
(spki_password_decrypt): Deleted class.
(make_spki_read_userkeys): Deleted function.
(spki_read_userkeys): Deleted expression.
(spki_return_userkeys): Deleted command.
(spki_add_userkey_command): Deleted command.
(do_spki_add_userkey): Deleted function.
(spki_read_userkey_context): Deleted class.

Rev: src/spki_commands.c:1.30
parent 03e8d037
......@@ -262,342 +262,3 @@ DEFINE_COMMAND(spki_read_hostkeys_command)
COMMAND_RETURN(c, res);
}
/* Reading of private user-keys
* ****************************/
/* GABA:
(class
(name spki_read_userkey_context)
(super command)
(vars
(keys struct object_queue)))
*/
static void
do_spki_add_userkey(struct command *s,
struct lsh_object *a,
struct command_continuation *c,
struct exception_handler *e UNUSED)
{
CAST(spki_read_userkey_context, self, s);
CAST(keypair, key, a);
trace("do_spki_add_userkey\n");
object_queue_add_tail(&self->keys, &key->super);
COMMAND_RETURN(c, s);
}
/* Ignores its argument */
DEFINE_COMMAND(spki_add_userkey_command)
(struct command *s UNUSED,
struct lsh_object *a UNUSED,
struct command_continuation *c,
struct exception_handler *e UNUSED)
{
NEW(spki_read_userkey_context, self);
trace("spki_add_userkey_command\n");
self->super.call = do_spki_add_userkey;
object_queue_init(&self->keys);
COMMAND_RETURN(c, self);
}
DEFINE_COMMAND(spki_return_userkeys)
(struct command *s UNUSED,
struct lsh_object *a,
struct command_continuation *c,
struct exception_handler *e UNUSED)
{
CAST(spki_read_userkey_context, self, a);
trace("spki_return_userkeys\n");
COMMAND_RETURN(c,queue_to_list(&self->keys));
}
/* GABA:
(expr
(name spki_read_userkeys)
(params
(algorithms object alist)
(decrypt object command))
(expr
(lambda (file)
(let ((ctx (spki_add_userkey file)))
(for_sexp (lambda (e)
;; Delay return until we actually get an exception
(return_userkeys (prog1 ctx e)))
(lambda (key)
(ctx (sexp2keypair
algorithms (decrypt key))))
file)))))
*/
struct command *
make_spki_read_userkeys(struct alist *algorithms,
struct alist *signature_algorithms,
struct interact *tty)
{
struct command *decrypt;
trace("make_spki_read_userkeys\n");
if (tty)
{
struct alist *mac = make_alist(0, -1);
struct alist *crypto = make_alist(0, -1);
alist_select_l(mac, algorithms,
2, ATOM_HMAC_SHA1, ATOM_HMAC_MD5, -1);
alist_select_l(crypto, algorithms,
3, ATOM_3DES_CBC, ATOM_BLOWFISH_CBC,
ATOM_RIJNDAEL_CBC_LOCAL, -1);
decrypt = make_pkcs5_decrypt(mac, crypto, tty);
}
else
decrypt = &command_I;
{
CAST_SUBTYPE(command, res,
spki_read_userkeys(signature_algorithms,
decrypt));
return res;
}
}
/* Encryption of private data.
* For PKCS#5 (version 2) key derivation, we use
*
* (password-encrypted LABEL
* (Xpkcs5v2 hmac-sha1 (salt #...#)
* (iterations #...#))
* ("3des-cbc" (iv #...#) (data #...#)))
*
* where the X:s will be removed when the format is more stable.
*
*/
/* GABA:
(class
(name spki_password_decrypt)
(super command)
(vars
(mac_algorithms object alist)
(crypto_algorithms object alist)
(tty object interact)))
*/
static void
do_spki_decrypt(struct command *s,
struct lsh_object *a,
struct command_continuation *c,
struct exception_handler *e)
{
CAST(spki_password_decrypt, self, s);
CAST_SUBTYPE(sexp, expr, a);
struct sexp_iterator *i;
if (!(i = sexp_check_type(expr, ATOM_PASSWORD_ENCRYPTED)))
COMMAND_RETURN(c, expr);
else
{
const struct lsh_string *label;
struct sexp *key_info;
struct sexp *payload;
struct crypto_algorithm *crypto;
struct mac_algorithm *mac;
const struct lsh_string *salt;
const struct lsh_string *iv;
const struct lsh_string *data;
UINT32 iterations;
if (SEXP_LEFT(i) != 3)
{
SPKI_ERROR(e, "Invalid (password-encrypted ...) expression.",
expr);
return;
}
/* NOTE: This is a place where it might make sense to use a sexp
* display type, but we don't support that for now. */
label = sexp2string(SEXP_GET(i));
if (!label)
{
SPKI_ERROR(e, "Invalid label in (password-encrypted ...) expression.",
expr);
return;
}
SEXP_NEXT(i);
key_info = SEXP_GET(i);
assert(key_info);
SEXP_NEXT(i);
payload = SEXP_GET(i);
assert(payload);
/* Examine the payload expression first, before asking for a
* pass phrase. */
{
int algorithm_name = spki_get_type(payload, &i);
CAST_SUBTYPE(crypto_algorithm, tmp,
ALIST_GET(self->crypto_algorithms, algorithm_name));
crypto = tmp;
}
if (!crypto)
{
SPKI_ERROR(e, "Unknown encryption algorithm for pkcs5v2.", payload);
return;
}
iv = sexp2string(sexp_assq(i, ATOM_IV));
if (crypto->iv_size)
{
if (!iv || (iv->length != crypto->iv_size))
{
SPKI_ERROR(e, "Invalid IV for pkcs5v2.", payload);
return;
}
}
else if (iv)
{
if (iv->length)
{
SPKI_ERROR(e, "Unexpected iv provided for pkcs5v2.", payload);
return;
}
iv = NULL;
}
data = sexp2string(sexp_assq(i, ATOM_DATA));
if (!data)
{
SPKI_ERROR(e, "Payload data missing for pkcs5v2.", payload);
return;
}
if (crypto->block_size && (data->length & crypto->block_size))
{
SPKI_ERROR(e, "Payload data doesn't match block size for pkcs5v2.", payload);
return;
}
/* Get key */
switch (spki_get_type(key_info, &i))
{
default:
SPKI_ERROR(e, "Unknown key derivation mechanism.", key_info);
return;
case ATOM_XPKCS5V2:
if (SEXP_LEFT(i) != 3)
{
SPKI_ERROR(e, "Invalid pkcs5v2 parameters.", key_info);
return;
}
{
int algorithm_name = sexp2atom(SEXP_GET(i));
CAST_SUBTYPE(mac_algorithm, tmp,
ALIST_GET(self->mac_algorithms,
algorithm_name));
mac = tmp;
}
if (!mac)
{
SPKI_ERROR(e, "Unknown mac for pkcs5v2.", key_info);
return;
}
SEXP_NEXT(i);
if (!sexp2uint32(sexp_assq(i, ATOM_ITERATIONS), &iterations)
|| !iterations)
{
SPKI_ERROR(e, "Invalid iteration count for pkcs5v2.", key_info);
return;
}
salt = sexp2string(sexp_assq(i, ATOM_SALT));
if (!salt)
{
SPKI_ERROR(e, "Invalid salt for pkcs5v2.", key_info);
return;
}
/* Do the work */
{
struct lsh_string *password
= INTERACT_READ_PASSWORD(self->tty, 500, label, 0);
struct lsh_string *clear;
struct sexp *res;
UINT8 *key;
if (!password)
{
SPKI_ERROR(e, "No password provided for pkcs5v2.", key_info);
return;
}
key = alloca(crypto->key_size);
pkcs5_derive_key(mac,
password->length, password->data,
salt->length, salt->data,
iterations,
crypto->key_size, key);
lsh_string_free(password);
clear = crypt_string_unpad(MAKE_DECRYPT(crypto,
key,
iv ? iv->data : NULL),
data, 0);
if (!clear)
{
SPKI_ERROR(e, "Bad password for pkcs5v2.", key_info);
return;
}
res = string_to_sexp(SEXP_CANONICAL, clear, 1);
if (res)
COMMAND_RETURN(c, res);
else
{
SPKI_ERROR(e, "Bad password for pkcs5v2.", key_info);
return;
}
}
}
}
}
struct command *
make_pkcs5_decrypt(struct alist *mac_algorithms,
struct alist *crypto_algorithms,
struct interact *tty)
{
NEW(spki_password_decrypt, self);
self->super.call = do_spki_decrypt;
self->mac_algorithms = mac_algorithms;
self->crypto_algorithms = crypto_algorithms;
self->tty = tty;
return &self->super;
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment