curl: make --httpsig-key take a key OR a file name for key
No binary (build failed)
—
(log yok)
| @@ -3,8 +3,8 @@ c: Copyright (C) Daniel Stenberg, <[email protected]>, et al. | |
| SPDX-License-Identifier: curl | |
| Long: httpsig-key | |
| Protocols: HTTP | |
| - | Arg: <file> |
| - | Help: Key file for HTTP Message Signatures |
| + | Arg: <key/file> |
| + | Help: Key for HTTP Message Signatures |
| Category: auth http | |
| Added: 8.22.0 | |
| Multi: single | |
| @@ -13,16 +13,19 @@ See-also: | |
| - httpsig-algo | |
| - httpsig-keyid | |
| Example: | |
| - | - --httpsig-algo ed25519 --httpsig-key key.hex --httpsig-keyid "my-key" $URL |
| + | - --httpsig-algo ed25519 --httpsig-key @key.hex --httpsig-keyid "my-key" $URL |
| + | - --httpsig-key 123a56fb72197633bc --httpsig-keyid "my-key" $URL |
| --- | |
| # `--httpsig-key` | |
| - | Path to the key file used for RFC 9421 HTTP Message Signatures. |
| + | The key to use for RFC 9421 HTTP Message Signatures. Provide it as-is, or as |
| + | `@filename`. If the argument starts with an `@`, the rest is treated as a file |
| + | name for the key. |
| - | The file must contain a hex-encoded key on its first line. For **ed25519**, |
| - | this is the 32-byte private seed (64 hex characters). For **hmac-sha256**, |
| - | this is the shared secret. PEM files are not supported. |
| + | The key is formatted as a series of hexadecimal digits in a single line. For |
| + | **ed25519**, this is the 32-byte private seed (64 hex characters). For |
| + | **hmac-sha256**, this is the shared secret. PEM files are not supported. |
| ## Generating Ed25519 keys | |
| @@ -32,4 +35,4 @@ With OpenSSL 3: | |
| openssl pkey -in k.pem -outform RAW -out k.raw | |
| xxd -p -c 64 k.raw | tr -d '\n' > k.hex | |
| - | Use `k.hex` with `--httpsig-key`. |
| + | Use `@k.hex` with `--httpsig-key`. |
| @@ -599,8 +599,9 @@ static CURLcode httpsig_setopts(struct OperationConfig *config, CURL *curl) | |
| my_setopt_long(curl, CURLOPT_HTTPSIG_ALGORITHM, httpsig_alg); | |
| MY_SETOPT_STR(curl, CURLOPT_HTTPSIG_HEADERS, config->httpsig_headers); | |
| MY_SETOPT_STR(curl, CURLOPT_HTTPSIG_KEYID, config->httpsig_keyid); | |
| - | { |
| - | FILE *keyf = curlx_fopen(config->httpsig_key, FOPEN_READTEXT); |
| + | |
| + | if(config->httpsig_key[0] == '@') { |
| + | FILE *keyf = curlx_fopen(&config->httpsig_key[1], FOPEN_READTEXT); |
| if(keyf) { | |
| char *hexdata = NULL; | |
| ParameterError pe = file2string(&hexdata, keyf); | |
| @@ -612,12 +613,13 @@ static CURLcode httpsig_setopts(struct OperationConfig *config, CURL *curl) | |
| } | |
| if(pe == PARAM_READ_ERROR) { | |
| curlx_safefree(hexdata); | |
| - | errorf("httpsig: cannot read key file '%s'", config->httpsig_key); |
| + | errorf("httpsig: cannot read key file '%s'", |
| + | &config->httpsig_key[1]); |
| return CURLE_READ_ERROR; | |
| } | |
| if(!hexdata || !*hexdata) { | |
| curlx_safefree(hexdata); | |
| - | errorf("httpsig: key file '%s' is empty", config->httpsig_key); |
| + | errorf("httpsig: key file '%s' is empty", &config->httpsig_key[1]); |
| return CURLE_BAD_FUNCTION_ARGUMENT; | |
| } | |
| /* can't use the MY_SETOPT_STR() macro here since it returns on error | |
| @@ -628,10 +630,17 @@ static CURLcode httpsig_setopts(struct OperationConfig *config, CURL *curl) | |
| return result; | |
| } | |
| else { | |
| - | errorf("httpsig: cannot open key file '%s'", config->httpsig_key); |
| + | errorf("httpsig: cannot open key file '%s'", &config->httpsig_key[1]); |
| return CURLE_READ_ERROR; | |
| } | |
| } | |
| + | else { |
| + | if(!config->httpsig_key[0]) { |
| + | errorf("httpsig: key is empty"); |
| + | return CURLE_BAD_FUNCTION_ARGUMENT; |
| + | } |
| + | MY_SETOPT_STR(curl, CURLOPT_HTTPSIG_KEY, config->httpsig_key); |
| + | } |
| } | |
| return CURLE_OK; | |
| } | |
| @@ -314,8 +314,8 @@ const struct helptxt helptext[] = { | |
| CURLHELP_AUTH | CURLHELP_HTTP }, | |
| #endif | |
| #ifndef CURL_DISABLE_HTTPSIG | |
| - | { " --httpsig-key <file>", |
| - | "Key file for HTTP Message Signatures", |
| + | { " --httpsig-key <key/file>", |
| + | "Key for HTTP Message Signatures", |
| CURLHELP_AUTH | CURLHELP_HTTP }, | |
| #endif | |
| #ifndef CURL_DISABLE_HTTPSIG | |
| @@ -294,7 +294,7 @@ test4000 test4001 \ | |
| \ | |
| test5000 test5001 test5002 test5003 test5004 test5005 test5006 test5007 \ | |
| test5008 test5009 test5010 test5011 test5012 test5013 test5014 test5015 \ | |
| - | test5016 test5017 test5018 test5019 test5020 test5021 |
| + | test5016 test5017 test5018 test5019 test5020 test5021 test5022 |
| EXTRA_DIST = $(TESTCASES) DISABLED data-xml1 \ | |
| data1461.txt data1463.txt \ | |
| @@ -36,7 +36,7 @@ httpsig | |
| HTTP RFC 9421 Message Signatures: CLI GET with query | |
| </name> | |
| <command> | |
| - | "http://example.com:8000/%TESTNUMBER/resource?action=read" --httpsig-algo "ed25519" --httpsig-key %SRCDIR/data/data-httpsig-ed25519.key --httpsig-keyid "my-key-1" --connect-to example.com:8000:%HOSTIP:%HTTPPORT |
| + | "http://example.com:8000/%TESTNUMBER/resource?action=read" --httpsig-algo "ed25519" --httpsig-key @%SRCDIR/data/data-httpsig-ed25519.key --httpsig-keyid "my-key-1" --connect-to example.com:8000:%HOSTIP:%HTTPPORT |
| </command> | |
| </client> | |
| @@ -36,7 +36,7 @@ httpsig | |
| HTTP RFC 9421 Message Signatures: CLI GET with HMAC-SHA256 | |
| </name> | |
| <command> | |
| - | "http://example.com:7000/%TESTNUMBER/resource" --httpsig-algo "hmac-sha256" --httpsig-key %SRCDIR/data/data-httpsig-hmac-sha256.key --httpsig-keyid "shared-key-1" --connect-to example.com:7000:%HOSTIP:%HTTPPORT |
| + | "http://example.com:7000/%TESTNUMBER/resource" --httpsig-algo "hmac-sha256" --httpsig-key @%SRCDIR/data/data-httpsig-hmac-sha256.key --httpsig-keyid "shared-key-1" --connect-to example.com:7000:%HOSTIP:%HTTPPORT |
| </command> | |
| </client> | |
| @@ -36,7 +36,7 @@ httpsig | |
| HTTP RFC 9421 Message Signatures: custom --httpsig-headers | |
| </name> | |
| <command> | |
| - | "http://example.com:6000/%TESTNUMBER/resource" --httpsig-algo "ed25519" --httpsig-key %SRCDIR/data/data-httpsig-ed25519.key --httpsig-keyid "test-key-ed25519" --httpsig-headers "method authority" --connect-to example.com:6000:%HOSTIP:%HTTPPORT |
| + | "http://example.com:6000/%TESTNUMBER/resource" --httpsig-algo "ed25519" --httpsig-key @%SRCDIR/data/data-httpsig-ed25519.key --httpsig-keyid "test-key-ed25519" --httpsig-headers "method authority" --connect-to example.com:6000:%HOSTIP:%HTTPPORT |
| </command> | |
| </client> | |
| @@ -36,7 +36,7 @@ httpsig | |
| HTTP RFC 9421 Message Signatures: sign with a regular HTTP header | |
| </name> | |
| <command> | |
| - | "http://example.com:5000/%TESTNUMBER/resource" --httpsig-algo "ed25519" --httpsig-key %SRCDIR/data/data-httpsig-ed25519.key --httpsig-keyid "test-key-ed25519" --httpsig-headers "method authority content-type:" -H "Content-Type: application/json" --connect-to example.com:5000:%HOSTIP:%HTTPPORT |
| + | "http://example.com:5000/%TESTNUMBER/resource" --httpsig-algo "ed25519" --httpsig-key @%SRCDIR/data/data-httpsig-ed25519.key --httpsig-keyid "test-key-ed25519" --httpsig-headers "method authority content-type:" -H "Content-Type: application/json" --connect-to example.com:5000:%HOSTIP:%HTTPPORT |
| </command> | |
| </client> | |
| @@ -36,7 +36,7 @@ httpsig | |
| HTTP RFC 9421 Message Signatures: component name lowercasing | |
| </name> | |
| <command> | |
| - | "http://example.com:5100/%TESTNUMBER/resource" --httpsig-algo "ed25519" --httpsig-key %SRCDIR/data/data-httpsig-ed25519.key --httpsig-keyid "test-key-ed25519" --httpsig-headers "method Content-Type:" -H "Content-Type: text/plain" --connect-to example.com:5100:%HOSTIP:%HTTPPORT |
| + | "http://example.com:5100/%TESTNUMBER/resource" --httpsig-algo "ed25519" --httpsig-key @%SRCDIR/data/data-httpsig-ed25519.key --httpsig-keyid "test-key-ed25519" --httpsig-headers "method Content-Type:" -H "Content-Type: text/plain" --connect-to example.com:5100:%HOSTIP:%HTTPPORT |
| </command> | |
| </client> | |
| @@ -36,7 +36,7 @@ httpsig | |
| HTTP RFC 9421 Message Signatures: POST method | |
| </name> | |
| <command> | |
| - | "http://example.com:5200/%TESTNUMBER/resource" --httpsig-algo "ed25519" --httpsig-key %SRCDIR/data/data-httpsig-ed25519.key --httpsig-keyid "test-key-ed25519" -d "postbody" --connect-to example.com:5200:%HOSTIP:%HTTPPORT |
| + | "http://example.com:5200/%TESTNUMBER/resource" --httpsig-algo "ed25519" --httpsig-key @%SRCDIR/data/data-httpsig-ed25519.key --httpsig-keyid "test-key-ed25519" -d "postbody" --connect-to example.com:5200:%HOSTIP:%HTTPPORT |
| </command> | |
| </client> | |
| @@ -33,7 +33,7 @@ httpsig | |
| HTTP RFC 9421 Message Signatures: error - non-existent key file | |
| </name> | |
| <command> | |
| - | "http://example.com/%TESTNUMBER/resource" --httpsig-algo "ed25519" --httpsig-key /nonexistent/key.hex --httpsig-keyid "my-key" --connect-to example.com::%HOSTIP:%HTTPPORT |
| + | "http://example.com/%TESTNUMBER/resource" --httpsig-algo "ed25519" --httpsig-key @/nonexistent/key.hex --httpsig-keyid "my-key" --connect-to example.com::%HOSTIP:%HTTPPORT |
| </command> | |
| </client> | |
| @@ -36,7 +36,7 @@ httpsig | |
| HTTP RFC 9421 Message Signatures: query string with special characters | |
| </name> | |
| <command> | |
| - | "http://example.com:5300/%TESTNUMBER/resource?name=me%AMPnoval%AMPaim=b%25ad" --httpsig-algo "ed25519" --httpsig-key %SRCDIR/data/data-httpsig-ed25519.key --httpsig-keyid "test-key-ed25519" --connect-to example.com:5300:%HOSTIP:%HTTPPORT |
| + | "http://example.com:5300/%TESTNUMBER/resource?name=me%AMPnoval%AMPaim=b%25ad" --httpsig-algo "ed25519" --httpsig-key @%SRCDIR/data/data-httpsig-ed25519.key --httpsig-keyid "test-key-ed25519" --connect-to example.com:5300:%HOSTIP:%HTTPPORT |
| </command> | |
| </client> | |
| @@ -36,7 +36,7 @@ httpsig | |
| HTTP RFC 9421 Message Signatures: default port omitted from @authority | |
| </name> | |
| <command> | |
| - | "http://example.com/%TESTNUMBER/resource" --httpsig-algo "ed25519" --httpsig-key %SRCDIR/data/data-httpsig-ed25519.key --httpsig-keyid "test-key-ed25519" --connect-to example.com::%HOSTIP:%HTTPPORT |
| + | "http://example.com/%TESTNUMBER/resource" --httpsig-algo "ed25519" --httpsig-key @%SRCDIR/data/data-httpsig-ed25519.key --httpsig-keyid "test-key-ed25519" --connect-to example.com::%HOSTIP:%HTTPPORT |
| </command> | |
| </client> | |
| @@ -36,7 +36,7 @@ httpsig | |
| HTTP RFC 9421 Message Signatures: non-default port in @authority | |
| </name> | |
| <command> | |
| - | "http://example.com:9000/%TESTNUMBER/resource" --httpsig-algo "ed25519" --httpsig-key %SRCDIR/data/data-httpsig-ed25519.key --httpsig-keyid "test-key-ed25519" --connect-to example.com:9000:%HOSTIP:%HTTPPORT |
| + | "http://example.com:9000/%TESTNUMBER/resource" --httpsig-algo "ed25519" --httpsig-key @%SRCDIR/data/data-httpsig-ed25519.key --httpsig-keyid "test-key-ed25519" --connect-to example.com:9000:%HOSTIP:%HTTPPORT |
| </command> | |
| </client> | |
| @@ -36,7 +36,7 @@ httpsig | |
| HTTP RFC 9421 Message Signatures: @query explicitly requested, no query in URL | |
| </name> | |
| <command> | |
| - | "http://example.com:5400/%TESTNUMBER/resource" --httpsig-algo "ed25519" --httpsig-key %SRCDIR/data/data-httpsig-ed25519.key --httpsig-keyid "test-key-ed25519" --httpsig-headers "method authority query" --connect-to example.com:5400:%HOSTIP:%HTTPPORT |
| + | "http://example.com:5400/%TESTNUMBER/resource" --httpsig-algo "ed25519" --httpsig-key @%SRCDIR/data/data-httpsig-ed25519.key --httpsig-keyid "test-key-ed25519" --httpsig-headers "method authority query" --connect-to example.com:5400:%HOSTIP:%HTTPPORT |
| </command> | |
| </client> | |
| @@ -37,7 +37,7 @@ httpsig | |
| HTTP RFC 9421 Message Signatures: POST with HMAC-SHA256 | |
| </name> | |
| <command> | |
| - | "http://example.com:5500/%TESTNUMBER/resource" --httpsig-algo "hmac-sha256" --httpsig-key %SRCDIR/data/data-httpsig-hmac-sha256.key --httpsig-keyid "shared-key-1" -d "postbody" --connect-to example.com:5500:%HOSTIP:%HTTPPORT |
| + | "http://example.com:5500/%TESTNUMBER/resource" --httpsig-algo "hmac-sha256" --httpsig-key @%SRCDIR/data/data-httpsig-hmac-sha256.key --httpsig-keyid "shared-key-1" -d "postbody" --connect-to example.com:5500:%HOSTIP:%HTTPPORT |
| </command> | |
| </client> | |
| @@ -37,7 +37,7 @@ httpsig | |
| HTTP RFC 9421 Message Signatures: HMAC-SHA256 with custom headers | |
| </name> | |
| <command> | |
| - | "http://example.com:5600/%TESTNUMBER/resource" --httpsig-algo "hmac-sha256" --httpsig-key %SRCDIR/data/data-httpsig-hmac-sha256.key --httpsig-keyid "shared-key-1" --httpsig-headers "method authority content-type:" -H "Content-Type: application/json" --connect-to example.com:5600:%HOSTIP:%HTTPPORT |
| + | "http://example.com:5600/%TESTNUMBER/resource" --httpsig-algo "hmac-sha256" --httpsig-key @%SRCDIR/data/data-httpsig-hmac-sha256.key --httpsig-keyid "shared-key-1" --httpsig-headers "method authority content-type:" -H "Content-Type: application/json" --connect-to example.com:5600:%HOSTIP:%HTTPPORT |
| </command> | |
| </client> | |
| @@ -39,7 +39,7 @@ putdata | |
| HTTP RFC 9421 Message Signatures: PUT upload | |
| </name> | |
| <command> | |
| - | "http://example.com:5800/%TESTNUMBER/resource" --httpsig-algo "ed25519" --httpsig-key %SRCDIR/data/data-httpsig-ed25519.key --httpsig-keyid "test-key-ed25519" -T log/upload5018 --connect-to example.com:5800:%HOSTIP:%HTTPPORT |
| + | "http://example.com:5800/%TESTNUMBER/resource" --httpsig-algo "ed25519" --httpsig-key @%SRCDIR/data/data-httpsig-ed25519.key --httpsig-keyid "test-key-ed25519" -T log/upload5018 --connect-to example.com:5800:%HOSTIP:%HTTPPORT |
| </command> | |
| </client> | |
| @@ -35,7 +35,7 @@ httpsig | |
| HTTP RFC 9421 Message Signatures: default algorithm (ed25519) when --httpsig-algo omitted | |
| </name> | |
| <command> | |
| - | "http://example.com:6100/%TESTNUMBER/resource" --httpsig-key %SRCDIR/data/data-httpsig-ed25519.key --httpsig-keyid "test-key-ed25519" --connect-to example.com:6100:%HOSTIP:%HTTPPORT |
| + | "http://example.com:6100/%TESTNUMBER/resource" --httpsig-key @%SRCDIR/data/data-httpsig-ed25519.key --httpsig-keyid "test-key-ed25519" --connect-to example.com:6100:%HOSTIP:%HTTPPORT |
| </command> | |
| </client> | |
| @@ -0,0 +1,55 @@ | |
| + | <?xml version="1.0" encoding="US-ASCII"?> |
| + | <testcase> |
| + | <info> |
| + | <keywords> |
| + | HTTP |
| + | httpsig |
| + | RFC9421 |
| + | </keywords> |
| + | </info> |
| + | |
| + | # Server-side |
| + | <reply> |
| + | <data crlf="headers"> |
| + | HTTP/1.1 200 OK |
| + | Date: Tue, 09 Nov 2010 14:49:00 GMT |
| + | Server: test-server/fake |
| + | Last-Modified: Tue, 13 Jun 2000 12:10:00 GMT |
| + | Content-Length: 6 |
| + | Connection: close |
| + | Content-Type: text/html |
| + | |
| + | -foo- |
| + | </data> |
| + | </reply> |
| + | |
| + | # Client-side |
| + | <client> |
| + | <server> |
| + | http |
| + | </server> |
| + | <features> |
| + | Debug |
| + | httpsig |
| + | </features> |
| + | <name> |
| + | HTTP RFC 9421 Message Signatures: pass key directly |
| + | </name> |
| + | <command> |
| + | "http://example.com:8000/5001/resource?action=read" --httpsig-algo "ed25519" --variable key@%SRCDIR/data/data-httpsig-ed25519.key --expand-httpsig-key '{{key:trim}}' --httpsig-keyid "my-key-1" --connect-to example.com:8000:%HOSTIP:%HTTPPORT |
| + | </command> |
| + | </client> |
| + | |
| + | # Verify data after the test has been "shot" |
| + | <verify> |
| + | <protocol crlf="headers"> |
| + | GET /5001/resource?action=read HTTP/1.1 |
| + | Host: example.com:8000 |
| + | Signature-Input: sig1=("@method" "@authority" "@path" "@query");created=0;keyid="my-key-1";alg="ed25519" |
| + | Signature: sig1=:RQniOeqmwdRzGvoDIMJ8XJha75evJWgqo5/66EeuJeEGczZtnP2U/F52Lzd/y7Vd1DCb8oUcCKHrKi2VJI7lBA==: |
| + | User-Agent: curl/%VERSION |
| + | Accept: */* |
| + | |
| + | </protocol> |
| + | </verify> |
| + | </testcase> |