Skip to content

Commit

Permalink
add direct tag 16
Browse files Browse the repository at this point in the history
  • Loading branch information
OR13 committed Feb 23, 2024
1 parent fb1d9c6 commit 93a4bef
Show file tree
Hide file tree
Showing 6 changed files with 31 additions and 46 deletions.
2 changes: 1 addition & 1 deletion examples/hpke.direct.diag
Original file line number Diff line number Diff line change
@@ -1 +1 @@
96([h'a1011823', {}, h'cb3fbf75dd90e2848e7cde4451a82f0233dc00a96394c4232c2bc79aacb6b648d2bf9ba72db83c232b5d8832601af2d865317a49b3feb385288b5d28788a3f52200fc012ae8c99c42dcd5fdbdda825dd', [[h'a1011823', {4: "meriadoc.brandybuck@buckland.example", -1: {1: 5, -1: h'048f98972f38af086e2b8cdb40ffd2c0b22ef5d600f263f1541f09907e97dbe0af06aaf0dcdcd47ce7d1913c5dad4d689b89cbfd28ab45d446c662301483676bf9'}}, h'']]])
16([h'a1011823', {4: "meriadoc.brandybuck@buckland.example", -1: {1: 5, -1: h'047e28c472862e148b3a039640f3a2461855ab43b955b2232575e2c2d2e5998369c38ea1be27f483c2d2fc860345298bf3316737b8771c8aa4783b366914199ab0'}}, h'6fde098224bc4f8661fb7c268dbce2269612a092490e94cb9b0de698ed015e2594e148b5ec418a7c397866c66f26af4ddf8d5c602899fe5d494833390e47075a6b7243e0594e930947c906f365626506'])
2 changes: 1 addition & 1 deletion examples/hpke.wrap.diag
Original file line number Diff line number Diff line change
@@ -1 +1 @@
96([h'a10101', {5: 64(h'41469c98fcbd872dd11a01df13b33743')}, h'55181b9b3e619ed041fbd863ecf62517f1eabafaa3b61f7d204b1b7f5cda6ddd36726df0219c1842351bcc65219a5c2222d0e8163ab478cf61b3916bb3dc0e805fd6aa297bd84b394c4792f9421b0391', [[h'a1011823', {4: "meriadoc.brandybuck@buckland.example", -1: {1: 5, -1: h'04b5f1c2cb90d20ec23ed8adafd0f548ceccc72a1ac3b189bc646eb02ed5621fe3216c88e777d201b24103b65a5dfce8ca5afefffada562a9b776361cf843a8300'}}, h'b4622b2ef308e90fea8c70858089df4ebf95dc6091ac2e45122cb93b5f7b5e26']]])
96([h'a10101', {5: 64(h'd87da66c769df98f417188913d393f63')}, h'71b7f5825726e08580d95d5b3123af4cb3013bf9835302486fcbf306010af64cb085ce936746a97fadf0ca6e7b59347c03e9404a232603ce7911a5eb31c3070062938e90488fa7b631b4f4a0be619aaf', [[h'a1011823', {4: "meriadoc.brandybuck@buckland.example", -1: {1: 5, -1: h'0484a62d158fadb34eaf812aa7a246dfb1c2aaac313b3dc6d6388fd3729f61dd1b87a9b51a1d12dc281fa8ebfa34d219088e46a6038363717fd94aaa1aeb796ce7'}}, h'755902f15658d8ebbbf47667a5e93f88903188dda2e6f04b58f5f13c466d0070']]])
10 changes: 4 additions & 6 deletions src/cose/encrypt/direct.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,17 +61,15 @@ export const encrypt = async (req: RequestDirectEncryption) => {
return encodeAsync(new Tagged(COSE_Encrypt_Tag, COSE_Encrypt), { canonical: true })
}



export const decrypt = async (req: RequestDirectDecryption) => {
const decoded = await decodeFirst(req.ciphertext)
if (decoded.tag !== 96) {
throw new Error('Only tag 96 cose encrypt are supported')
}
const receiverPrivateKeyJwk = req.recipients.keys[0]
if (receiverPrivateKeyJwk.alg === hpke.primaryAlgorithm.label) {
return hpke.decrypt.direct(req)
}
const decoded = await decodeFirst(req.ciphertext)
if (decoded.tag !== 96) {
throw new Error('Only tag 96 cose encrypt are supported')
}
const [protectedHeader, unprotectedHeader, ciphertext, recipients] = decoded.value
if (recipients.length !== 1) {
throw new Error('Expected a single recipient for direct decryption')
Expand Down
55 changes: 21 additions & 34 deletions src/cose/encrypt/hpke.ts
Original file line number Diff line number Diff line change
Expand Up @@ -127,16 +127,12 @@ export const secondaryAlgorithm = {
'value': 37
}

export const directAlgorithm = {
'label': `HPKE-Direct`,
'value': 36
}

const computeHPKEAad = (protectedHeader: any, protectedRecipientHeader: any, direct = false) => {
if (direct) {
return protectedHeader
const computeHPKEAad = (protectedHeader: any, protectedRecipientHeader?: any) => {
if (protectedRecipientHeader) {
// not sure what to do when recipient protected header exists...
return encode([protectedHeader, protectedRecipientHeader])
}
return encode([protectedHeader, protectedRecipientHeader])
return protectedHeader
}

const encryptWrap = async (req: RequestWrapEncryption) => {
Expand Down Expand Up @@ -193,43 +189,37 @@ const encryptWrap = async (req: RequestWrapEncryption) => {
}

export const encryptDirect = async (req: RequestDirectEncryption) => {
if (req.protectedHeader.get(1) !== 35) {
throw new Error('Only alg 35 is supported')
}
const protectedHeader = await encodeAsync(req.protectedHeader)
const unprotectedHeader = req.unprotectedHeader;
const [recipientPublicKeyJwk] = req.recipients.keys
const suite = suites[recipientPublicKeyJwk.alg as JOSE_HPKE_ALG]
const sender = await suite.createSenderContext({
recipientPublicKey: await publicKeyFromJwk(recipientPublicKeyJwk),
});
const recipientProtectedHeader = await encodeAsync(new Map<number, any>([
[1, primaryAlgorithm.value],
]))
const hpkeSealAad = computeHPKEAad(protectedHeader, recipientProtectedHeader, true)
const hpkeSealAad = computeHPKEAad(protectedHeader)
const ciphertext = await sender.seal(req.plaintext, hpkeSealAad)
const recipientCoseKey = new Map<any, any>([
[1, 5], // kty: EK
[- 1, sender.enc]
])
const recipientUnprotectedHeader = new Map([
[4, recipientPublicKeyJwk.kid], // kid
[-1, recipientCoseKey], // epk
])
const recipients = [[recipientProtectedHeader, recipientUnprotectedHeader, EMPTY_BUFFER]]
const COSE_Encrypt = [
unprotectedHeader.set(4, recipientPublicKeyJwk.kid)
unprotectedHeader.set(-1, recipientCoseKey)
const COSE_Encrypt0 = [
protectedHeader,
unprotectedHeader,
ciphertext,
recipients
]
return encodeAsync(new Tagged(COSE_Encrypt_Tag, COSE_Encrypt), { canonical: true })
return encodeAsync(new Tagged(16, COSE_Encrypt0), { canonical: true })
}


export const encrypt = {
direct: encryptDirect,
wrap: encryptWrap
}


export const decryptWrap = async (req: RequestWrapDecryption) => {
const decoded = await decodeFirst(req.ciphertext)
if (decoded.tag !== 96) {
Expand Down Expand Up @@ -264,28 +254,25 @@ export const decryptWrap = async (req: RequestWrapDecryption) => {

export const decryptDirect = async (req: RequestDirectDecryption) => {
const decoded = await decodeFirst(req.ciphertext)
if (decoded.tag !== 96) {
throw new Error('Only tag 96 cose encrypt are supported')
if (decoded.tag !== 16) {
throw new Error('Only tag 16 cose encrypt are supported')
}
const [protectedHeader, unprotectedHeader, ciphertext, recipients] = decoded.value
const [recipient] = recipients

const [recipientProtectedHeader, recipientUnprotectedHeader, recipientCipherText] = recipient
const kid = recipientUnprotectedHeader.get(4).toString();
const [protectedHeader, unprotectedHeader, ciphertext] = decoded.value
const kid = unprotectedHeader.get(4).toString();
const receiverPrivateKeyJwk = req.recipients.keys.find((k) => {
return k.kid === kid
})
const decodedRecipientProtectedHeader = await decodeFirst(recipientProtectedHeader)
const recipientAlgorithm = decodedRecipientProtectedHeader.get(1)
const epk = recipientUnprotectedHeader.get(-1)

const recipientAlgorithm = unprotectedHeader.get(1)
const epk = unprotectedHeader.get(-1)
// ensure the epk has the algorithm that is set in the protected header
epk.set(3, recipientAlgorithm) // EPK is allowed to have an alg
const suite = suites[receiverPrivateKeyJwk.alg as JOSE_HPKE_ALG]
const hpkeRecipient = await suite.createRecipientContext({
recipientKey: await privateKeyFromJwk(receiverPrivateKeyJwk),
enc: epk.get(-1) // ek
})
const hpkeSealAad = computeHPKEAad(protectedHeader, recipientProtectedHeader, true)
const hpkeSealAad = computeHPKEAad(protectedHeader)
const plaintext = await hpkeRecipient.open(ciphertext, hpkeSealAad)
return plaintext
}
Expand Down
6 changes: 3 additions & 3 deletions src/cose/encrypt/wrap.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,6 @@ import * as hpke from './hpke'

export const decrypt = async (req: RequestWrapDecryption) => {
const decoded = await decodeFirst(req.ciphertext)
if (decoded.tag !== 96) {
throw new Error('Only tag 96 cose encrypt are supported')
}
const [protectedHeader, unprotectedHeader, ciphertext, recipients] = decoded.value
const [recipient] = recipients
const [recipientProtectedHeader, recipientUnprotectedHeader, recipientCipherText] = recipient
Expand All @@ -26,6 +23,9 @@ export const decrypt = async (req: RequestWrapDecryption) => {
if (receiverPrivateKeyJwk.alg === 'HPKE-Base-P256-SHA256-AES128GCM') {
return hpke.decrypt.wrap(req)
}
if (decoded.tag !== 96) {
throw new Error('Only tag 96 cose encrypt are supported')
}
const decodedRecipientProtectedHeader = await decodeFirst(recipientProtectedHeader)
const recipientAlgorithm = decodedRecipientProtectedHeader.get(1)
const epk = recipientUnprotectedHeader.get(-1)
Expand Down
2 changes: 1 addition & 1 deletion test/hpke.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ it('direct', async () => {
}
})
const decoded = transmute.cbor.decodeFirstSync(ct);
expect(decoded.tag).toBe(96)
expect(decoded.tag).toBe(16)
const decrypted = await transmute.decrypt.direct({
ciphertext: ct,
recipients: {
Expand Down

0 comments on commit 93a4bef

Please sign in to comment.