Skip to content

Commit

Permalink
entryway: pull correct key from based on mod service did ref
Browse files Browse the repository at this point in the history
  • Loading branch information
devinivy committed Mar 5, 2024
1 parent f0058e8 commit 1fce33f
Show file tree
Hide file tree
Showing 4 changed files with 79 additions and 7 deletions.
21 changes: 21 additions & 0 deletions packages/common-web/src/did-doc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,27 @@ export const getSigningKey = (
}
}

export const getVerificationMaterial = (
doc: DidDocument,
keyId: string,
): { type: string; publicKeyMultibase: string } | undefined => {
const did = getDid(doc)
let keys = doc.verificationMethod
if (!keys) return undefined
if (typeof keys !== 'object') return undefined
if (!Array.isArray(keys)) {
keys = [keys]
}
const found = keys.find(
(key) => key.id === `#${keyId}` || key.id === `${did}#${keyId}`,
)
if (!found?.publicKeyMultibase) return undefined
return {
type: found.type,
publicKeyMultibase: found.publicKeyMultibase,
}
}

export const getPdsEndpoint = (doc: DidDocument): string | undefined => {
return getServiceEndpoint(doc, {
id: '#atproto_pds',
Expand Down
17 changes: 17 additions & 0 deletions packages/identity/src/did/atproto-data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,23 @@ export const getKey = (doc: DidDocument): string | undefined => {
return didKey
}

export const getDidKeyFromMultibase = (key: {
type: string
publicKeyMultibase: string
}): string | undefined => {
const keyBytes = crypto.multibaseToBytes(key.publicKeyMultibase)
let didKey: string | undefined = undefined
if (key.type === 'EcdsaSecp256r1VerificationKey2019') {
didKey = crypto.formatDidKey(crypto.P256_JWT_ALG, keyBytes)
} else if (key.type === 'EcdsaSecp256k1VerificationKey2019') {
didKey = crypto.formatDidKey(crypto.SECP256K1_JWT_ALG, keyBytes)
} else if (key.type === 'Multikey') {
const parsed = crypto.parseMultikey(key.publicKeyMultibase)
didKey = crypto.formatDidKey(parsed.jwtAlg, parsed.keyBytes)
}
return didKey
}

export const parseToAtprotoDocument = (
doc: DidDocument,
): Partial<AtprotoData> => {
Expand Down
27 changes: 23 additions & 4 deletions packages/pds/src/auth-verifier.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,15 @@ import {
InvalidRequestError,
verifyJwt as verifyServiceJwt,
} from '@atproto/xrpc-server'
import { IdResolver } from '@atproto/identity'
import { IdResolver, getDidKeyFromMultibase } from '@atproto/identity'
import * as ui8 from 'uint8arrays'
import express from 'express'
import * as jose from 'jose'
import KeyEncoder from 'key-encoder'
import Database from './db'
import { softDeleted } from './db/util'
import { SigningKeyMemory, VerifyKey } from './config'
import { getVerificationMaterial } from '@atproto/common'

type ReqCtx = {
req: express.Request
Expand Down Expand Up @@ -260,14 +261,32 @@ export class AuthVerifier {
const payload = await verifyServiceJwt(
jwtStr,
this._pdsServiceDid,
async (did, forceRefresh) => {
if (did !== this._modServiceDid) {
async (iss, forceRefresh) => {
if (
iss !== this._modServiceDid &&
iss !== `${this._modServiceDid}#atproto_labeler`
) {
throw new AuthRequiredError(
'Untrusted issuer for admin actions',
'UntrustedIss',
)
}
return this.idResolver.did.resolveAtprotoKey(did, forceRefresh)
const [did, serviceId] = iss.split('#')
const keyId =
serviceId === 'atproto_labeler' ? 'atproto_label' : 'atproto'
const didDoc = await this.idResolver.did.resolve(did, forceRefresh)
if (!didDoc) {
throw new AuthRequiredError('could not resolve iss did')
}
const parsedKey = getVerificationMaterial(didDoc, keyId)
if (!parsedKey) {
throw new AuthRequiredError('missing or bad key in did doc')
}
const didKey = getDidKeyFromMultibase(parsedKey)
if (!didKey) {
throw new AuthRequiredError('missing or bad key in did doc')
}
return didKey
},
)
return {
Expand Down
21 changes: 18 additions & 3 deletions packages/pds/tests/admin-auth.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,28 @@ describe('admin auth', () => {
pdsDid = network.pds.ctx.cfg.service.did

modServiceKey = await Secp256k1Keypair.create()
const origResolve = network.pds.ctx.idResolver.did.resolveAtprotoKey
network.pds.ctx.idResolver.did.resolveAtprotoKey = async function (
const origResolve = network.pds.ctx.idResolver.did.resolve
network.pds.ctx.idResolver.did.resolve = async function (
did: string,
forceRefresh?: boolean,
) {
if (did === modServiceDid || did === altModDid) {
return modServiceKey.did()
return {
'@context': [
'https://www.w3.org/ns/did/v1',
'https://w3id.org/security/multikey/v1',
'https://w3id.org/security/suites/secp256k1-2019/v1',
],
id: did,
verificationMethod: [
{
id: `${did}#atproto`,
type: 'Multikey',
controller: did,
publicKeyMultibase: modServiceKey.did().replace('did:key:', ''),
},
],
}
}
return origResolve.call(this, did, forceRefresh)
}
Expand Down

0 comments on commit 1fce33f

Please sign in to comment.