Skip to content

Commit

Permalink
More cleanup
Browse files Browse the repository at this point in the history
  • Loading branch information
OR13 committed Aug 24, 2024
1 parent e7a630e commit e11d389
Show file tree
Hide file tree
Showing 12 changed files with 32 additions and 28 deletions.
6 changes: 4 additions & 2 deletions src/cose/key/generate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -19,6 +20,7 @@ import { thumbprint } from "./thumbprint"
import { formatJwk } from './formatJwk'

import { iana } from '../../iana'
import { Key } from "../Params"

export const generate = async <T>(alg: CoseSignatureAlgorithms, contentType: PrivateKeyContentType = 'application/jwk+json'): Promise<T> => {
let knownAlgorithm = Object.values(IANACOSEAlgorithms).find((
Expand Down Expand Up @@ -47,7 +49,7 @@ export const generate = async <T>(alg: CoseSignatureAlgorithms, contentType: Pri
delete privateKeyJwk.kid;
const secretKeyCoseKey = await convertJsonWebKeyToCoseKey<CoseKey>(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.')
Expand Down
2 changes: 1 addition & 1 deletion src/cose/key/publicFromPrivate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ export const extractPublicCoseKey = (secretKey: CoseKey) => {
}

export const publicFromPrivate = <T>(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
Expand Down
2 changes: 1 addition & 1 deletion src/cose/key/serialize.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { CoseKey } from '.'

export const serialize = <T>(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)
Expand Down
5 changes: 3 additions & 2 deletions src/cose/receipt/add.ts
Original file line number Diff line number Diff line change
@@ -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<ArrayBuffer> => {
Expand All @@ -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 }));
}
6 changes: 3 additions & 3 deletions src/cose/receipt/consistency/issue.ts
Original file line number Diff line number Diff line change
@@ -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'
Expand All @@ -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')
}

Expand All @@ -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')
}

Expand Down
4 changes: 2 additions & 2 deletions src/cose/receipt/consistency/verify.ts
Original file line number Diff line number Diff line change
@@ -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"

Expand All @@ -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)
Expand Down
3 changes: 2 additions & 1 deletion src/cose/receipt/get.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { decodeFirstSync, Sign1Tag } from '../../cbor'
import { Receipts } from '../Params';
import { CoseSign1Bytes } from "../sign1";

export const get = async (signature: CoseSign1Bytes): Promise<CoseSign1Bytes[]> => {
Expand All @@ -10,6 +11,6 @@ export const get = async (signature: CoseSign1Bytes): Promise<CoseSign1Bytes[]>
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
}
4 changes: 2 additions & 2 deletions src/cose/receipt/inclusion/issue.ts
Original file line number Diff line number Diff line change
@@ -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"

Expand All @@ -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)
Expand Down
4 changes: 2 additions & 2 deletions src/cose/receipt/inclusion/verify.ts
Original file line number Diff line number Diff line change
@@ -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"

Expand All @@ -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)
Expand Down
2 changes: 1 addition & 1 deletion src/cose/sign1/hashEnvelopeSigner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export const hash = {
sign: async ({ protectedHeader, unprotectedHeader, payload }: RequestCoseSign1): Promise<Uint8Array> => {
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)
Expand Down
1 change: 1 addition & 0 deletions src/cose/sign1/verifier.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
21 changes: 10 additions & 11 deletions src/x509/certificate.ts
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -34,6 +27,11 @@ const algTowebCryptoParams: Record<CoseSignatureAlgorithms, { name: string, hash
hash: "SHA-256",
namedCurve: "P-256",
},
'ESP384': {
name: "ECDSA",
hash: "SHA-384",
namedCurve: "P-384",
},
'ES256': {
name: "ECDSA",
hash: "SHA-256",
Expand All @@ -57,12 +55,13 @@ export type RequestRootCertificate = {
iss: string
nbf: string
exp: string
serial: string
}

// https://datatracker.ietf.org/doc/html/rfc9360#section-2-5.6.1
const thumbprint = async (cert: string): Promise<[number, ArrayBuffer]> => {
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 }
Expand All @@ -78,7 +77,7 @@ const root = async (req: RequestRootCertificate): Promise<RootCertificateRespons
const webCryptoAlgorithm = algTowebCryptoParams[req.alg]
const caKeys = await crypto.subtle.generateKey(webCryptoAlgorithm, extractable, ["sign", "verify"]);
const caCert = await x509.X509CertificateGenerator.create({
serialNumber: "01",
serialNumber: req.serial || "01",
subject: req.sub,
issuer: req.iss,
notBefore: new Date(req.nbf),
Expand Down

0 comments on commit e11d389

Please sign in to comment.