From 76738995dcc8d1e76fb5295c1d3fe4c70876ca74 Mon Sep 17 00:00:00 2001 From: Marco Munizaga Date: Thu, 3 Aug 2023 16:16:05 -0700 Subject: [PATCH 1/3] Limit RSA key size --- packages/crypto/src/keys/rsa-browser.ts | 14 ++++++++++++++ packages/crypto/src/keys/rsa-class.ts | 24 ++++++++++++++++++++++++ packages/crypto/src/keys/rsa.ts | 10 ++++++++++ packages/crypto/test/keys/rsa.spec.ts | 23 ++++++++++++++++++++++- 4 files changed, 70 insertions(+), 1 deletion(-) diff --git a/packages/crypto/src/keys/rsa-browser.ts b/packages/crypto/src/keys/rsa-browser.ts index 193913aa9a..8288a2fe25 100644 --- a/packages/crypto/src/keys/rsa-browser.ts +++ b/packages/crypto/src/keys/rsa-browser.ts @@ -155,3 +155,17 @@ export function encrypt (key: JsonWebKey, msg: Uint8Array): Uint8Array { export function decrypt (key: JsonWebKey, msg: Uint8Array): Uint8Array { return convertKey(key, false, msg, (msg, key) => key.decrypt(msg)) } + +export function keySize (jwk: JsonWebKey) { + if (jwk.kty !== 'RSA') { + throw new CodeError('invalid key type', 'ERR_INVALID_KEY_TYPE') + } else if (jwk.n == null) { + throw new CodeError('invalid key modulus', 'ERR_INVALID_KEY_MODULUS') + } + let n = jwk.n + // Replace base64url characters with base64 characters + n = n.replace(/-/g, '+').replace(/_/g, '/'); + const binString = atob(n); + const bytes = Uint8Array.from(binString, (m) => m.codePointAt(0) as number); + return bytes.length * 8; +} diff --git a/packages/crypto/src/keys/rsa-class.ts b/packages/crypto/src/keys/rsa-class.ts index 83582db8a4..5e378f3614 100644 --- a/packages/crypto/src/keys/rsa-class.ts +++ b/packages/crypto/src/keys/rsa-class.ts @@ -10,6 +10,8 @@ import * as pbm from './keys.js' import * as crypto from './rsa.js' import type { Multibase } from 'multiformats' +var maxKeySize = 8192 + export class RsaPublicKey { private readonly _key: JsonWebKey @@ -135,21 +137,43 @@ export class RsaPrivateKey { export async function unmarshalRsaPrivateKey (bytes: Uint8Array): Promise { const jwk = crypto.utils.pkcs1ToJwk(bytes) + if (crypto.keySize(jwk) > maxKeySize) { + throw new CodeError('key size is too large', 'ERR_KEY_SIZE_TOO_LARGE') + } const keys = await crypto.unmarshalPrivateKey(jwk) return new RsaPrivateKey(keys.privateKey, keys.publicKey) } export function unmarshalRsaPublicKey (bytes: Uint8Array): RsaPublicKey { const jwk = crypto.utils.pkixToJwk(bytes) + if (crypto.keySize(jwk) > maxKeySize) { + throw new CodeError('key size is too large', 'ERR_KEY_SIZE_TOO_LARGE') + } return new RsaPublicKey(jwk) } export async function fromJwk (jwk: JsonWebKey): Promise { const keys = await crypto.unmarshalPrivateKey(jwk) + if (crypto.keySize(jwk) > maxKeySize) { + throw new CodeError('key size is too large', 'ERR_KEY_SIZE_TOO_LARGE') + } return new RsaPrivateKey(keys.privateKey, keys.publicKey) } export async function generateKeyPair (bits: number): Promise { + if (bits > maxKeySize) { + throw new CodeError('key size is too large', 'ERR_KEY_SIZE_TOO_LARGE') + } const keys = await crypto.generateKey(bits) return new RsaPrivateKey(keys.privateKey, keys.publicKey) } + +// Overrides the maximum key size for RSA keys. Only useful for tests. Returns a +// function the resets the value. +export function overrideMaxKeySize (size: number): () => void { + const original = maxKeySize + maxKeySize = size + return () => { + maxKeySize = original + } +} diff --git a/packages/crypto/src/keys/rsa.ts b/packages/crypto/src/keys/rsa.ts index a2411ef382..7afd167415 100644 --- a/packages/crypto/src/keys/rsa.ts +++ b/packages/crypto/src/keys/rsa.ts @@ -67,3 +67,13 @@ export function decrypt (key: JsonWebKey, bytes: Uint8Array): Uint8Array { // @ts-expect-error node types are missing jwk as a format return crypto.privateDecrypt({ format: 'jwk', key, padding }, bytes) } + +export function keySize (jwk: JsonWebKey) { + if (jwk.kty !== 'RSA') { + throw new CodeError('invalid key type', 'ERR_INVALID_KEY_TYPE') + } else if (jwk.n == null) { + throw new CodeError('invalid key modulus', 'ERR_INVALID_KEY_MODULUS') + } + const modulus = Buffer.from(jwk.n, 'base64'); + return modulus.length * 8; +} diff --git a/packages/crypto/test/keys/rsa.spec.ts b/packages/crypto/test/keys/rsa.spec.ts index 27c9740b54..fcb215d5ce 100644 --- a/packages/crypto/test/keys/rsa.spec.ts +++ b/packages/crypto/test/keys/rsa.spec.ts @@ -3,7 +3,8 @@ import { expect } from 'aegir/chai' import { fromString as uint8ArrayFromString } from 'uint8arrays/from-string' import * as crypto from '../../src/index.js' -import { RsaPrivateKey } from '../../src/keys/rsa-class.js' +import { RsaPrivateKey, RsaPublicKey, overrideMaxKeySize } from '../../src/keys/rsa-class.js' +import * as rsaCrypto from '../../src/keys/rsa.js' import fixtures from '../fixtures/go-key-rsa.js' import { testGarbage } from '../helpers/test-garbage-error-handling.js' @@ -25,6 +26,26 @@ describe('RSA', function () { expect(digest).to.have.length(34) }) + it('Does not generate a big key', async () => { + await expect(rsa.generateKeyPair(8193)).to.be.rejected() + }) + + it('Does not unmarshal a big key', async () => { + const reset = overrideMaxKeySize(4096-8) + try { + const k = await rsaCrypto.generateKey(4096) + const sk = new RsaPrivateKey(k.privateKey, k.publicKey) + const pubk = new RsaPublicKey(k.publicKey) + const m = sk.marshal() + const pubm = pubk.marshal() + await expect(rsa.unmarshalRsaPrivateKey(m)).to.be.rejectedWith(/too large/) + expect(() => rsa.unmarshalRsaPublicKey(pubm)).to.throw(/too large/) + await expect(rsa.fromJwk(k.privateKey)).to.be.rejectedWith(/too large/) + } finally { + reset() + } + }) + it('signs', async () => { const text = key.genSecret() const sig = await key.sign(text) From 35afa27c73b2acc2d261d2f6d330240abb676ac3 Mon Sep 17 00:00:00 2001 From: Marco Munizaga Date: Thu, 3 Aug 2023 16:22:19 -0700 Subject: [PATCH 2/3] Lint fix --- packages/crypto/src/keys/rsa-browser.ts | 10 +++++----- packages/crypto/src/keys/rsa-class.ts | 2 +- packages/crypto/src/keys/rsa.ts | 6 +++--- packages/crypto/test/keys/rsa.spec.ts | 6 +++--- 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/packages/crypto/src/keys/rsa-browser.ts b/packages/crypto/src/keys/rsa-browser.ts index 8288a2fe25..327211ca4f 100644 --- a/packages/crypto/src/keys/rsa-browser.ts +++ b/packages/crypto/src/keys/rsa-browser.ts @@ -156,7 +156,7 @@ export function decrypt (key: JsonWebKey, msg: Uint8Array): Uint8Array { return convertKey(key, false, msg, (msg, key) => key.decrypt(msg)) } -export function keySize (jwk: JsonWebKey) { +export function keySize (jwk: JsonWebKey): number { if (jwk.kty !== 'RSA') { throw new CodeError('invalid key type', 'ERR_INVALID_KEY_TYPE') } else if (jwk.n == null) { @@ -164,8 +164,8 @@ export function keySize (jwk: JsonWebKey) { } let n = jwk.n // Replace base64url characters with base64 characters - n = n.replace(/-/g, '+').replace(/_/g, '/'); - const binString = atob(n); - const bytes = Uint8Array.from(binString, (m) => m.codePointAt(0) as number); - return bytes.length * 8; + n = n.replace(/-/g, '+').replace(/_/g, '/') + const binString = atob(n) + const bytes = Uint8Array.from(binString, (m) => m.codePointAt(0) as number) + return bytes.length * 8 } diff --git a/packages/crypto/src/keys/rsa-class.ts b/packages/crypto/src/keys/rsa-class.ts index 5e378f3614..067069d6db 100644 --- a/packages/crypto/src/keys/rsa-class.ts +++ b/packages/crypto/src/keys/rsa-class.ts @@ -10,7 +10,7 @@ import * as pbm from './keys.js' import * as crypto from './rsa.js' import type { Multibase } from 'multiformats' -var maxKeySize = 8192 +let maxKeySize = 8192 export class RsaPublicKey { private readonly _key: JsonWebKey diff --git a/packages/crypto/src/keys/rsa.ts b/packages/crypto/src/keys/rsa.ts index 7afd167415..1d43afc925 100644 --- a/packages/crypto/src/keys/rsa.ts +++ b/packages/crypto/src/keys/rsa.ts @@ -68,12 +68,12 @@ export function decrypt (key: JsonWebKey, bytes: Uint8Array): Uint8Array { return crypto.privateDecrypt({ format: 'jwk', key, padding }, bytes) } -export function keySize (jwk: JsonWebKey) { +export function keySize (jwk: JsonWebKey): number { if (jwk.kty !== 'RSA') { throw new CodeError('invalid key type', 'ERR_INVALID_KEY_TYPE') } else if (jwk.n == null) { throw new CodeError('invalid key modulus', 'ERR_INVALID_KEY_MODULUS') } - const modulus = Buffer.from(jwk.n, 'base64'); - return modulus.length * 8; + const modulus = Buffer.from(jwk.n, 'base64') + return modulus.length * 8 } diff --git a/packages/crypto/test/keys/rsa.spec.ts b/packages/crypto/test/keys/rsa.spec.ts index fcb215d5ce..f82cacadf1 100644 --- a/packages/crypto/test/keys/rsa.spec.ts +++ b/packages/crypto/test/keys/rsa.spec.ts @@ -31,11 +31,11 @@ describe('RSA', function () { }) it('Does not unmarshal a big key', async () => { - const reset = overrideMaxKeySize(4096-8) + const reset = overrideMaxKeySize(4096 - 8) try { const k = await rsaCrypto.generateKey(4096) - const sk = new RsaPrivateKey(k.privateKey, k.publicKey) - const pubk = new RsaPublicKey(k.publicKey) + const sk = new RsaPrivateKey(k.privateKey, k.publicKey) + const pubk = new RsaPublicKey(k.publicKey) const m = sk.marshal() const pubm = pubk.marshal() await expect(rsa.unmarshalRsaPrivateKey(m)).to.be.rejectedWith(/too large/) From 8073158eed9161e115dfb303ad9818fe7020fbdf Mon Sep 17 00:00:00 2001 From: achingbrain Date: Fri, 4 Aug 2023 12:28:57 +0100 Subject: [PATCH 3/3] fix: small edits for behaviour and consistency - Make max key size a const - Export max key size - Add a fixuture with a key bigger than max key size - Remove ability to override max key size (since if it's exported it becomes part of the documented API) - Ensure we check the max key size before doing any async work - Use uint8arrays/from-string to decode base64url instead of rolling our own - Minor edits to test names to make them consistent with the others --- packages/crypto/src/keys/rsa-browser.ts | 6 +---- packages/crypto/src/keys/rsa-class.ts | 31 +++++++++++----------- packages/crypto/test/fixtures/rsa.ts | 23 +++++++++++++++++ packages/crypto/test/keys/rsa.spec.ts | 34 ++++++++++--------------- 4 files changed, 53 insertions(+), 41 deletions(-) create mode 100644 packages/crypto/test/fixtures/rsa.ts diff --git a/packages/crypto/src/keys/rsa-browser.ts b/packages/crypto/src/keys/rsa-browser.ts index 327211ca4f..2f0e0c04b1 100644 --- a/packages/crypto/src/keys/rsa-browser.ts +++ b/packages/crypto/src/keys/rsa-browser.ts @@ -162,10 +162,6 @@ export function keySize (jwk: JsonWebKey): number { } else if (jwk.n == null) { throw new CodeError('invalid key modulus', 'ERR_INVALID_KEY_MODULUS') } - let n = jwk.n - // Replace base64url characters with base64 characters - n = n.replace(/-/g, '+').replace(/_/g, '/') - const binString = atob(n) - const bytes = Uint8Array.from(binString, (m) => m.codePointAt(0) as number) + const bytes = uint8ArrayFromString(jwk.n, 'base64url') return bytes.length * 8 } diff --git a/packages/crypto/src/keys/rsa-class.ts b/packages/crypto/src/keys/rsa-class.ts index 067069d6db..83640ca26b 100644 --- a/packages/crypto/src/keys/rsa-class.ts +++ b/packages/crypto/src/keys/rsa-class.ts @@ -10,7 +10,7 @@ import * as pbm from './keys.js' import * as crypto from './rsa.js' import type { Multibase } from 'multiformats' -let maxKeySize = 8192 +export const MAX_KEY_SIZE = 8192 export class RsaPublicKey { private readonly _key: JsonWebKey @@ -137,43 +137,42 @@ export class RsaPrivateKey { export async function unmarshalRsaPrivateKey (bytes: Uint8Array): Promise { const jwk = crypto.utils.pkcs1ToJwk(bytes) - if (crypto.keySize(jwk) > maxKeySize) { + + if (crypto.keySize(jwk) > MAX_KEY_SIZE) { throw new CodeError('key size is too large', 'ERR_KEY_SIZE_TOO_LARGE') } + const keys = await crypto.unmarshalPrivateKey(jwk) + return new RsaPrivateKey(keys.privateKey, keys.publicKey) } export function unmarshalRsaPublicKey (bytes: Uint8Array): RsaPublicKey { const jwk = crypto.utils.pkixToJwk(bytes) - if (crypto.keySize(jwk) > maxKeySize) { + + if (crypto.keySize(jwk) > MAX_KEY_SIZE) { throw new CodeError('key size is too large', 'ERR_KEY_SIZE_TOO_LARGE') } + return new RsaPublicKey(jwk) } export async function fromJwk (jwk: JsonWebKey): Promise { - const keys = await crypto.unmarshalPrivateKey(jwk) - if (crypto.keySize(jwk) > maxKeySize) { + if (crypto.keySize(jwk) > MAX_KEY_SIZE) { throw new CodeError('key size is too large', 'ERR_KEY_SIZE_TOO_LARGE') } + + const keys = await crypto.unmarshalPrivateKey(jwk) + return new RsaPrivateKey(keys.privateKey, keys.publicKey) } export async function generateKeyPair (bits: number): Promise { - if (bits > maxKeySize) { + if (bits > MAX_KEY_SIZE) { throw new CodeError('key size is too large', 'ERR_KEY_SIZE_TOO_LARGE') } + const keys = await crypto.generateKey(bits) - return new RsaPrivateKey(keys.privateKey, keys.publicKey) -} -// Overrides the maximum key size for RSA keys. Only useful for tests. Returns a -// function the resets the value. -export function overrideMaxKeySize (size: number): () => void { - const original = maxKeySize - maxKeySize = size - return () => { - maxKeySize = original - } + return new RsaPrivateKey(keys.privateKey, keys.publicKey) } diff --git a/packages/crypto/test/fixtures/rsa.ts b/packages/crypto/test/fixtures/rsa.ts new file mode 100644 index 0000000000..2f941850bd --- /dev/null +++ b/packages/crypto/test/fixtures/rsa.ts @@ -0,0 +1,23 @@ +import type { JWKKeyPair } from '../../src/keys/interface' + +/** + * A 8200 bit RSA key + */ +export const RSA_KEY_8200_BITS: JWKKeyPair = { + privateKey: { + kty: 'RSA', + n: 'AtSHgbWZ-5MHNh8LpVD4-2lOjLitwGjADZ8gEcs3EqskGl1E7Lna8oGRt6V-0yiGwicgNgWPVRW3M4aK8kXe9izb1O43I20A2QVfmZDZB7inS23hrj9PZs863x497-WMdiyBBa3SVrg0StU_vQ8iUFYi5ihQr0b58IKJhVHA6AhqpuUeCbbTakoH1btzOlfqWb6chlL2bT-1KY1EUSRN25Qrfk5T7wV59QvbkGMUuHJRreh6caTASf3cGEG6nk_2YXTiZ6Yyc5XzR0hNervbwa9WVPc19iCP9fNJ8T6oFmJsJ-T9MnEQqttDSOYGwhnzleV4FWrv0jiWhC1-LMdJ-rdHVXPUH9pKArXwWu1FZBk8EG4o3uAB5rcxgk7Z_5sV3PAXQlAISZl3IwauWcDaWIgckDUU3AmzpdrddPn8IiqVtSpcTMISi2MkKJw1iom97iQk8V0dkPvCpFB1wzOoEJfL-gcl61ePeU5xohzy0eQcwjsGAtuK6XgT_TB_u7Q6_FbS0AwySISYz6JsnV-FHsb-0FMUjj6-jF0A3vb7El43xwZUrAhx7qqn_DuvrztjChsNWyE7dKWDceTwxIHDobEG7LDivMvsq-jkRYIzYoMJabrIzTgRjGBLruxBp8Zl1CuOepD4vFO6JBzbZl5Qy0hrpuP9YAlYBg3sBhwsYcrATZWVYcNRkJDsNIo-lSFNOl8DalFm7IsxW0A6AMuysLzm4oLZe2hDrmfRI9Mh5JBgio8cKetZan-0pLpoU5ezcMdIszlaUC4ggbOa2h7wVZCanTO79VoeiZLIrCimL4hbtlegpiX6A792jaD5G-cmPhMRGqn2rZcbwIx61e1z3Lz_Wag4lc8I2UwSMFUaIFi67OWN9608JgNNv2-W2uj5NpTFNJSBGUO6gfdOt1C-dgAafhXyPyyQ9m1Uq_0JMwaOkqkkTjW5UNKBacx8Hi9S2AVX7Ln9DN2mNFtFZVCmpnS2qKwd53yhcGQWr_1QL3kshTH5-hkpnLr7ntWIf094NGClp9l5Y2BOB-NqO7JecD_3WHxzjh_3jx6yAiSc3FqX9zmNmiOyIlENc6GHDe10a6p3NNZkI3jTO6C6fQfzOFCQ544htxF7JvxahKLazpSIBRkbf7Hxgdo5s8p8kH5S8HTpl5hdCOsMveJjH0rYU801iTF7Sv5rqn_Zd9FGkT98mjhGl8O4fhEHd967-GR9KupALmG9LtfA2jKwipAcwxyhaXFg2hobCpSvHx9KLOW-3gQt93PqNoE9TAGyIlYbHBFyN3IDsH5bKDYkL4C7RlXUFogBq64SpljjXoW3gYmH2guEaXMwMLf7Mogaoi0Or4ubitxd8EvFuhH2W1TekVc', + e: 'AQAB', + d: 'o85TLBy5PR-XQ-OdJ7ZzGPbyZ9qYstYg_kYA3-H-rYTHFSk9IDP5OgQY8ii_Ut1Mzg3BSPaD9RnrY1LMvbFQFQpKlOUQdFeJuWZI0O_QiBYCvsAUZinsg5O62BqGv25HVX6CKy9v_cuM07PKab6HTUIsqRa82h4uG0U-SCKGE0kRnKFy7svTrxMgZnYBzdilG6xFzkH6pzmtQEwe0EduCozezJS7aJCPL3Qfq9cGcIo4-GOeh_IViHiXX1zy5_87P3LknjWv3koXZqhlxE1F9_9bzFx93hTONYgVK-ZS0UPErUf1fIyZJGOM-ryya62fyTaiGQBJlhOppKNvOktmjMNq9XoTDYZIIJxL4nMa03259T32Tc0APZDK9krhOE30GrAXhQKqqTC_UYZfsnNrKrLSg73IlcTxDY-eH9q6WshoIkCl9ga9Ttfg-pg8TzIKwk875qKFofX6slo9nNM1lSw_xhfzomNEuNCGJ2davuklnLSaNsqsSEK0rp9ib7gaTwLwmKFRtfDamM1Xsz3knHcF4JK4KkVodKp6vno7R-PycmL4Vhx0Kk86fsAUrSeSJFWbseLAV59lQ66Prwrs5po7Ly7EIpLKtyfM80fs0NVy-xDlHPUSuL7DuJSLexaQppxa56Xk5kUiXwfXmCFKJIB6RfeGG_azv7gKFZqPLYgUBJf0yL-nSUa3SoqsS31SbHnFSGLs9Xb0IwX_450Z906Vrva-KNK6N5t4u_Q6S5ZcSrlho7zxcwrpGUWUuqcnuuAVv21qFbO7PshrWhvC_wkXdSrgisRwTxPwCR1OVZ5mTYdWBt5c2mZDVsxmdqLCMoupDOH75eI_FbxuHY82IiSWeWlKTC9Nn0EfXxiin5TuBKMXdJkGLujD66TAkoORG6-E4yx-yQYBD_EuA2niSTmCOFn1H8GHItO0hkY8hd7WOM6PUM7bcJFIALMsCm--ya_-x-uwTU381mY9iliYFKw41GHmTEdA-04igfpjgsI9U5fzLxMYi7ku2fI_NmRtWznY6QU51GxZ9gWnKEVgneowI9fWxi-nAZ0Fl6CMSPSJhurKPAPXgIEYKA-V5ORbzTS5YKMMs5t05lVqSLdO00XBFjuyyeSqAP0X0b3Iy7o5v9S8TTOdKE9KnWR3zda7rwlT-pV_XVHegzclMcpNoRZu68mYIK5r40_mQJfygQBoRpqUyb2lvac3K4o4gVGH82i1YPscDZZvd9iqFAq3YpxutsJSuj3TsRGrYatq0xdgHA1mF1RE1_JN2x4FD2_5QAXLLoGwlLiz6-uhqBT6e3aDNChD8aIFDP88WD7KMjUbzheqt1w2Ym4TMnszfkPru4I45ObIOiN7AoDIwFjOuQ', + p: 'Aa5Enbkyn0LpdzDYDmoxJx3bIrhaZ-lINx0eJTqSsjCLtdoV53Ya1dZOPFNY0z1yF1ckL81M7CiTLzetlzqERK-y13yWe194yti8IFtmyA53eAAx4xB70fpL0dIfXvLHar5456UdeaaQkUYm2xAxaQ5SYYwHMOJoMt-SaLq-WSD6d8ej6dtcBjKfX6vnlZGeeVBQUfSuYYO5gMFTlBqvgltkvWJ-FJjfQtHXDM7mooC3RO6hjiGvbpkzAQVj5fR6tZNoeN-Cb7IW0BWQ01UWdJeutl-4Mxn-1byFBgP1Na801yVNpLR-bE145BwfrZVAUVMqPaskcthClhIHCr3NrDGyp06xfONPUyxTmntQvTD9S6fyOzqoxBLz-vB91eDjeZPvt0ULPtZQx9thfLUzxt_fI_uiqVEeh8NEfco442OVij1ciJvREap5mSFzbj_GzLWsZOxUdB65T-1PzXizcMvUIThzLlxJhgpfEEIUC7hOPKjBDTMImrQbFoXJXCiuxy-PGj79ORvbSH5klM3T90KMSoWg_sUozP_fUcUCFAnQEOWHT3-CROzjhox8T5CLzpYUW2BTKCAFm9CMmRTZsDl8y7PhiXmTB3imQRN9Sc7pTTVsj_kYKgaOHOc7Rzuwb3KVDsHAkSBvPPatZJkvLktt-wTxYFXpz772L6EzuGdd', + q: 'Aa8UOGhm4KQPVD8gQ29WMjUEoDy3otlOI-fQvI6haOX73SI-8gkuG2U70DVWD08yUQMpCGEpJ5dykhrtXC5xruGqIySkO6RousTB2uad6TIpUpn_GCbbaf_Hb2T_dXJd7cX06cTIf78vXC_o1fWuODAGG-k6uit0mrvC8l69MEQ2CL5Dr29sH6DyNXyhw8NnG45sRIcjiwXyHlrmSJUlrd_HcHXU0JK_2gMyaXB_rFnazDShJ2Td7bRRPUmlVvWQgZ-X8Rw6jL0Zfy4Vsp7yaYnLbi1GKjb-13r1GpAm1ECAVH13jDW8rpM608v2tN-fgYG3eh9SUX5cjNQ6tyqGje_abXl3og4t7wzvLCXwhb5L5nMDrk2XQrzZWuhQBlcYoaLlaks7w6DK9eq_T4JNywtB7PuRMYMOHaQ_p54xzz0PH2ZhRTCCitVoxLmt1S5Ib47DSDjmy4-9ghyluH0M5CfPo5IHY0SOBBG-JF0IpH_LIU5JEChVoKUXLBGoTH2pc5Wy4riFfgcVXmn1JPikAuw0IwQjgrOMvBj4BaN9H3z152pOSyxQeI9LBnWWXrDDtSve7ws4SKiuVmpGvp6S-zWDMw_9hIKoD5WQ5Z85LrJZhZJub9jfyaaz6YiGfh8p8tNSiBfqEN_lbKOLQzE9d7lsozqNMmsCXqmTlOlqZVRD', + dp: 'AaFreAifj9p-XN_J-9IR9X0Fh12Kd5zeLnnVMRDuGGj4YWg-L9tolWPfaq8BUY4fDX3A4Y8uvT1v7TL6-egPQgOiYWPBKdepfEFf4ZRK1nMSfBzUSRFIzqEgxWIwhRDLXkeDTFfnjImHXyjLsWK4TM9UJMaQg2Bi7lfv1iK1YAqac3H_F3V0hZ6-9zXy6ivnrpG4GopiUsBUSxFDYD-zXagEx6ax4pGcp1qkYwymu6hcJEfN-_G6HHYMAUWVcRYJpfZoODu-c1Y2w5Doe93kdyBgoxWhwhHKJNlLxFY6oeZkQQUzmkJxE-jlC4gtQ120lDE2nbVXGwOrNaQvqMAStKdSRvYVQq_T2UD7qrdP0PuiAK_iVIvIBtDMWfrOWZxfkyduPEKDcmbA3-N5ZF726E1wUZxiZhkIoXVTESYKoq-N-BsnlnB0F8tnRKQrNB4zY44svYx5Ml5MMbps3U3n59oW5lO5ipSFz8BoEYHJqMUZQcgF4iRMiKmKTgNlIj9lsF_3WOMbDzhzOJVGRwaYSR0KtZGGayQjPR5PLSkPpxkN_hZvezSc0PlwkqvgPeBhgf4fqbZ9dkP6rPtaK3kK5-gdphHREGodtfXadO_PcLeHpxvZQqPKSZsqa-f4nlbOCJEFAtf9Vc49nMtD1IC4QRV0kT5uXaN7vcvpUrP1VUUR', + dq: 'rdjbvs7ufXtpIGQkjfwXF2acMKBmXniy5kQ6JtNVeJqQXcVA2w7rIXJzz267kdba8QlVRcnRG7Sq040yBdD3FC8HKTnKi81otPzxCNxaNU6Q72X_GXyXTP3jILodZVgYEiNpO2EYk8PHy9J8py3xnvx3uSFj_y5xUJOYJzjpBDk-YWzujWLvhnrnszGRv3YPmOp04IMnB-jS8Rm539xoOL03z21aCDSy-WMVPrdejIY-oGL1fio6OOQicVbqsPHsNK6UICxEoeZscetyM8PTaCzQbBXF5JP11rKOWeAu7SxT5p2Vv_4t8VZiH_mIjD7JfcS-zW7nSqyMZvKe99l32GkgiUID6u__Xhn-lfZgGZSGhY_QdZ4w3fRSQyoyxGE8nnMi4OBjTq9LabZpnEU_Q3T82598djv1HE5HjPbNevRkV2eW_a9HyjUMUU2XkajIxKxgrgH1yixFEsSKmHPgd2W3s6ajE_yqC3XBOHvJy3fiIK46g-m0dZ_Yt-5FmtABuzd_U6cSYkzt3JFurY-HVjbYgEzJ4xs4qGEt9Pb7AewxvZ-BlYeGd1NscXOJEIR8xgqMINw8ATr9wrJxIYZpJPWaXDKDhCW-0zSyRfpLqMWNprY_CRmHO2GHJvYGWw8RzMOV-v78ey8NFw-Ms4j0haUYVv6mfJ1iC8Vm4pNz9f0', + qi: 'VWzU4gk0YHzmtUbU9IKfjGDgWaCY5H_hhUQ3oz9rK-WU1IOrrnpH8ltjLSlcvimpL_Nw2G3JxyY8A1IrsFrTgj6_wqexMEyia_j-62AxNtspt4-lHXbLGxvxv4KswKD88mvFdBloomxEcb5j32v_YX_gQfl6znJBR27dbeU8dyRmbH-WOyM8p9lunZRIbQ7UnSAIWlswN60XvNiqFjVrjAWB5rvAu_F0pAv_raWE46OqHFNBWncOsp2GGoNZa_hOsx_4ORaz3YO2qAqMCwkXpux-YJmAG3sXtzVnr7-dV3R7T5Rz-IkUJJMPwXnlW568j9-lH3xnNEQ8uwmaYFChMYTPUAoa2tF-YHwtvKaRUMuoCUwiqKdgNybtLsBewjbFygrJsiMiYjmmIMzwPGqJfVtXkosolHErGWoGCv19vASbNBwB31zE0GBBMculZ6vOYqq7YKN46MIcCvujxlAUdXyg4-3VoqgHBXYSPj0M2y1LeQ2YXtGWaX5i6g8coKdPcWg5gUu38H_J2RKJiyWYwei9nz3fLB_xsl7cS1a2Wfm30HMa_-wWgwb1XfzLRYQKVACu6yBU7-lx1tq0I2D6s8ufurJRjEj6Uu7NPxP3lmeS2FIxkfXDQkXiqpq2FZu4Bj6cV9BDnXVvBBBeNcqBrvnpFeX25IGGKMEyYn6s9UI' + }, + publicKey: { + kty: 'RSA', + n: 'AtSHgbWZ-5MHNh8LpVD4-2lOjLitwGjADZ8gEcs3EqskGl1E7Lna8oGRt6V-0yiGwicgNgWPVRW3M4aK8kXe9izb1O43I20A2QVfmZDZB7inS23hrj9PZs863x497-WMdiyBBa3SVrg0StU_vQ8iUFYi5ihQr0b58IKJhVHA6AhqpuUeCbbTakoH1btzOlfqWb6chlL2bT-1KY1EUSRN25Qrfk5T7wV59QvbkGMUuHJRreh6caTASf3cGEG6nk_2YXTiZ6Yyc5XzR0hNervbwa9WVPc19iCP9fNJ8T6oFmJsJ-T9MnEQqttDSOYGwhnzleV4FWrv0jiWhC1-LMdJ-rdHVXPUH9pKArXwWu1FZBk8EG4o3uAB5rcxgk7Z_5sV3PAXQlAISZl3IwauWcDaWIgckDUU3AmzpdrddPn8IiqVtSpcTMISi2MkKJw1iom97iQk8V0dkPvCpFB1wzOoEJfL-gcl61ePeU5xohzy0eQcwjsGAtuK6XgT_TB_u7Q6_FbS0AwySISYz6JsnV-FHsb-0FMUjj6-jF0A3vb7El43xwZUrAhx7qqn_DuvrztjChsNWyE7dKWDceTwxIHDobEG7LDivMvsq-jkRYIzYoMJabrIzTgRjGBLruxBp8Zl1CuOepD4vFO6JBzbZl5Qy0hrpuP9YAlYBg3sBhwsYcrATZWVYcNRkJDsNIo-lSFNOl8DalFm7IsxW0A6AMuysLzm4oLZe2hDrmfRI9Mh5JBgio8cKetZan-0pLpoU5ezcMdIszlaUC4ggbOa2h7wVZCanTO79VoeiZLIrCimL4hbtlegpiX6A792jaD5G-cmPhMRGqn2rZcbwIx61e1z3Lz_Wag4lc8I2UwSMFUaIFi67OWN9608JgNNv2-W2uj5NpTFNJSBGUO6gfdOt1C-dgAafhXyPyyQ9m1Uq_0JMwaOkqkkTjW5UNKBacx8Hi9S2AVX7Ln9DN2mNFtFZVCmpnS2qKwd53yhcGQWr_1QL3kshTH5-hkpnLr7ntWIf094NGClp9l5Y2BOB-NqO7JecD_3WHxzjh_3jx6yAiSc3FqX9zmNmiOyIlENc6GHDe10a6p3NNZkI3jTO6C6fQfzOFCQ544htxF7JvxahKLazpSIBRkbf7Hxgdo5s8p8kH5S8HTpl5hdCOsMveJjH0rYU801iTF7Sv5rqn_Zd9FGkT98mjhGl8O4fhEHd967-GR9KupALmG9LtfA2jKwipAcwxyhaXFg2hobCpSvHx9KLOW-3gQt93PqNoE9TAGyIlYbHBFyN3IDsH5bKDYkL4C7RlXUFogBq64SpljjXoW3gYmH2guEaXMwMLf7Mogaoi0Or4ubitxd8EvFuhH2W1TekVc', + e: 'AQAB' + } +} diff --git a/packages/crypto/test/keys/rsa.spec.ts b/packages/crypto/test/keys/rsa.spec.ts index f82cacadf1..657ead0937 100644 --- a/packages/crypto/test/keys/rsa.spec.ts +++ b/packages/crypto/test/keys/rsa.spec.ts @@ -3,15 +3,13 @@ import { expect } from 'aegir/chai' import { fromString as uint8ArrayFromString } from 'uint8arrays/from-string' import * as crypto from '../../src/index.js' -import { RsaPrivateKey, RsaPublicKey, overrideMaxKeySize } from '../../src/keys/rsa-class.js' -import * as rsaCrypto from '../../src/keys/rsa.js' +import { MAX_KEY_SIZE, RsaPrivateKey, RsaPublicKey } from '../../src/keys/rsa-class.js' import fixtures from '../fixtures/go-key-rsa.js' +import { RSA_KEY_8200_BITS } from '../fixtures/rsa.js' import { testGarbage } from '../helpers/test-garbage-error-handling.js' const rsa = crypto.keys.supportedKeys.rsa -/** @typedef {import('libp2p-crypto').keys.supportedKeys.rsa.RsaPrivateKey} RsaPrivateKey */ - describe('RSA', function () { this.timeout(20 * 1000) let key: RsaPrivateKey @@ -26,24 +24,20 @@ describe('RSA', function () { expect(digest).to.have.length(34) }) - it('Does not generate a big key', async () => { - await expect(rsa.generateKeyPair(8193)).to.be.rejected() + it('does not generate a big key', async () => { + await expect(rsa.generateKeyPair(MAX_KEY_SIZE + 1)).to.be.rejected() }) - it('Does not unmarshal a big key', async () => { - const reset = overrideMaxKeySize(4096 - 8) - try { - const k = await rsaCrypto.generateKey(4096) - const sk = new RsaPrivateKey(k.privateKey, k.publicKey) - const pubk = new RsaPublicKey(k.publicKey) - const m = sk.marshal() - const pubm = pubk.marshal() - await expect(rsa.unmarshalRsaPrivateKey(m)).to.be.rejectedWith(/too large/) - expect(() => rsa.unmarshalRsaPublicKey(pubm)).to.throw(/too large/) - await expect(rsa.fromJwk(k.privateKey)).to.be.rejectedWith(/too large/) - } finally { - reset() - } + it('does not unmarshal a big key', async () => { + const k = RSA_KEY_8200_BITS + const sk = new RsaPrivateKey(k.privateKey, k.publicKey) + const pubk = new RsaPublicKey(k.publicKey) + const m = sk.marshal() + const pubm = pubk.marshal() + + await expect(rsa.unmarshalRsaPrivateKey(m)).to.eventually.be.rejectedWith(/too large/) + expect(() => rsa.unmarshalRsaPublicKey(pubm)).to.throw(/too large/) + await expect(rsa.fromJwk(k.privateKey)).to.eventually.be.rejectedWith(/too large/) }) it('signs', async () => {