From 55d11d187458f2e85b61da7e79807487eef4c8c2 Mon Sep 17 00:00:00 2001 From: Nathan Lie Date: Wed, 30 Nov 2022 13:31:21 -0800 Subject: [PATCH] feat(auth): add content type and length to signature headers (#804) --- packages/auth/src/tests/context.ts | 25 ++++++++++++++----------- packages/auth/src/tests/signature.ts | 27 ++++++++++++++++++++++++--- 2 files changed, 38 insertions(+), 14 deletions(-) diff --git a/packages/auth/src/tests/context.ts b/packages/auth/src/tests/context.ts index a2a4a83135..9d43e45760 100644 --- a/packages/auth/src/tests/context.ts +++ b/packages/auth/src/tests/context.ts @@ -46,16 +46,17 @@ export async function createContextWithSigHeaders( container?: IocContract ): Promise { const { headers, url, method } = reqOpts - const { signature, sigInput, contentDigest } = await generateSigHeaders({ - privateKey, - keyId, - url, - method, - optionalComponents: { - body: requestBody, - authorization: headers.Authorization as string - } - }) + const { signature, sigInput, contentDigest, contentLength, contentType } = + await generateSigHeaders({ + privateKey, + keyId, + url, + method, + optionalComponents: { + body: requestBody, + authorization: headers.Authorization as string + } + }) const ctx = createContext( { @@ -64,7 +65,9 @@ export async function createContextWithSigHeaders( ...headers, 'Content-Digest': contentDigest, Signature: signature, - 'Signature-Input': sigInput + 'Signature-Input': sigInput, + 'Content-Type': contentType, + 'Content-Length': contentLength } }, params, diff --git a/packages/auth/src/tests/signature.ts b/packages/auth/src/tests/signature.ts index 04cb3275c0..c9c02d848b 100644 --- a/packages/auth/src/tests/signature.ts +++ b/packages/auth/src/tests/signature.ts @@ -69,18 +69,33 @@ export async function generateSigHeaders({ body?: unknown authorization?: string } -}): Promise<{ sigInput: string; signature: string; contentDigest?: string }> { +}): Promise<{ + sigInput: string + signature: string + contentDigest?: string + contentLength?: string + contentType?: string +}> { let sigInputComponents = 'sig1=("@method" "@target-uri"' const { body, authorization } = optionalComponents ?? {} - if (body) sigInputComponents += ' "content-digest"' + if (body) + sigInputComponents += ' "content-digest" "content-length" "content-type"' + if (authorization) sigInputComponents += ' "authorization"' const sigInput = sigInputComponents + `);created=1618884473;keyid="${keyId}"` let challenge = `"@method": ${method}\n"@target-uri": ${url}\n` let contentDigest + let contentLength + let contentType if (body) { contentDigest = createContentDigestHeader(JSON.stringify(body), ['sha-512']) challenge += `"content-digest": ${contentDigest}\n` + + contentLength = Buffer.from(JSON.stringify(body), 'utf-8').length + challenge += `"content-length": ${contentLength}\n` + contentType = 'application/json' + challenge += `"content-type": ${contentType}\n` } if (authorization) { @@ -92,5 +107,11 @@ export async function generateSigHeaders({ const privateJwk = (await importJWK(privateKey)) as crypto.KeyLike const signature = crypto.sign(null, Buffer.from(challenge), privateJwk) - return { signature: signature.toString('base64'), sigInput, contentDigest } + return { + signature: signature.toString('base64'), + sigInput, + contentDigest, + contentLength, + contentType + } }