Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
L
libvmod-gcrypt
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
uplex-varnish
libvmod-gcrypt
Commits
37232bcf
Commit
37232bcf
authored
May 04, 2017
by
Geoff Simmons
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add the random() function.
parent
3f6619c9
Pipeline
#190
skipped
Changes
6
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
473 additions
and
32 deletions
+473
-32
README.rst
README.rst
+126
-16
very_strong_random.vtc
src/tests.disabled/very_strong_random.vtc
+36
-0
aes.vtc
src/tests/aes.vtc
+54
-0
random.vtc
src/tests/random.vtc
+72
-0
vmod_gcrypt.c
src/vmod_gcrypt.c
+66
-0
vmod_gcrypt.vcc
src/vmod_gcrypt.vcc
+119
-16
No files found.
README.rst
View file @
37232bcf
...
...
@@ -35,6 +35,9 @@ import gcrypt [from "path"] ;
<OBJ>.encrypt(BLOB plaintext [, BLOB iv] [, BLOB ctr])
<OBJ>.decrypt(BLOB plaintext [, BLOB iv] [, BLOB ctr])
BLOB gcrypt.random([ENUM {STRONG, VERY_STRONG, NONCE} quality]
[, BYTES n])
gcrypt.version()
gcrypt.gcrypt_version()
...
...
@@ -44,8 +47,12 @@ DESCRIPTION
This Varnish Module (VMOD) provides access to the libgcrypt library of
cryptographic building blocks -- the same library used by the GNU
Privacy Guard cryptographic suite (GnuPG or GPG). The VMOD currently
only supports symmetric encryption with AES, and with the standard
modes of operation.
supports:
* symmetric encryption with AES, and with the standard modes of
operation
* generation of pseudo-random data
The VMOD uses the VCL data type BLOB for data that enter into
encryption operations -- plaintext, ciphertext, initialization vectors
...
...
@@ -78,24 +85,32 @@ This is a simple usage example::
# into production VCL!
new k = blobcode.blob(HEX, "000102030405060708090a0b0c0d0e0f");
# Create an object for AES-128 in CTR mode with PKCS#7 padding,
# using the key just created, and with libgcrypt internal
# structures in secure memory.
new aes = gcrypt.symmetric(AES, CTR, PKCS7, key=k.get(),
secure=true);
# Create an object for AES-128 in CTR mode using the key just
# created, and with libgcrypt internal structures in secure memory.
new aes = gcrypt.symmetric(AES, CTR, key=k.get(), secure=true);
}
# Assume that a ciphertext to be decrypted is in the request
# header X-Msg, and the counter vector is in X-CTR, both
# hex-encoded.
# Assume that a plaintext to be encrypted is in the response
# header X-Msg. Assign the hex-encoded encrypted message to the
# response header X-Cipher, and the hex-encoded counter vector to
# the response header X-Ctr; and remove X-Msg from the response.
sub vcl_recv {
# Use the blobcode VMOD to decode the two headers, and to
# encode the decrypted plaintext in hex with lower-case
# digits, to be assigned to the request header X-Plain.
set req.http.X-Plain
# Use the blobcode VMOD to decode to convert the contents of
# X-Msg to a BLOB, and to encode the encrypted ciphertext in
# hex with lower-case digits. Use the random() function to
# generate a counter vector as a 128 bit nonce.
set resp.http.X-Cipher
= blobcode.encode(HEXLC,
aes.decrypt(blobcode.decode(HEX, req.http.X-Msg),
ctr=blobcode.decode(HEX, req.http.X-CTR)));
aes.encrypt(blobcode.decode(encoded=req.http.X-Msg),
ctr=gcrypt.random(NONCE, 16B)));
# Use the no-argument version of random() to retrieve the
# counter vector that was just generated, and use the
# blobcode VMOD to encode it as lower-case hex.
set resp.http.X-CTR = blobcode.encode(HEXLC, gcrypt.random());
# Remove the plaintext from the response header.
unset resp.http.X-Msg;
}
libgcrypt secure memory
...
...
@@ -152,6 +167,7 @@ CONTENTS
* VOID init(ENUM {INIT_SECMEM,DISABLE_SECMEM,FINISH}, BYTES)
* symmetric(ENUM {AES,AES128,RIJNDAEL,RIJNDAEL128,AES192,RIJNDAEL192,AES256,RIJNDAEL256}, ENUM {ECB,CFB,CBC,OFB,CTR}, ENUM {PKCS7,ISO7816,X923,NONE}, BLOB, BOOL, BOOL)
* BLOB random(PRIV_TASK, ENUM {STRONG,VERY_STRONG,NONCE}, BYTES)
* STRING version()
* STRING gcrypt_version()
...
...
@@ -478,6 +494,100 @@ Examples::
iv=blobcode.decode(BASE64, req.http.X-IV-256)));
}
.. _func_random:
random
------
::
BLOB random(PRIV_TASK, ENUM {STRONG,VERY_STRONG,NONCE} quality=0, BYTES n=0)
Return a BLOB containing ``n`` bytes of pseudo-random data. The
cryptographic strength of random number generation is determined by
the ``quality`` ENUM:
* ``NONCE`` (for "number used once"): Pseudo-random bytes for
applications where cryptographic security is not required. This
level is suitable, for example, for generation of initialization or
counter vectors when used with modes of operation that require
uniqueness, but do not have strong requirements for unpredictabilty.
* ``STRONG``: From the libgcrypt manual: "Use this level for session
keys and similar purposes". Most applications requiring
cryptographically secure pseudo-random data should use this level.
* ``VERY_STRONG``: From the libgcrypt manual: "Use this level for long
term key material".
*NOTE: At the VERY_STRONG level, the random() function may take
several minutes to execute.* This level should *not* be used when
performance is important; ``STRONG`` is sufficient for crypto-quality
randomness. If at all, ``VERY_STRONG`` might be used in a service that
occasionally generates new keys, on the understanding that this will
take quite some time (and it may be necessary to set long timeouts).
Consider using the ``NONCE`` level for applications that do not
require strong randomness. With ``NONCE``, performance is better,
nothing can be revealed about the internal state of the strong random
number generator, and entropy mixed into the strong generator is not
consumed.
If ``n`` is 0B, then ``random()`` returns the same BLOB that was
returned by its most recent invocation in the same client or backend
context. Since 0B is the default value of ``n``, it can be left out
for this purpose, and the ``quality`` ENUM can be left out as well. In
other words, calling ``random()`` with no arguments returns the same
BLOB that was returned with arguments in the same client or backend
scope.
This makes it possible, for example, to use ``random()`` with
appropriate arguments to generate an initialization or counter vector
in an encryption operation, and then call ``random()`` again with no
arguments to assign the same value to a header to be sent along with
the encrypted message, as illustrated below.
The ``random()`` function fails if:
* ``n`` is 0B, but ``random()`` was not previously called with ``n`` >
0B in the same client or backend context.
* ``n`` is greater than 0B, but the ``quality`` ENUM is not set.
* There is insufficient workspace for the BLOB to be returned.
If ``random()`` fails in ``vcl_init``, then the VCL load fails with an
error message. If it fails in any other subroutine, then it returns
NULL, and an error message is written to the log with the
``VCL_Error`` tag.
Example::
# Assume the aes192 object shown in the examples above: AES-192
# encryption with CBC mode.
# Encrypt the contents of the X-Msg response header, using the
# random() function to generate an initialization vector, which
# is sent in the reponse header X-IV.
sub vcl_resp {
# The length of the IV MUST match the block size of the
# cipher in use -- 64 bits (8 bytes) for AES. For CBC, the IV
# MUST be unpredictable, so we use quality level STRONG.
set resp.http.X-Encrypted
= blobcode.encode(BASE64,
aes192.encrypt(blobcode.decode(encoded=resp.http.X-Msg),
iv=gcrypt.random(STRONG, 8B)));
# Now call random() with no arguments to retrive the IV that
# was generated, to be sent in the base64-encoded response
# header X-IV.
set resp.http.X-IV = blobcode.encode(BASE64, gcrypt.random());
# Remove the plaintext from the response header.
unset resp.http.X-Msg;
}
.. _func_version:
version
...
...
src/tests.disabled/very_strong_random.vtc
0 → 100644
View file @
37232bcf
# looks like -*- vcl -*-
varnishtest "random() at quality level VERY_STRONG"
# This test can take several minutes to run!
# The default timeout for varnishtest is very likely to be too short
# for this test, resulting in the test aborting and failing. For best
# results, use the -t parameter to set a longer timeout, for example:
# varnishtest -t 300
varnish v1 -vcl {
import blobcode;
import gcrypt from "${vmod_topbuild}/src/.libs/libvmod_gcrypt.so";
backend b { .host = "${bad_ip}"; }
sub vcl_recv {
return(synth(200));
}
sub vcl_synth {
set resp.http.very_strong
= blobcode.encode(HEXUC, gcrypt.random(VERY_STRONG, 16B));
set resp.http.very_strong_task
= blobcode.encode(HEXUC, gcrypt.random());
return(deliver);
}
} -start
client c1 {
txreq
rxresp
expect resp.status == 200
expect resp.http.very_strong ~ "^[[:xdigit:]]{32}$"
expect resp.http.very_strong_task == resp.http.very_strong
} -run
src/tests/aes.vtc
View file @
37232bcf
...
...
@@ -793,3 +793,57 @@ client c1 {
expect resp.http.c_j == "c58c18a02297685e11148e51cbde72e644262e6bc875a3270f207f9e3936c1dd"
expect resp.http.p_j == {{"encrypt" : "foo"}}
} -run
# Use random() to create an IV and a counter.
varnish v1 -vcl {
import blobcode;
import gcrypt from "${vmod_topbuild}/src/.libs/libvmod_gcrypt.so";
backend b { .host = "${bad_ip}"; }
sub vcl_init {
new k1 = blobcode.blob(HEX, "000102030405060708090a0b0c0d0e0f");
new ctr = gcrypt.symmetric(AES, CTR, key=k1.get());
new cbc = gcrypt.symmetric(AES, CBC, key=k1.get(), cbc_cts=true);
new p1 = blobcode.blob(HEX, "000102030405060708090a0b0c0d0e0f");
}
sub vcl_recv {
return(synth(200));
}
sub vcl_synth {
set resp.http.ctr-ciphertext
= blobcode.encode(HEXLC,
ctr.encrypt(p1.get(),
ctr=gcrypt.random(NONCE, 16B)));
set resp.http.ctr-ctr
= blobcode.encode(HEXLC, gcrypt.random());
set resp.http.ctr-plaintext
= blobcode.encode(HEXLC,
ctr.decrypt(blobcode.decode(HEX, resp.http.ctr-ciphertext),
ctr=blobcode.decode(HEX, resp.http.ctr-ctr)));
set resp.http.cbc-ciphertext
= blobcode.encode(HEXLC,
cbc.encrypt(p1.get(),
iv=gcrypt.random(STRONG, 8B)));
set resp.http.cbc-iv
= blobcode.encode(HEXLC, gcrypt.random());
set resp.http.cbc-plaintext
= blobcode.encode(HEXLC,
cbc.decrypt(blobcode.decode(HEX, resp.http.cbc-ciphertext),
iv=blobcode.decode(HEX, resp.http.cbc-iv)));
return(deliver);
}
}
client c1 {
txreq
rxresp
expect resp.status == 200
expect resp.http.ctr-ciphertext ~ "^[[:xdigit:]]{32}$"
expect resp.http.ctr-ctr ~ "^[[:xdigit:]]{32}$"
expect resp.http.ctr-plaintext == "000102030405060708090a0b0c0d0e0f"
expect resp.http.cbc-ciphertext ~ "^[[:xdigit:]]{32}$"
expect resp.http.cbc-iv ~ "^[[:xdigit:]]{16}$"
expect resp.http.cbc-plaintext == "000102030405060708090a0b0c0d0e0f"
} -run
src/tests/random.vtc
0 → 100644
View file @
37232bcf
# looks like -*- vcl -*-
varnishtest "random()"
# Quality level VERY_STRONG is not tested here, because random() can
# take several minutes to run at that level. See
# src/tests.disabled/very_strong_random.vtc for a test of VERY_STRONG,
# which almost certainly requires a long timeout parameter for
# varnishtest.
varnish v1 -vcl {
import blobcode;
import gcrypt from "${vmod_topbuild}/src/.libs/libvmod_gcrypt.so";
backend b { .host = "${bad_ip}"; }
sub vcl_recv {
return(synth(200));
}
sub vcl_synth {
set resp.http.nonce16
= blobcode.encode(HEXUC, gcrypt.random(NONCE, 16B));
set resp.http.nonce16-task
= blobcode.encode(HEXUC, gcrypt.random());
set resp.http.strong32
= blobcode.encode(HEXUC, gcrypt.random(STRONG, 32B));
set resp.http.strong32-task-noarg
= blobcode.encode(HEXUC, gcrypt.random());
set resp.http.strong32-task-n0
= blobcode.encode(HEXUC, gcrypt.random(n=0B));
set resp.http.strong32-task-enum
= blobcode.encode(HEXUC, gcrypt.random(VERY_STRONG));
set resp.http.strong32-task-n0-enum
= blobcode.encode(HEXUC, gcrypt.random(NONCE, n=0B));
set resp.http.error
= blobcode.encode(HEXUC, gcrypt.random(n=1B));
return(deliver);
}
} -start
client c1 {
txreq
rxresp
expect resp.status == 200
expect resp.http.nonce16 ~ "^[[:xdigit:]]{32}$"
expect resp.http.nonce16-task == resp.http.nonce16
expect resp.http.strong32 ~ "^[[:xdigit:]]{64}$"
expect resp.http.strong32-task-noarg == resp.http.strong32
expect resp.http.strong32-task-n0 == resp.http.strong32
expect resp.http.strong32-task-enum == resp.http.strong32
expect resp.http.strong32-task-n0-enum == resp.http.strong32
expect resp.http.error == ""
} -run
logexpect l1 -v v1 -d 1 -q "VCL_Error" {
expect 0 * Begin req
expect * = VCL_Error "^vmod gcrypt error: in gcrypt.random..: quality ENUM is NULL"
expect * = End
} -run
varnish v1 -errvcl {vmod gcrypt error: in gcrypt.random(): quality ENUM is NULL} {
import blobcode;
import gcrypt from "${vmod_topbuild}/src/.libs/libvmod_gcrypt.so";
backend b { .host = "${bad_ip}"; }
sub vcl_init {
gcrypt.init(FINISH);
new aes = gcrypt.symmetric(AES, ECB, NONE,
key=gcrypt.random(n=16B));
}
}
src/vmod_gcrypt.c
View file @
37232bcf
...
...
@@ -54,6 +54,9 @@
#define VERR(ctx, fmt, ...) \
errmsg((ctx), "vmod gcrypt error: " fmt, __VA_ARGS__)
#define ERRNOMEM(ctx, msg) \
ERR((ctx), msg ", out of space")
#define VERRNOMEM(ctx, fmt, ...) \
VERR((ctx), fmt ", out of space", __VA_ARGS__)
...
...
@@ -529,6 +532,69 @@ vmod_symmetric_decrypt(VRT_CTX, struct vmod_gcrypt_symmetric *symmetric,
return
plaintext
;
}
/* Function random */
VCL_BLOB
vmod_random
(
VRT_CTX
,
struct
vmod_priv
*
rnd_task
,
VCL_ENUM
qualitys
,
VCL_BYTES
n
)
{
struct
vmod_priv
*
rnd_blob
;
uintptr_t
snap
;
CHECK_OBJ_NOTNULL
(
ctx
,
VRT_CTX_MAGIC
);
AN
(
rnd_task
);
assert
(
n
>=
0
);
if
(
n
==
0
)
{
if
(
rnd_task
->
priv
==
NULL
)
{
ERR
(
ctx
,
"in gcrypt.random(): No random BLOB was "
"created previously in this task scope"
);
return
NULL
;
}
assert
(
rnd_task
->
len
==
sizeof
(
*
rnd_blob
));
assert
(((
VCL_BLOB
)
rnd_task
->
priv
)
->
len
>
0
);
return
(
VCL_BLOB
)
rnd_task
->
priv
;
}
if
(
qualitys
==
NULL
)
{
ERR
(
ctx
,
"in gcrypt.random(): quality ENUM is NULL"
);
return
NULL
;
}
snap
=
WS_Snapshot
(
ctx
->
ws
);
if
((
rnd_blob
=
WS_Alloc
(
ctx
->
ws
,
sizeof
(
*
rnd_blob
)))
==
NULL
)
{
ERRNOMEM
(
ctx
,
"in gcrypt.random(), allocating space for return "
"BLOB"
);
return
NULL
;
}
if
((
rnd_blob
->
priv
=
WS_Alloc
(
ctx
->
ws
,
n
))
==
NULL
)
{
WS_Reset
(
ctx
->
ws
,
snap
);
VERRNOMEM
(
ctx
,
"in gcrypt.random(), allocating space for %d "
"random bytes"
,
n
);
return
NULL
;
}
switch
(
qualitys
[
0
])
{
case
'N'
:
AZ
(
strcmp
(
qualitys
+
1
,
"ONCE"
));
gcry_create_nonce
(
rnd_blob
->
priv
,
n
);
break
;
case
'S'
:
AZ
(
strcmp
(
qualitys
+
1
,
"TRONG"
));
gcry_randomize
(
rnd_blob
->
priv
,
n
,
GCRY_STRONG_RANDOM
);
break
;
case
'V'
:
AZ
(
strcmp
(
qualitys
+
1
,
"ERY_STRONG"
));
gcry_randomize
(
rnd_blob
->
priv
,
n
,
GCRY_VERY_STRONG_RANDOM
);
break
;
default:
WRONG
(
"Illegal quality enum"
);
}
rnd_blob
->
len
=
n
;
rnd_blob
->
free
=
NULL
;
rnd_task
->
priv
=
rnd_blob
;
rnd_task
->
len
=
sizeof
(
*
rnd_blob
);
rnd_task
->
free
=
NULL
;
return
rnd_blob
;
}
VCL_STRING
vmod_version
(
VRT_CTX
__attribute__
((
unused
)))
{
...
...
src/vmod_gcrypt.vcc
View file @
37232bcf
...
...
@@ -18,6 +18,9 @@ $Module gcrypt 3 access the libgcrypt cryptographic library
<OBJ>.encrypt(BLOB plaintext [, BLOB iv] [, BLOB ctr])
<OBJ>.decrypt(BLOB plaintext [, BLOB iv] [, BLOB ctr])
BLOB gcrypt.random([ENUM {STRONG, VERY_STRONG, NONCE} quality]
[, BYTES n])
gcrypt.version()
gcrypt.gcrypt_version()
...
...
@@ -27,8 +30,12 @@ DESCRIPTION
This Varnish Module (VMOD) provides access to the libgcrypt library of
cryptographic building blocks -- the same library used by the GNU
Privacy Guard cryptographic suite (GnuPG or GPG). The VMOD currently
only supports symmetric encryption with AES, and with the standard
modes of operation.
supports:
* symmetric encryption with AES, and with the standard modes of
operation
* generation of pseudo-random data
The VMOD uses the VCL data type BLOB for data that enter into
encryption operations -- plaintext, ciphertext, initialization vectors
...
...
@@ -61,24 +68,32 @@ This is a simple usage example::
# into production VCL!
new k = blobcode.blob(HEX, "000102030405060708090a0b0c0d0e0f");
# Create an object for AES-128 in CTR mode with PKCS#7 padding,
# using the key just created, and with libgcrypt internal
# structures in secure memory.
new aes = gcrypt.symmetric(AES, CTR, PKCS7, key=k.get(),
secure=true);
# Create an object for AES-128 in CTR mode using the key just
# created, and with libgcrypt internal structures in secure memory.
new aes = gcrypt.symmetric(AES, CTR, key=k.get(), secure=true);
}
# Assume that a ciphertext to be decrypted is in the request
# header X-Msg, and the counter vector is in X-CTR, both
# hex-encoded.
# Assume that a plaintext to be encrypted is in the response
# header X-Msg. Assign the hex-encoded encrypted message to the
# response header X-Cipher, and the hex-encoded counter vector to
# the response header X-Ctr; and remove X-Msg from the response.
sub vcl_recv {
# Use the blobcode VMOD to decode the two headers, and to
# encode the decrypted plaintext in hex with lower-case
# digits, to be assigned to the request header X-Plain.
set req.http.X-Plain
# Use the blobcode VMOD to decode to convert the contents of
# X-Msg to a BLOB, and to encode the encrypted ciphertext in
# hex with lower-case digits. Use the random() function to
# generate a counter vector as a 128 bit nonce.
set resp.http.X-Cipher
= blobcode.encode(HEXLC,
aes.decrypt(blobcode.decode(HEX, req.http.X-Msg),
ctr=blobcode.decode(HEX, req.http.X-CTR)));
aes.encrypt(blobcode.decode(encoded=req.http.X-Msg),
ctr=gcrypt.random(NONCE, 16B)));
# Use the no-argument version of random() to retrieve the
# counter vector that was just generated, and use the
# blobcode VMOD to encode it as lower-case hex.
set resp.http.X-CTR = blobcode.encode(HEXLC, gcrypt.random());
# Remove the plaintext from the response header.
unset resp.http.X-Msg;
}
libgcrypt secure memory
...
...
@@ -428,6 +443,94 @@ Examples::
iv=blobcode.decode(BASE64, req.http.X-IV-256)));
}
$Function BLOB random(PRIV_TASK, ENUM {STRONG, VERY_STRONG, NONCE} quality=0,
BYTES n=0)
Return a BLOB containing ``n`` bytes of pseudo-random data. The
cryptographic strength of random number generation is determined by
the ``quality`` ENUM:
* ``NONCE`` (for "number used once"): Pseudo-random bytes for
applications where cryptographic security is not required. This
level is suitable, for example, for generation of initialization or
counter vectors when used with modes of operation that require
uniqueness, but do not have strong requirements for unpredictabilty.
* ``STRONG``: From the libgcrypt manual: "Use this level for session
keys and similar purposes". Most applications requiring
cryptographically secure pseudo-random data should use this level.
* ``VERY_STRONG``: From the libgcrypt manual: "Use this level for long
term key material".
*NOTE: At the VERY_STRONG level, the random() function may take
several minutes to execute.* This level should *not* be used when
performance is important; ``STRONG`` is sufficient for crypto-quality
randomness. If at all, ``VERY_STRONG`` might be used in a service that
occasionally generates new keys, on the understanding that this will
take quite some time (and it may be necessary to set long timeouts).
Consider using the ``NONCE`` level for applications that do not
require strong randomness. With ``NONCE``, performance is better,
nothing can be revealed about the internal state of the strong random
number generator, and entropy mixed into the strong generator is not
consumed.
If ``n`` is 0B, then ``random()`` returns the same BLOB that was
returned by its most recent invocation in the same client or backend
context. Since 0B is the default value of ``n``, it can be left out
for this purpose, and the ``quality`` ENUM can be left out as well. In
other words, calling ``random()`` with no arguments returns the same
BLOB that was returned with arguments in the same client or backend
scope.
This makes it possible, for example, to use ``random()`` with
appropriate arguments to generate an initialization or counter vector
in an encryption operation, and then call ``random()`` again with no
arguments to assign the same value to a header to be sent along with
the encrypted message, as illustrated below.
The ``random()`` function fails if:
* ``n`` is 0B, but ``random()`` was not previously called with ``n`` >
0B in the same client or backend context.
* ``n`` is greater than 0B, but the ``quality`` ENUM is not set.
* There is insufficient workspace for the BLOB to be returned.
If ``random()`` fails in ``vcl_init``, then the VCL load fails with an
error message. If it fails in any other subroutine, then it returns
NULL, and an error message is written to the log with the
``VCL_Error`` tag.
Example::
# Assume the aes192 object shown in the examples above: AES-192
# encryption with CBC mode.
# Encrypt the contents of the X-Msg response header, using the
# random() function to generate an initialization vector, which
# is sent in the reponse header X-IV.
sub vcl_resp {
# The length of the IV MUST match the block size of the
# cipher in use -- 64 bits (8 bytes) for AES. For CBC, the IV
# MUST be unpredictable, so we use quality level STRONG.
set resp.http.X-Encrypted
= blobcode.encode(BASE64,
aes192.encrypt(blobcode.decode(encoded=resp.http.X-Msg),
iv=gcrypt.random(STRONG, 8B)));
# Now call random() with no arguments to retrive the IV that
# was generated, to be sent in the base64-encoded response
# header X-IV.
set resp.http.X-IV = blobcode.encode(BASE64, gcrypt.random());
# Remove the plaintext from the response header.
unset resp.http.X-Msg;
}
$Function STRING version()
Returns the version string for this VMOD.
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment