Skip to content

Commit

Permalink
fix(utils): convert JWK with curv Ed25519 to X25519 (#1078)
Browse files Browse the repository at this point in the history
  • Loading branch information
nickreynolds authored Dec 5, 2022
1 parent 32a0f97 commit deb546b
Show file tree
Hide file tree
Showing 2 changed files with 96 additions and 3 deletions.
87 changes: 87 additions & 0 deletions packages/did-comm/src/__tests__/packing.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,63 @@ const hexDoc = {
]
}

// https://github.com/aviarytech/didcomm/blob/master/tests/fixtures/didDocs/alice.json
const jwkDocX = {
"@context": ["https://www.w3.org/ns/did/v1", "https://w3id.org/security/suites/jws-2020/v1"],
"id": "did:example:alice",
"verificationMethod": [
{
"id": "did:example:alice#key-0",
"controller": "did:example:alice",
"type": "JsonWebKey2020",
"publicKeyJwk": {
"kty": "OKP",
"crv": "X25519",
"x": "tsc9iYfy4hv2Mz5Q-ztGjKXeXzWUDWl5DLpfepJg4Wc"
}
}
],
"authentication": ["did:example:alice#key-0"],
"assertionMethod": ["did:example:alice#key-0"],
"keyAgreement": ["did:example:alice#key-0"],
"service": [
{
"id": "did:example:alice#didcomm",
"type": "DIDCommMessaging",
"serviceEndpoint": "http://example.com/didcomm",
"routingKeys": []
}
]
}

const jwkDocEd = {
"@context": ["https://www.w3.org/ns/did/v1", "https://w3id.org/security/suites/jws-2020/v1"],
"id": "did:example:alice",
"verificationMethod": [
{
"id": "did:example:alice#key-0",
"controller": "did:example:alice",
"type": "JsonWebKey2020",
"publicKeyJwk": {
"kty": "OKP",
"crv": "Ed25519",
"x": "CV-aGlld3nVdgnhoZK0D36Wk-9aIMlZjZOK2XhPMnkQ"
}
}
],
"authentication": ["did:example:alice#key-0"],
"assertionMethod": ["did:example:alice#key-0"],
"keyAgreement": ["did:example:alice#key-0"],
"service": [
{
"id": "did:example:alice#didcomm",
"type": "DIDCommMessaging",
"serviceEndpoint": "http://example.com/didcomm",
"routingKeys": []
}
]
}

describe('didComm', () => {
let didKeyIdentifier: IIdentifier
let agent: TAgent<IResolver & IKeyManager & IDIDManager>
Expand Down Expand Up @@ -165,6 +222,10 @@ describe('didComm', () => {
doc = multiBaseDoc
} else if (did === "did:fake:hex") {
doc = hexDoc
} else if (did === "did:fake:jwkx") {
doc = jwkDocX
} else if (did === "did:fake:jwked") {
doc = jwkDocEd
} else {
throw new Error("Bad didUrl for fake resolver: " + did)
}
Expand Down Expand Up @@ -202,6 +263,8 @@ describe('didComm', () => {
expect(packedMessage).toBeDefined()
})

it.todo('should unpack message packed for base58')

it('should pack message for public key as multibase', async () => {
const packedMessage = await agent.packDIDCommMessage({
message: testMessage("did:fake:multibase"),
Expand All @@ -210,11 +273,35 @@ describe('didComm', () => {
expect(packedMessage).toBeDefined()
})

it.todo('should unpack message packed for multibase')

it('should pack message for public key as hex', async () => {
const packedMessage = await agent.packDIDCommMessage({
message: testMessage("did:fake:hex"),
packing: 'authcrypt'
})
expect(packedMessage).toBeDefined()
})

it.todo('should unpack message packed for hex')

it('should pack message for public key as jwk with X25519 crv', async () => {
const packedMessage = await agent.packDIDCommMessage({
message: testMessage("did:fake:jwkx"),
packing: 'authcrypt'
})
expect(packedMessage).toBeDefined()
})

it.todo('should unpack message packed for jwk with X25519 crv')

it('should pack message for public key as jwk with Ed25519 crv', async () => {
const packedMessage = await agent.packDIDCommMessage({
message: testMessage("did:fake:jwked"),
packing: 'authcrypt'
})
expect(packedMessage).toBeDefined()
})

it.todo('should unpack message packed for jwk with Ed25519 crv')
})
12 changes: 9 additions & 3 deletions packages/utils/src/did-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ function extractPublicKeyBytes(pk: VerificationMethod): Uint8Array {
)
} else if (
pk.publicKeyJwk &&
pk.publicKeyJwk.crv === 'Ed25519' &&
(pk.publicKeyJwk.crv === 'Ed25519' || pk.publicKeyJwk.crv === 'X25519') &&
pk.publicKeyJwk.x
) {
return base64ToBytes(pk.publicKeyJwk.x)
Expand Down Expand Up @@ -311,9 +311,15 @@ export async function dereferenceDidKeys(
const hexKey = extractPublicKeyHex(key, convert)
const { publicKeyHex, publicKeyBase58, publicKeyMultibase, publicKeyBase64, publicKeyJwk, ...keyProps } = key
const newKey = { ...keyProps, publicKeyHex: hexKey }

// With a JWK `key`, `newKey` does not have information about crv (Ed25519 vs X25519)
// Should type of `newKey` change?
if (convert && 'Ed25519VerificationKey2018' === newKey.type) {
newKey.type = 'X25519KeyAgreementKey2019'
} else if (convert && 'Ed25519VerificationKey2020' === newKey.type) {
newKey.type = 'X25519KeyAgreementKey2020'
}

return newKey
})
}
Expand All @@ -330,9 +336,9 @@ export async function dereferenceDidKeys(
export function extractPublicKeyHex(pk: _ExtendedVerificationMethod, convert: boolean = false): string {
let keyBytes = extractPublicKeyBytes(pk)
if (convert) {
if (['Ed25519', 'Ed25519VerificationKey2018', 'Ed25519VerificationKey2020'].includes(pk.type)) {
if (['Ed25519', 'Ed25519VerificationKey2018', 'Ed25519VerificationKey2020'].includes(pk.type) || (pk.type === 'JsonWebKey2020' && pk.publicKeyJwk?.crv === 'Ed25519')) {
keyBytes = convertPublicKeyToX25519(keyBytes)
} else if (!['X25519', 'X25519KeyAgreementKey2019', 'X25519KeyAgreementKey2020'].includes(pk.type)) {
} else if (!['X25519', 'X25519KeyAgreementKey2019', 'X25519KeyAgreementKey2020'].includes(pk.type) && !(pk.type === 'JsonWebKey2020' && pk.publicKeyJwk?.crv === 'X25519')) {
return ''
}
}
Expand Down

0 comments on commit deb546b

Please sign in to comment.