diff --git a/src/key/import.ts b/src/key/import.ts index 5cbd61c2af..a9b566f42a 100644 --- a/src/key/import.ts +++ b/src/key/import.ts @@ -41,20 +41,13 @@ function parseElement(bytes: Uint8Array) { if (bytes[position] < 0x80) { length = bytes[position] position++ - } else { - let numberOfDigits = bytes[position] & 0x7f - position++ - length = 0 - for (let i = 0; i < numberOfDigits; i++) { - length = length * 256 + bytes[position] - position++ - } - } - - if (length === 0x80) { + } else if (length === 0x80) { length = 0 while (bytes[position + length] !== 0 || bytes[position + length + 1] !== 0) { + if (length > bytes.byteLength) { + throw new TypeError('invalid indefinite form length') + } length++ } @@ -64,6 +57,14 @@ function parseElement(bytes: Uint8Array) { contents: bytes.subarray(position, position + length), raw: bytes.subarray(0, byteLength), } + } else { + let numberOfDigits = bytes[position] & 0x7f + position++ + length = 0 + for (let i = 0; i < numberOfDigits; i++) { + length = length * 256 + bytes[position] + position++ + } } const byteLength = position + length @@ -158,7 +159,13 @@ export async function importX509( if (typeof x509 !== 'string' || x509.indexOf('-----BEGIN CERTIFICATE-----') !== 0) { throw new TypeError('"x509" must be X.509 formatted string') } - const spki = getSPKI(x509) + let spki: string + try { + spki = getSPKI(x509) + } catch (cause) { + // @ts-ignore + throw new TypeError('failed to parse the X.509 certificate', { cause }) + } return importPublic(spki, alg, options) } diff --git a/test/jwk/issue-459.test.mjs b/test/jwk/issue-459.test.mjs new file mode 100644 index 0000000000..b1d353a7b7 --- /dev/null +++ b/test/jwk/issue-459.test.mjs @@ -0,0 +1,32 @@ +import test from 'ava' +import { keyRoot } from '../dist.mjs' + +const { importX509 } = await import(keyRoot) + +const cert = `-----BEGIN CERTIFICATE----- +MIID5jCCAs6gAwIBAgIBAjANBgkqhkiG9w0BAQsFADB7MQswCQYDVQQGEwJVUzEL +MAkGA1UECBMCVE4xEDAOBgNVBAoTB01TSUdOSUExDDAKBgNVBAsTA1JORDEXMBUG +A1UEAxMOTVNJR05JQSBSTkQgQ0ExJjAkBgkqhkiG9w0BCQEWF3BhdmxvLmx5c292 +QG1zaWduaWEuY29tMB4XDTE5MTExMzA4MjAwMFoXDTI4MTExMzA4MjAwMFowgYAx +CzAJBgNVBAYTAlVTMQswCQYDVQQIEwJUTjEQMA4GA1UEChMHTVNJR05JQTEUMBIG +A1UECxMLTVNJR05JQSBSTkQxFDASBgNVBAMTC01TSUdOSUEgUk5EMSYwJAYJKoZI +hvcNAQkBFhdwYXZsby5seXNvdkBtc2lnbmlhLmNvbTCCASIwDQYJKoZIhvcNAQEB +BQADggEPADCCAQoCggEBAKRoo30zttpiFlBKnOAmlOcT07xPms7Z6/ZdN9KnE/Po +NQx7g6+Ap6b+trA2WDG80jEtwAy5XJcm81rBvJJvjwWQhiPjhXHvEibl+5zTYEXQ +tvl3qKNdikXuXPBLI/rwmZTNZd2aa5biVoLEY+cQVLOjdAZS9ZIkeuLYeLEZfNky +7rLa4XyRO4W4XEUWgafOp+ZSXATOz48XCb+fmaek4d8epsVJ/X3Qww9I9mqg8QA7 +/EH9ASOYvbMzOjSuDjYBCRq4SJw/YBJDnBcBJSESzLJDDCJQyP4BOD2+P5UZ/OWS +NyzEDCLfLsiCVjdt0mNXrn/tGpdLoy1rVfC2SOAoZEUCAwEAAaNvMG0wDAYDVR0T +AQH/BAIwADAdBgNVHQ4EFgQUU/luo/bbBOlrQ7wrC3+ggkITcSYwCwYDVR0PBAQD +AgSwMBEGCWCGSAGG+EIBAQQEAwIFoDAeBglghkgBhvhCAQ0EERYPeGNhIGNlcnRp +ZmljYXRlMA0GCSqGSIb3DQEBCwUAA4IBAQAXroFZ9FeP10gtQguptDo6U0SIAB9n +qjN1IktyqatfUuVtThuxXAb3QQ7kYmGCZEaOIKoFdVc8i9aR5ZrYC1VIN4+cGLv7 +P36Zl2q4i2G/X0QzniPPvsPyOUXeTVs3k6Sxe07uWdxsglq9LcVW++PvGYzotZP+ +ZtmTzYAQtgadhPNo7+QmTO1FDju9p9hTFK7WhmXAO48bF9jrFiTkbwmo6PdlQiqi +PQYlbfO0XV727QUZ1YyG8rR/3VVRsBOmwZBKCj0dkh9eiRcNpJloqe1uZ83EBG/W +Cic5wE9P+Ol/pFNJFpfjXMsmT8lkCK954aYf2xoH1bHkONYAEEk0iQu/ +-----END CERTIFICATE-----` + +test('https://github.com/panva/jose/issues/459', (t) => { + return t.notThrowsAsync(() => importX509(cert, 'RS256')) +})