Cryptographic- and hashing-related VCL functions

Last updated July 06, 2017

Fastly provides several functions in VCL for cryptographic- and hashing-related purposes. It is based very heavily on Kristian Lyngstøl's digest vmod for Varnish 3 (which means you can also refer to that documentation for more detail).

Functions

Returns an AWSv4 message authentication code based on the supplied secret_access_key and string_to_sign. This function automatically prepends "AWS4" in front of the secret access key (the first function parameter) as required by the protocol. This function does not support binary data for its secret_access_key or string_to_sign parameters. See the example.

A boolean function that returns true if the RSA digest using public_key of payload matches digest. The hash_method parameter selects the digest function to use. It can be sha256, sha384, sha512, or default (default is equivalent to sha256). The base64_method parameter is optional. It can be standard, url, url_nopad, or default (default is equivalent to url_nopad).

digest.secure_is_equal(STRING_LIST s1, STRING_LIST s2)

A boolean function that returns true if s1 and s2 are equal. The comparison is done in constant time to defend against timing attacks.

digest.time_hmac_md5(<base64 encoded key>, <interval>, <offset>)

Time based One Time Password using MD5. Returns base64 encoded output.

digest.time_hmac_sha1(<base64 encoded key>, <interval>, <offset>)

Time based One Time Password using SHA1. Returns base64 encoded output.

digest.time_hmac_sha256(<base64 encoded key>, <interval>, <offset>)

Time based One Time Password using SHA256. Returns base64 encoded output.

Notes

In base64 decoding, the output theoretically could be in binary but is interpreted as a string. So if the binary output contains '\0' then it could be truncated.

The time based One-Time Password algorithm initializes the HMAC using the key and appropriate hash type. Then it hashes the message

(<time now in seconds since UNIX epoch> / <interval>) + <offset>

as a 64bit unsigned integer (little endian) and base64 encodes the result.

Examples

One-Time Password Validation (Token Authentication)

Example implementations for token generation in various languages can be found in GitHub.

Example VCL

sub vcl_recv{/* make sure there is a token */if(req.url!~"[?&]token=([^&]+)"){error403;}if(re.group.1!=digest.time_hmac_sha256("RmFzdGx5IFRva2VuIFRlc3Q=",60,0)&&re.group.1!=digest.time_hmac_sha256("RmFzdGx5IFRva2VuIFRlc3Q=",60,-1)){error403;}#FASTLY recv...}

Signature

Base64 decoding

A snippet like this in vcl_error would set the response body to the value of the request header field named x-parrot after base64-decoding the value:

syntheticdigest.base64_decode(req.http.x-parrot);

However, if the base64-decoded string contains a NUL byte (0x00), then that byte and any bytes following it will not be included in the response. Keep that in mind if you intend to send a synthetic response that contains binary data. There is currently no way to send a synthetic response containing a NUL byte.