Skip to content

Commit c40d9c6

Browse files
committed
feat: Encode method and URL in HTTP message signatures
1 parent a126717 commit c40d9c6

File tree

3 files changed

+19
-16
lines changed

3 files changed

+19
-16
lines changed

packages/css/src/util/fetch/SignedFetcher.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,11 @@ export class SignedFetcher implements Fetcher {
5757
new Headers(init?.headers).forEach((value, key) => request.headers[key] = value);
5858
request.headers['Authorization'] = `HttpSig cred="${this.baseUrl}"`;
5959

60-
const signed = await httpbis.signMessage({ key, paramValues: { keyid: 'TODO' } }, request);
60+
const signed = await httpbis.signMessage({
61+
key,
62+
fields: [ '@target-uri', '@method' ],
63+
paramValues: { keyid: 'TODO' }
64+
}, request);
6165

6266
return await this.fetcher.fetch(url, signed);
6367
}

packages/css/test/unit/util/fetch/SignedFetcher.test.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ describe('SignedFetcher', (): void => {
2929
alg: 'ES256',
3030
getPrivateKey: vi.fn().mockResolvedValue(jwk),
3131
getPublicKey: vi.fn(),
32-
}
32+
};
3333

3434
source = {
3535
fetch: vi.fn().mockResolvedValue('result'),
@@ -42,7 +42,11 @@ describe('SignedFetcher', (): void => {
4242
await expect(fetcher.fetch('http://example.com', { method: 'DELETE', headers: { accept: 'text/turtle' } })).resolves.toBe('result');
4343
expect(signMessage).toHaveBeenCalledTimes(1);
4444
expect(signMessage).toHaveBeenLastCalledWith(
45-
{ key: expect.objectContaining({ alg: 'ES256', id: 'kid' }), paramValues: { keyid: 'TODO' }},
45+
{
46+
key: expect.objectContaining({ alg: 'ES256', id: 'kid' }),
47+
fields: [ '@target-uri', '@method' ],
48+
paramValues: { keyid: 'TODO' }
49+
},
4650
{
4751
url: 'http://example.com',
4852
method: 'DELETE',

packages/uma/src/util/HttpMessageSignatures.ts

Lines changed: 8 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import { UnauthorizedHttpError, type AlgJwk, BadRequestHttpError, InternalServerError } from '@solid/community-server';
2-
import { httpbis, type SigningKey, type Request as SignRequest } from 'http-message-signatures';
1+
import { UnauthorizedHttpError, type AlgJwk, BadRequestHttpError } from '@solid/community-server';
2+
import { httpbis, type SigningKey, type Request as SignRequest, defaultParams } from 'http-message-signatures';
33
import { verifyMessage } from 'http-message-signatures/lib/httpbis';
44
import { type SignatureParameters, type VerifierFinder, type VerifyingKey } from 'http-message-signatures/lib/types';
55
import { HttpHandlerRequest } from './http/models/HttpHandler';
@@ -17,12 +17,13 @@ export async function signRequest(
1717
id: jwk.kid,
1818
alg: jwk.alg,
1919
async sign(data: BufferSource) {
20-
const key = await crypto.subtle.importKey('jwk', jwk, jwk.alg, false, ['sign', 'verify']);
21-
return Buffer.from(await crypto.subtle.sign(jwk.alg, key, data));
20+
const params = algMap[jwk.alg];
21+
const key = await crypto.subtle.importKey('jwk', jwk, params, false, ['sign']);
22+
return Buffer.from(await crypto.subtle.sign(params, key, data));
2223
},
2324
};
2425

25-
return await httpbis.signMessage<RequestInit & SignRequest>({ key }, { ...request, url });
26+
return await httpbis.signMessage({ key, fields: [ '@target-uri', '@method' ] }, { ...request, url });
2627
}
2728

2829
export async function extractRequestSigner(request: HttpHandlerRequest): Promise<string> {
@@ -40,11 +41,7 @@ export async function extractRequestSigner(request: HttpHandlerRequest): Promise
4041
throw new UnauthorizedHttpError();
4142
}
4243

43-
const signer = params.cred;
44-
45-
if (!signer) throw new UnauthorizedHttpError('No valid HTTPSig authorization header found.');
46-
47-
return signer;
44+
return params.cred;
4845
}
4946

5047
export async function verifyRequest(
@@ -66,11 +63,9 @@ export async function verifyRequest(
6663
domain: signer!,
6764
alg: alg ?? '',
6865
kid: keyid ?? '',
69-
})
66+
});
7067

7168
if (!alg) throw new BadRequestHttpError('Invalid HTTP message Signature parameters.');
72-
// if (alg === 'EdDSA') throw new InternalServerError('EdDSA signing is not supported');
73-
// if (alg === 'ES256K') throw new InternalServerError('ES256K signing is not supported');
7469

7570
const verifier: VerifyingKey = {
7671
id: keyid,

0 commit comments

Comments
 (0)