Skip to content

Commit

Permalink
feat(backend): validate httpsig on rs requests using auth implementat…
Browse files Browse the repository at this point in the history
…ion (#672)

* feat(backend): rebase

* feat(backend): move verification to middleware

* feat(backend): update package.json

* feat(backend): remove structured-headers package

* feat(backend): fix linting

* feat(backend): fix httpsig pkg node

* feat(backend): fix httpsig pkg

* feat(backend): readd lib to gitignore

* feat(backend): add flag to skip signature verify

* Update packages/backend/src/open_payments/auth/middleware.ts

Co-authored-by: Brandon Wilson <[email protected]>

* feat(backend): verification updates

* feat(backend): handle eddsa alias

* Update packages/backend/src/open_payments/auth/middleware.ts

Co-authored-by: Brandon Wilson <[email protected]>

* Update packages/backend/src/open_payments/auth/middleware.ts

Co-authored-by: Brandon Wilson <[email protected]>

* Update packages/backend/src/open_payments/auth/middleware.ts

Co-authored-by: Brandon Wilson <[email protected]>

* feat(backend): updates

* feat(backend): restore keyinfo

* feat(backend): add tests

* Update packages/backend/src/open_payments/auth/middleware.test.ts

Co-authored-by: Brandon Wilson <[email protected]>

* Update packages/backend/src/open_payments/auth/middleware.test.ts

Co-authored-by: Brandon Wilson <[email protected]>

* feat(backend): test fixes

* feat(backend): change isdone to done in auth tests

* feat(backend): remove skipSignatureVerification option

* feat(backend): fix content digest verification

* feat(backend): add content digest test

* feat(backend): updates

* feat(backend): update tests

* feat(backend): rebase

* feat(backend): remove http-message-signatures

* feat(backend): rebase

* feat(backend): update ignores

* Update packages/backend/src/open_payments/auth/middleware.test.ts

Co-authored-by: Brandon Wilson <[email protected]>

* feat(backend): updates

* feat(backend): use httpsigcontext

* feat(backend): fix linting

* feat(backend): fix auth test

* feat(backend): fix auth test

* feat(backend): fix lockfile

* feat(backend): fix lockfile

* feat(backend): fix lockfile

* Update packages/backend/src/open_payments/auth/middleware.test.ts

Co-authored-by: Brandon Wilson <[email protected]>

* feat(backend): rebase lock

* feat(backend): rebase middleware

* feat(backend): rebase middleware

* feat(backend): rebase middleware

* Update packages/backend/src/open_payments/auth/middleware.ts

Co-authored-by: Brandon Wilson <[email protected]>

* Update packages/backend/src/open_payments/auth/middleware.test.ts

Co-authored-by: Brandon Wilson <[email protected]>

* feat(backend): updates

* feat(backend): add tests without body

* fix(backend): await prepareTest

Co-authored-by: Damien Clipp <[email protected]>
Co-authored-by: Brandon Wilson <[email protected]>
  • Loading branch information
3 people authored Nov 9, 2022
1 parent 0fa4f61 commit e796ded
Show file tree
Hide file tree
Showing 9 changed files with 505 additions and 115 deletions.
3 changes: 2 additions & 1 deletion packages/auth/src/grant/routes.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ import { Grant, StartMethod, FinishMethod, GrantState } from '../grant/model'
import { AccessToken } from '../accessToken/model'
import { AccessTokenService } from '../accessToken/service'

export const KEY_REGISTRY_ORIGIN = 'https://openpayments.network'
import { KEY_REGISTRY_ORIGIN } from '../tests/signature'
export { KEY_REGISTRY_ORIGIN } from '../tests/signature'
export const KID_PATH = '/keys/base-test-key'
export const TEST_CLIENT_DISPLAY = {
name: 'Test Client',
Expand Down
3 changes: 2 additions & 1 deletion packages/auth/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ import { createAccessTokenRoutes } from './accessToken/routes'
import { createGrantRoutes } from './grant/routes'
import { createOpenAPI } from 'openapi'

export { JWKWithRequired } from './client/service'
export { JWKWithRequired, KeyInfo } from './client/service'
export { HttpSigContext, verifySigAndChallenge } from './signature/middleware'
const container = initIocContainer(Config)
const app = new App(container)

Expand Down
18 changes: 11 additions & 7 deletions packages/auth/src/signature/middleware.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { importJWK } from 'jose'
import { AppContext } from '../app'
import { Grant } from '../grant/model'
import { JWKWithRequired } from '../client/service'
import { Context } from 'koa'

export async function verifySig(
sig: string,
Expand All @@ -17,7 +18,7 @@ export async function verifySig(
return crypto.verify(null, data, publicKey, Buffer.from(sig, 'base64'))
}

async function verifySigAndChallenge(
export async function verifySigAndChallenge(
clientKey: JWKWithRequired,
ctx: HttpSigContext
): Promise<boolean> {
Expand Down Expand Up @@ -68,7 +69,7 @@ function getSigInputComponents(sigInput: string): string[] | null {

function validateSigInputComponents(
sigInputComponents: string[],
ctx: AppContext
ctx: Context
): boolean {
// https://datatracker.ietf.org/doc/html/draft-ietf-gnap-core-protocol#section-7.3.1

Expand All @@ -90,7 +91,7 @@ function validateSigInputComponents(

export function sigInputToChallenge(
sigInput: string,
ctx: AppContext
ctx: Context
): string | null {
const sigInputComponents = getSigInputComponents(sigInput)

Expand Down Expand Up @@ -118,15 +119,18 @@ export function sigInputToChallenge(
return signatureBase
}

type HttpSigRequest = Omit<AppContext['request'], 'headers'> & {
headers: Record<'signature' | 'signature-input', string>
type HttpSigHeaders = Record<'signature' | 'signature-input', string>

type HttpSigRequest = Omit<Context['request'], 'headers'> & {
headers: HttpSigHeaders
}

type HttpSigContext = AppContext & {
export type HttpSigContext = Context & {
request: HttpSigRequest
headers: HttpSigHeaders
}

function validateHttpSigHeaders(ctx: AppContext): ctx is HttpSigContext {
function validateHttpSigHeaders(ctx: Context): ctx is HttpSigContext {
const sig = ctx.headers['signature']
const sigInput = ctx.headers['signature-input'] as string

Expand Down
2 changes: 1 addition & 1 deletion packages/auth/src/tests/signature.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import crypto from 'crypto'
import { v4 } from 'uuid'
import { importJWK, exportJWK } from 'jose'
import { KEY_REGISTRY_ORIGIN } from '../grant/routes.test'
import { JWKWithRequired } from '../client/service'

export const SIGNATURE_METHOD = 'GET'
export const SIGNATURE_TARGET_URI = '/test'
export const KEY_REGISTRY_ORIGIN = 'https://openpayments.network'

export const TEST_CLIENT = {
id: v4(),
Expand Down
8 changes: 4 additions & 4 deletions packages/backend/src/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -329,14 +329,14 @@ export class App {
router[method](
PAYMENT_POINTER_PATH + toRouterPath(path),
createPaymentPointerMiddleware(),
createAuthMiddleware({
type,
action
}),
createValidatorMiddleware<ContextType<typeof route>>(openApi, {
path,
method
}),
createAuthMiddleware({
type,
action
}),
route
)
}
Expand Down
Loading

0 comments on commit e796ded

Please sign in to comment.