Skip to content
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -412,5 +412,11 @@ stsafe/stsafe_test
stsafe/wolfssl_stsafe_test
stsafe/wolfssl_stsafe_full_test

# HTTP Message Signatures (RFC 9421) example
http-message-signatures/sign_request
http-message-signatures/test_vectors
http-message-signatures/http_server_verify
http-message-signatures/http_client_signed

# uefi-library generated filesystem content
uefi-library/efifs
13 changes: 13 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -389,6 +389,19 @@ Please see the [uefi-static/README.md](uefi-static/README.md) for further usage
details.


<br />

#### http-message-signatures (RFC 9421 HTTP Message Signatures)

This directory contains examples that demonstrate RFC 9421 HTTP Message
Signatures using wolfCrypt Ed25519, including a signing example,
client/server demo, and test vectors for RFC 9421 Appendix B.2.6.

Please see the
[http-message-signatures/README.md](http-message-signatures/README.md)
for further usage and details.


<br />

#### uefi-library (wolfCrypt UEFI boot module and test app)
Expand Down
35 changes: 35 additions & 0 deletions http-message-signatures/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
CC ?= gcc
WOLFSSL_INSTALL_DIR = /usr/local
CFLAGS = -I$(WOLFSSL_INSTALL_DIR)/include -I. -Wall -Wextra
LDFLAGS = -L$(WOLFSSL_INSTALL_DIR)/lib
LDLIBS = -lwolfssl

COMMON_SRC = common/wc_sf.c common/wc_http_sig.c
COMMON_OBJ = $(COMMON_SRC:.c=.o)

TARGETS = sign_request test_vectors http_server_verify http_client_signed

all: $(TARGETS)

sign_request: sign_request.o $(COMMON_OBJ)
$(CC) -o $@ $^ $(LDFLAGS) $(LDLIBS)

test_vectors: test_vectors.o $(COMMON_OBJ)
$(CC) -o $@ $^ $(LDFLAGS) $(LDLIBS)

http_server_verify: http_server_verify.o $(COMMON_OBJ)
$(CC) -o $@ $^ $(LDFLAGS) $(LDLIBS)

http_client_signed: http_client_signed.o $(COMMON_OBJ)
$(CC) -o $@ $^ $(LDFLAGS) $(LDLIBS)

%.o: %.c
$(CC) -c -o $@ $< $(CFLAGS)

.PHONY: all clean test

clean:
rm -f $(TARGETS) *.o common/*.o

test: test_vectors
./test_vectors
92 changes: 92 additions & 0 deletions http-message-signatures/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
# RFC 9421 HTTP Message Signatures with wolfCrypt

Minimal [RFC 9421](https://www.rfc-editor.org/rfc/rfc9421) implementation
using wolfCrypt Ed25519. Covers derived components (`@method`, `@authority`,
`@path`, `@query`), arbitrary headers, timestamp validation, and `keyid`
extraction. Single signature (`sig1`), Ed25519 only.

## Quick start

```sh
# wolfSSL prerequisite
cd wolfssl && ./configure --enable-ed25519 --enable-coding && make && sudo make install

# Build and test
cd http-message-signatures
make
make test # 17 tests including RFC 9421 B.2.6 vector
./sign_request # standalone signing example
```

## Client/server demo

```sh
./http_server_verify & # terminal 1
./http_client_signed # terminal 2
```

The client sends three requests: a valid signed POST (→ 200), a tampered
request (→ 401), and a valid signed GET (→ 200).

## API

```c
/* Sign — outputs NUL-terminated Signature and Signature-Input header values */
int wc_HttpSig_Sign(
const char* method, const char* authority,
const char* path, const char* query,
const wc_HttpHeader* headers, int headerCount,
ed25519_key* key, const char* keyId, long created,
char* sigOut, word32* sigOutSz,
char* inputOut, word32* inputOutSz);

/* Extract keyid from Signature-Input */
int wc_HttpSig_GetKeyId(
const char* signatureInput, const char* label,
char* keyIdOut, word32* keyIdOutSz);

/* Verify — returns 0 on success; maxAgeSec=0 skips timestamp check */
int wc_HttpSig_Verify(
const char* method, const char* authority,
const char* path, const char* query,
const wc_HttpHeader* headers, int headerCount,
const char* signature, const char* signatureInput,
const char* label, ed25519_key* pubKey, int maxAgeSec);
```

Typical verify flow:

```
1. wc_HttpSig_GetKeyId(sigInput, label, keyIdBuf, &sz)
2. my_key_store_lookup(keyIdBuf) → pubKey
3. wc_HttpSig_Verify(..., pubKey, maxAgeSec)
```

## Limitations

- **No body protection** — no `content-digest` (RFC 9530); signatures cover
components and headers only
- **No replay prevention** — `maxAgeSec` limits the window; nonce tracking
is the caller's responsibility
- **Duplicate headers** — first match wins, no folding
- **Y2038** — `created` uses `long`; overflows on platforms where `long` is
32-bit (all 32-bit targets and 64-bit Windows/LLP64) after 2038-01-19
- **Canonicalization** — signer and verifier must agree on component
representation; intermediaries that rewrite headers will break verification

## Files

```
common/wc_http_sig.{c,h} RFC 9421 sign/verify/getKeyId
common/wc_sf.{c,h} RFC 8941 structured fields (subset)
sign_request.c Standalone signing example
http_server_verify.c Demo server with signature verification
http_client_signed.c Demo client sending signed requests
test_vectors.c 17 tests including RFC 9421 B.2.6
```

## References

- [RFC 9421 — HTTP Message Signatures](https://www.rfc-editor.org/rfc/rfc9421)
- [RFC 8941 — Structured Field Values for HTTP](https://www.rfc-editor.org/rfc/rfc8941)
- [wolfSSL Ed25519 Documentation](https://www.wolfssl.com/documentation/manuals/wolfssl/group__ED25519.html)
Loading