use_backend auth_bearer_be if { path /auth_bearer }
default_backend dflt_be
+ # Frontend used only to check binary HMAC secrets containing '\0' characters
+ frontend bin_hmac_fe
+ bind "fd@${binhmacfe}"
+ http-request set-var(txn.key) str(YQBiY2RlZg==),b64dec
+ http-request set-var(txn.ikey) int(12345)
+ http-request return status 200 hdr x-res "%[req.hdr(x-tok),jwt_verify(HS256,txn.key)]" hdr x-int "%[req.hdr(x-tok),jwt_verify(HS256,txn.ikey)]"
+
crt-store named_store
load crt "${testdir}/cert.rsa.pem" jwt on
expect resp.http.x-jwt-verify == "-3"
} -run
+# Check binary HMAC secrets
+client c30 -connect ${h1_binhmacfe_sock} {
+ # signed with the full secret "a\0bcdef"
+ txreq -hdr "x-tok: eyJhbGciOiAiSFMyNTYiLCAidHlwIjogIkpXVCJ9.eyJzdWIiOiJ4In0.x8ao0qtdSK7Gp8GOzciqyucdsYIupoT46NutNBuvnsk"
+ rxresp
+ expect resp.status == 200
+ expect resp.http.x-res == "1"
+
+ # signed with the truncated secret "a"
+ txreq -hdr "x-tok: eyJhbGciOiAiSFMyNTYiLCAidHlwIjogIkpXVCJ9.eyJzdWIiOiJ4In0.rtjwa3Fd19oC-izY5CrSva-VlzmxyLsYDVy0gtkWqkQ"
+ rxresp
+ expect resp.status == 200
+ expect resp.http.x-res == "0"
+
+ # signed with "12345", the integer variable's string form
+ txreq -hdr "x-tok: eyJhbGciOiAiSFMyNTYiLCAidHlwIjogIkpXVCJ9.eyJzdWIiOiJ4In0.uigQcqlOQfXIx6y3FZoQiyA_vnvq6jCU0DKT33UXW1Q"
+ rxresp
+ expect resp.status == 200
+ expect resp.http.x-int == "1"
+} -run
if (chunk_printf(alg, "%.*s", (int)b_data(&alg_smp.data.u.str), b_orig(&alg_smp.data.u.str)) <= 0)
goto end;
+ /* The key may be a binary HMAC secret, which must be retrieved and
+ * copied as-is since both a cast to string and printf() would stop at
+ * the first NUL byte. Variables of other types are still converted to
+ * strings. The key may also be a public key path, hence the trailing
+ * zero.
+ */
smp_set_owner(&key_smp, smp->px, smp->sess, smp->strm, smp->opt);
- if (!sample_conv_var2smp_str(&args[1], &key_smp))
+ if (args[1].type == ARGT_VAR) {
+ if (!vars_get_by_desc(&args[1].data.var, &key_smp, NULL))
+ goto end;
+ if (key_smp.data.type != SMP_T_BIN &&
+ (!sample_casts[key_smp.data.type][SMP_T_STR] ||
+ !sample_casts[key_smp.data.type][SMP_T_STR](&key_smp)))
+ goto end;
+ }
+ else if (!sample_conv_var2smp_str(&args[1], &key_smp))
goto end;
- if (chunk_printf(key, "%.*s", (int)b_data(&key_smp.data.u.str), b_orig(&key_smp.data.u.str)) <= 0)
+ if (!b_data(&key_smp.data.u.str) || b_data(&key_smp.data.u.str) >= b_size(key) ||
+ !chunk_cpy(key, &key_smp.data.u.str))
goto end;
+ key->area[key->data] = 0;
ret = jwt_verify(input, alg, key, 0);