Commit 2cc4dc7e authored by Geoff Simmons's avatar Geoff Simmons

Add update_key().

parent e319b598
......@@ -464,6 +464,36 @@ KEY_Set(VRT_CTX, uint8_t *id, uint8_t idlen, const uint8_t *key)
return (0);
}
int
KEY_Update(VRT_CTX, uint8_t *id, uint8_t idlen, const uint8_t *key)
{
struct key_tree *tree_h;
struct key *k;
CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
AN(id);
AN(key);
key_wrlock(idlen);
tree_h = &key_tbl[idlen].tree;
k = key_find(tree_h, id, idlen);
if (k == NULL) {
KEY_Unlock(idlen);
VRT_fail(ctx, "key \"%.*s\" does not exist", idlen, id);
return (-1);
}
CHECK_OBJ(k, KEY_MAGIC);
AN(k->key);
memcpy(k->key, key, AES128_KEYLEN);
KEY_Unlock(idlen);
AN(k->id);
assert(k->idlen == idlen);
AZ(memcmp(k->id, id, idlen));
return (0);
}
int
KEY_Delete(VRT_CTX, uint8_t *id, uint8_t idlen)
{
......
......@@ -38,6 +38,7 @@ void KEY_Rdlock(uint8_t idlen);
void KEY_Unlock(uint8_t idlen);
uint8_t *KEY_Get(uint8_t *id, uint8_t idlen);
int KEY_Add(VRT_CTX, uint8_t *id, uint8_t idlen, const uint8_t *key);
int KEY_Update(VRT_CTX, uint8_t *id, uint8_t idlen, const uint8_t *key);
int KEY_Set(VRT_CTX, uint8_t *id, uint8_t idlen, const uint8_t *key);
void KEY_Wipe(void * const key);
int KEY_Delete(VRT_CTX, uint8_t *id, uint8_t idlen);
......
......@@ -110,6 +110,55 @@ client c1 {
logexpect l1 -wait
server s1 -wait
server s1 -start
varnish v1 -vcl+backend {
import ${vmod_ece};
import blob;
sub vcl_init {
# This key will fail the decrypt.
ece.set_key("", blob.decode(BASE64,
encoded="X9yH1URj1a6C7qp1OqjMjQ=="));
}
sub vcl_recv {
if (req.url == "/update") {
ece.update_key("foo", blob.decode(BASE64,
encoded="oAAt/UDfkbY8F26rypiFtQ=="));
}
}
sub vcl_backend_response {
# This is the right key for the decryption.
ece.update_key("", blob.decode(BASE64URLNOPAD,
encoded="yqdlZ-tYemfogSmv7Ws5PQ"));
set beresp.filters = "ece_decrypt";
}
}
logexpect l1 -v v1 -d 0 -g vxid -q "VCL_Error" {
expect 0 * Begin req
expect * = VCL_Error {^key "foo" does not exist$}
expect * = End
} -start
client c1 {
txreq
rxresp
expect resp.status == 200
expect resp.bodylen == 15
expect resp.body == "I am the walrus"
txreq -url /update
rxresp
expect resp.status == 503
expect resp.reason == "VCL failed"
} -run
logexpect l1 -wait
varnish v1 -vcl {
import ${vmod_ece};
import blob;
......@@ -183,6 +232,28 @@ varnish v1 -vcl {
1234567890123456789012345678901234567890123456789012345678901234567890
1234567890123456789012345678901234567890123456789012345678901234567890
1234567890123456789012345678901234567890123456789012345678901234567890
"},
blob.decode(BASE64,
encoded="75cIt3LwTqbq66pKSmp2fA=="));
}
elsif (req.url == "/update/nullblob") {
ece.update_key("key", blob.decode(HEX,
encoded="bad blob"));
}
elsif (req.url == "/update/nullid") {
ece.update_key(req.http.No-Such-Header, blob.decode(HEX,
encoded="f00"));
}
elsif (req.url == "/update/shortkey") {
ece.update_key("key", blob.decode(HEX,
encoded="f00"));
}
elsif (req.url == "/update/toolong") {
ece.update_key({"
1234567890123456789012345678901234567890123456789012345678901234567890
1234567890123456789012345678901234567890123456789012345678901234567890
1234567890123456789012345678901234567890123456789012345678901234567890
1234567890123456789012345678901234567890123456789012345678901234567890
"},
blob.decode(BASE64,
encoded="75cIt3LwTqbq66pKSmp2fA=="));
......@@ -242,6 +313,22 @@ logexpect l1 -v v1 -d 0 -g vxid -q "VCL_Error" {
expect 0 * Begin req
expect * = VCL_Error {(?s)^key id .+ too long \(length \d+ > 255\)$}
expect * = End
expect 0 * Begin req
expect * = VCL_Error {^vmod blob error}
expect * = End
expect 0 * Begin req
expect * = VCL_Error {^key id is NULL$}
expect * = End
expect 0 * Begin req
expect * = VCL_Error {^illegal key length \d+ \(must be 16\)$}
expect * = End
expect 0 * Begin req
expect * = VCL_Error {(?s)^key id .+ too long \(length \d+ > 255\)$}
expect * = End
} -start
client c1 {
......@@ -335,4 +422,32 @@ client c1 {
expect resp.reason == "VCL failed"
} -run
client c1 {
txreq -url /update/nullblob
rxresp
expect resp.status == 503
expect resp.reason == "VCL failed"
} -run
client c1 {
txreq -url /update/nullid
rxresp
expect resp.status == 503
expect resp.reason == "VCL failed"
} -run
client c1 {
txreq -url /update/shortkey
rxresp
expect resp.status == 503
expect resp.reason == "VCL failed"
} -run
client c1 {
txreq -url /update/toolong
rxresp
expect resp.status == 503
expect resp.reason == "VCL failed"
} -run
logexpect l1 -wait
......@@ -115,6 +115,20 @@ vmod_add_key(VRT_CTX, VCL_STRING id, VCL_BLOB key)
(void)KEY_Add(ctx, (uint8_t *)id, (uint8_t)len, key->blob);
}
VCL_VOID
vmod_update_key(VRT_CTX, VCL_STRING id, VCL_BLOB key)
{
size_t len;
CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
CHECK_ID(ctx, id, len,);
CHECK_KEY(ctx, key);
/* KEY_Update calls VRT_fail() on error. */
(void)KEY_Update(ctx, (uint8_t *)id, (uint8_t)len, key->blob);
}
VCL_VOID
vmod_set_key(VRT_CTX, VCL_STRING id, VCL_BLOB key)
{
......
......@@ -63,10 +63,18 @@ blob ``key``, provided that ``id`` does not already exist.
XXX ...
$Function VOID update_key(STRING id, BLOB key)
Change the keying material identified by ``id`` to the contents of the
blob ``key``, provided that ``id`` already exists.
XXX ...
$Function VOID set_key(STRING id, BLOB key)
Set the keying material identified by ``id`` to the contents of the
blob ``key``.
blob ``key``. This is the "add-or-update" operation; key ``id`` is
added if it does not already exist, and modified if it already exists.
XXX ...
......
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