diff --git a/src/cose/key/generate.ts b/src/cose/key/generate.ts index 26d85fd..69f155b 100644 --- a/src/cose/key/generate.ts +++ b/src/cose/key/generate.ts @@ -6,8 +6,9 @@ import { IANACOSEAlgorithms } from "../algorithms" import { CoseKey } from '.' + export type CoseKeyAgreementAlgorithms = 'ECDH-ES+A128KW' -export type CoseSignatureAlgorithms = 'ES256' | 'ES384' | 'ES512' | 'ESP256' +export type CoseSignatureAlgorithms = 'ES256' | 'ES384' | 'ES512' | 'ESP256' | 'ESP384' export type ContentTypeOfJsonWebKey = 'application/jwk+json' export type ContentTypeOfCoseKey = 'application/cose-key' export type PrivateKeyContentType = ContentTypeOfCoseKey | ContentTypeOfJsonWebKey @@ -19,6 +20,7 @@ import { thumbprint } from "./thumbprint" import { formatJwk } from './formatJwk' import { iana } from '../../iana' +import { Key } from "../Params" export const generate = async (alg: CoseSignatureAlgorithms, contentType: PrivateKeyContentType = 'application/jwk+json'): Promise => { let knownAlgorithm = Object.values(IANACOSEAlgorithms).find(( @@ -47,7 +49,7 @@ export const generate = async (alg: CoseSignatureAlgorithms, contentType: Pri delete privateKeyJwk.kid; const secretKeyCoseKey = await convertJsonWebKeyToCoseKey(privateKeyJwk) const coseKeyThumbprint = await thumbprint.calculateCoseKeyThumbprint(secretKeyCoseKey) - secretKeyCoseKey.set(2, coseKeyThumbprint) + secretKeyCoseKey.set(Key.Kid, coseKeyThumbprint) return secretKeyCoseKey as T } throw new Error('Unsupported content type.') diff --git a/src/cose/key/publicFromPrivate.ts b/src/cose/key/publicFromPrivate.ts index 63eaf2d..a3eae73 100644 --- a/src/cose/key/publicFromPrivate.ts +++ b/src/cose/key/publicFromPrivate.ts @@ -25,7 +25,7 @@ export const extractPublicCoseKey = (secretKey: CoseKey) => { } export const publicFromPrivate = (secretKey: PrivateKeyJwk | CoseKey) => { - if ((secretKey as any).kty) { + if ((secretKey as PrivateKeyJwk).kty) { return extractPublicKeyJwk(secretKey as PrivateKeyJwk) as T } return extractPublicCoseKey(secretKey as CoseKey) as T diff --git a/src/cose/key/serialize.ts b/src/cose/key/serialize.ts index aa509ee..bc5e4e3 100644 --- a/src/cose/key/serialize.ts +++ b/src/cose/key/serialize.ts @@ -5,7 +5,7 @@ import { CoseKey } from '.' export const serialize = (key: JWK | CoseKey) => { // eslint-disable-next-line @typescript-eslint/no-explicit-any - if ((key as any).kty) { + if ((key as JWK).kty) { return JSON.stringify(key, null, 2) } return encode(key) diff --git a/src/cose/receipt/add.ts b/src/cose/receipt/add.ts index c7bd351..07468c4 100644 --- a/src/cose/receipt/add.ts +++ b/src/cose/receipt/add.ts @@ -1,4 +1,5 @@ import { decodeFirstSync, toArrayBuffer, encodeAsync, Tagged, Sign1Tag } from '../../cbor' +import { Receipts } from '../Params'; import { CoseSign1Bytes } from "../sign1"; export const add = async (signature: CoseSign1Bytes, receipt: CoseSign1Bytes): Promise => { @@ -10,8 +11,8 @@ export const add = async (signature: CoseSign1Bytes, receipt: CoseSign1Bytes): P value[1] = new Map(); } // unprotected header - const receipts = value[1].get(394) || []; // see https://datatracker.ietf.org/doc/draft-ietf-scitt-architecture/ + const receipts = value[1].get(Receipts) || []; // see https://datatracker.ietf.org/doc/draft-ietf-scitt-architecture/ receipts.push(receipt) - value[1].set(394, receipts) + value[1].set(Receipts, receipts) return toArrayBuffer(await encodeAsync(new Tagged(Sign1Tag, value), { canonical: true })); } \ No newline at end of file diff --git a/src/cose/receipt/consistency/issue.ts b/src/cose/receipt/consistency/issue.ts index dd60a62..2142217 100644 --- a/src/cose/receipt/consistency/issue.ts +++ b/src/cose/receipt/consistency/issue.ts @@ -1,7 +1,7 @@ import { CoMETRE } from '@transmute/rfc9162' -import { cbor, Protected, Unprotected, VerifiableDataProofTypes } from '../../..' +import { cbor, Protected, Unprotected, VerifiableDataProofTypes, VerifiableDataStructures } from '../../..' import { CoseSign1Bytes, CoseSign1Signer, ProtectedHeaderMap } from "../../sign1" import { toArrayBuffer } from '../../../cbor' @@ -16,7 +16,7 @@ export type RequestIssueConsistencyReceipt = { export const issue = async (req: RequestIssueConsistencyReceipt) => { const { protectedHeader, receipt, entries, signer } = req; const consistencyVds = protectedHeader.get(Protected.VerifiableDataStructure) - if (consistencyVds !== 1) { + if (consistencyVds !== VerifiableDataStructures['RFC9162-Binary-Merkle-Tree']) { throw new Error('Unsupported verifiable data structure. See https://datatracker.ietf.org/doc/draft-ietf-cose-merkle-tree-proofs') } @@ -28,7 +28,7 @@ export const issue = async (req: RequestIssueConsistencyReceipt) => { const [protectedHeaderBytes, unprotectedHeaderMap, payload] = value const receiptProtectedHeader = cbor.decode(protectedHeaderBytes) const inclusionVds = receiptProtectedHeader.get(Protected.VerifiableDataStructure); - if (inclusionVds !== 1) { + if (inclusionVds !== VerifiableDataStructures['RFC9162-Binary-Merkle-Tree']) { throw new Error('Unsupported verifiable data structure. See https://datatracker.ietf.org/doc/draft-ietf-cose-merkle-tree-proofs') } diff --git a/src/cose/receipt/consistency/verify.ts b/src/cose/receipt/consistency/verify.ts index 2aa0081..29f57c7 100644 --- a/src/cose/receipt/consistency/verify.ts +++ b/src/cose/receipt/consistency/verify.ts @@ -1,7 +1,7 @@ import { CoMETRE } from '@transmute/rfc9162' -import { cbor, Protected, Unprotected, VerifiableDataProofTypes } from '../../..' +import { cbor, Protected, Unprotected, VerifiableDataProofTypes, VerifiableDataStructures } from '../../..' import { CoseSign1Bytes, CoseSign1DetachedVerifier } from "../../sign1" @@ -21,7 +21,7 @@ export const verify = async (req: RequestVerifyConsistencyReceipt) => { const [protectedHeaderBytes, unprotectedHeaderMap, payload] = value const protectedHeader = cbor.decode(protectedHeaderBytes) const vds = protectedHeader.get(Protected.VerifiableDataStructure); - if (vds !== 1) { + if (vds !== VerifiableDataStructures['RFC9162-Binary-Merkle-Tree']) { throw new Error('Unsupported verifiable data structure. See https://datatracker.ietf.org/doc/draft-ietf-cose-merkle-tree-proofs') } const proofs = unprotectedHeaderMap.get(Unprotected.VerifiableDataProofs) diff --git a/src/cose/receipt/get.ts b/src/cose/receipt/get.ts index fd2f91f..7ae264b 100644 --- a/src/cose/receipt/get.ts +++ b/src/cose/receipt/get.ts @@ -1,4 +1,5 @@ import { decodeFirstSync, Sign1Tag } from '../../cbor' +import { Receipts } from '../Params'; import { CoseSign1Bytes } from "../sign1"; export const get = async (signature: CoseSign1Bytes): Promise => { @@ -10,6 +11,6 @@ export const get = async (signature: CoseSign1Bytes): Promise return [] } // unprotected header - const receipts = value[1].get(394) || []; // see https://datatracker.ietf.org/doc/draft-ietf-scitt-architecture/ + const receipts = value[1].get(Receipts) || []; // see https://datatracker.ietf.org/doc/draft-ietf-scitt-architecture/ return receipts } \ No newline at end of file diff --git a/src/cose/receipt/inclusion/issue.ts b/src/cose/receipt/inclusion/issue.ts index 5bb0b8d..56fdda5 100644 --- a/src/cose/receipt/inclusion/issue.ts +++ b/src/cose/receipt/inclusion/issue.ts @@ -1,7 +1,7 @@ import { CoMETRE } from '@transmute/rfc9162' -import { cbor, Protected, Unprotected, VerifiableDataProofTypes } from '../../..' +import { cbor, Protected, Unprotected, VerifiableDataProofTypes, VerifiableDataStructures } from '../../..' import { CoseSign1Signer, ProtectedHeaderMap } from "../../sign1" @@ -15,7 +15,7 @@ export type RequestIssueInclusionReceipt = { export const issue = async (req: RequestIssueInclusionReceipt) => { const { protectedHeader, entry, entries, signer } = req; const vds = protectedHeader.get(Protected.VerifiableDataStructure) - if (vds !== 1) { + if (vds !== VerifiableDataStructures['RFC9162-Binary-Merkle-Tree']) { throw new Error('Unsupported verifiable data structure. See https://datatracker.ietf.org/doc/draft-ietf-cose-merkle-tree-proofs') } const root = await CoMETRE.RFC9162_SHA256.root(entries) diff --git a/src/cose/receipt/inclusion/verify.ts b/src/cose/receipt/inclusion/verify.ts index d49c4f6..4fd14d2 100644 --- a/src/cose/receipt/inclusion/verify.ts +++ b/src/cose/receipt/inclusion/verify.ts @@ -1,7 +1,7 @@ import { CoMETRE } from '@transmute/rfc9162' -import { cbor, Protected, Unprotected, VerifiableDataProofTypes } from '../../..' +import { cbor, Protected, Unprotected, VerifiableDataProofTypes, VerifiableDataStructures } from '../../..' import { CoseSign1Bytes, CoseSign1DetachedVerifier } from "../../sign1" @@ -20,7 +20,7 @@ export const verify = async (req: RequestVerifyInclusionReceipt) => { const [protectedHeaderBytes, unprotectedHeaderMap, payload] = value const protectedHeader = cbor.decode(protectedHeaderBytes) const vds = protectedHeader.get(Protected.VerifiableDataStructure); - if (vds !== 1) { + if (vds !== VerifiableDataStructures['RFC9162-Binary-Merkle-Tree']) { throw new Error('Unsupported verifiable data structure. See https://datatracker.ietf.org/doc/draft-ietf-cose-merkle-tree-proofs') } const proofs = unprotectedHeaderMap.get(Unprotected.VerifiableDataProofs) diff --git a/src/cose/sign1/hashEnvelopeSigner.ts b/src/cose/sign1/hashEnvelopeSigner.ts index 9e20067..975d877 100644 --- a/src/cose/sign1/hashEnvelopeSigner.ts +++ b/src/cose/sign1/hashEnvelopeSigner.ts @@ -14,7 +14,7 @@ export const hash = { sign: async ({ protectedHeader, unprotectedHeader, payload }: RequestCoseSign1): Promise => { const subtle = await subtleCryptoProvider(); const hashEnvelopeAlgorithm = protectedHeader.get(Protected.PayloadHashAlgorithm) - if (hashEnvelopeAlgorithm !== -Hash.SHA256) { + if (hashEnvelopeAlgorithm !== Hash.SHA256) { throw new Error('Unsupported hash envelope algorithm (-16 is only one supported)') } const payloadHash = await subtle.digest("SHA-256", payload) diff --git a/src/cose/sign1/verifier.ts b/src/cose/sign1/verifier.ts index 8aa3fc8..7bfc309 100644 --- a/src/cose/sign1/verifier.ts +++ b/src/cose/sign1/verifier.ts @@ -22,6 +22,7 @@ const verifier = ({ resolver }: RequestCoseSign1Verifier) => { if (signatureStructure.length !== 4) { throw new Error('Expecting Array of length 4'); } + // eslint-disable-next-line @typescript-eslint/no-unused-vars const [protectedHeaderBytes, _, payload, signature] = signatureStructure; const protectedHeaderMap: ProtectedHeaderMap = (!protectedHeaderBytes.length) ? new Map() : decodeFirstSync(protectedHeaderBytes); const algInHeader = protectedHeaderMap.get(Protected.Alg) diff --git a/src/x509/certificate.ts b/src/x509/certificate.ts index b87cded..5be4798 100644 --- a/src/x509/certificate.ts +++ b/src/x509/certificate.ts @@ -1,15 +1,8 @@ import { exportJWK, exportPKCS8, importPKCS8 } from 'jose'; -import { ProtectedHeaderMap, PublicKeyJwk } from "../cose/sign1" - +import { PublicKeyJwk } from "../cose/sign1" import * as x509 from "@peculiar/x509"; - import { CoseSignatureAlgorithms } from '../cose/key'; - -import { IANACOSEAlgorithms, PrivateKeyJwk, detached, RequestCoseSign1VerifyDetached } from '..'; - - -import { decodeFirstSync } from '../cbor' - +import { IANACOSEAlgorithms, PrivateKeyJwk, detached, RequestCoseSign1VerifyDetached, Hash } from '..'; import { crypto } from '..'; // eslint-disable-next-line @typescript-eslint/no-empty-function @@ -34,6 +27,11 @@ const algTowebCryptoParams: Record => { const current = new x509.X509Certificate(cert) - return [-16, await current.getThumbprint('SHA-256')] + return [Hash.SHA256, await current.getThumbprint('SHA-256')] } export type RootCertificateResponse = { public: string, private: string } @@ -78,7 +77,7 @@ const root = async (req: RequestRootCertificate): Promise