Comparing version 6.0.3 to 6.0.4
@@ -12,3 +12,3 @@ import { JOSEError, JWKSNoMatchingKey, JWKSTimeout } from '../util/errors.js'; | ||
const NAME = 'jose'; | ||
const VERSION = 'v6.0.3'; | ||
const VERSION = 'v6.0.4'; | ||
USER_AGENT = `${NAME}/${VERSION}`; | ||
@@ -15,0 +15,0 @@ } |
@@ -188,7 +188,13 @@ import invalidKeyInput from './invalid_key_input.js'; | ||
} | ||
let X509Certificate; | ||
let createPublicKey; | ||
function getSPKI(x509) { | ||
if ((X509Certificate ||= globalThis.process?.getBuiltinModule?.('node:crypto')?.X509Certificate)) { | ||
try { | ||
createPublicKey ??= globalThis.process?.getBuiltinModule?.('node:crypto')?.createPublicKey; | ||
} | ||
catch { | ||
createPublicKey = 0; | ||
} | ||
if (createPublicKey) { | ||
try { | ||
return new X509Certificate(x509).publicKey.export({ format: 'pem', type: 'spki' }); | ||
return new createPublicKey(x509).export({ format: 'pem', type: 'spki' }); | ||
} | ||
@@ -195,0 +201,0 @@ catch { } |
@@ -1,13 +0,10 @@ | ||
import { encoder, decoder, Buffer } from '../lib/buffer_utils.js'; | ||
import { encoder, decoder } from '../lib/buffer_utils.js'; | ||
export function encodeBase64(input) { | ||
if (Buffer) | ||
return Buffer.from(input).toString('base64'); | ||
let unencoded = input; | ||
if (typeof unencoded === 'string') { | ||
unencoded = encoder.encode(unencoded); | ||
if (Uint8Array.prototype.toBase64) { | ||
return input.toBase64(); | ||
} | ||
const CHUNK_SIZE = 0x8000; | ||
const arr = []; | ||
for (let i = 0; i < unencoded.length; i += CHUNK_SIZE) { | ||
arr.push(String.fromCharCode.apply(null, unencoded.subarray(i, i + CHUNK_SIZE))); | ||
for (let i = 0; i < input.length; i += CHUNK_SIZE) { | ||
arr.push(String.fromCharCode.apply(null, input.subarray(i, i + CHUNK_SIZE))); | ||
} | ||
@@ -17,9 +14,15 @@ return btoa(arr.join('')); | ||
export function encode(input) { | ||
if (Buffer) | ||
return Buffer.from(input).toString('base64url'); | ||
return encodeBase64(input).replace(/=/g, '').replace(/\+/g, '-').replace(/\//g, '_'); | ||
let unencoded = input; | ||
if (typeof unencoded === 'string') { | ||
unencoded = encoder.encode(unencoded); | ||
} | ||
if (Uint8Array.prototype.toBase64) { | ||
return unencoded.toBase64({ alphabet: 'base64url', omitPadding: true }); | ||
} | ||
return encodeBase64(unencoded).replace(/=/g, '').replace(/\+/g, '-').replace(/\//g, '_'); | ||
} | ||
export function decodeBase64(encoded) { | ||
if (Buffer) | ||
return Buffer.from(encoded, 'base64'); | ||
if (Uint8Array.fromBase64) { | ||
return Uint8Array.fromBase64(encoded); | ||
} | ||
const binary = atob(encoded); | ||
@@ -33,2 +36,7 @@ const bytes = new Uint8Array(binary.length); | ||
export function decode(input) { | ||
if (Uint8Array.fromBase64) { | ||
return Uint8Array.fromBase64(typeof input === 'string' ? input : decoder.decode(input), { | ||
alphabet: 'base64url', | ||
}); | ||
} | ||
let encoded = input; | ||
@@ -38,4 +46,2 @@ if (encoded instanceof Uint8Array) { | ||
} | ||
if (Buffer) | ||
return Buffer.from(encoded, 'base64url'); | ||
encoded = encoded.replace(/-/g, '+').replace(/_/g, '/').replace(/\s/g, ''); | ||
@@ -42,0 +48,0 @@ try { |
export const encoder = new TextEncoder(); | ||
export const decoder = new TextDecoder(); | ||
const MAX_INT32 = 2 ** 32; | ||
const Buffer = globalThis.process?.getBuiltinModule?.('node:buffer')?.Buffer; | ||
export { Buffer }; | ||
export function concat(...buffers) { | ||
if (Buffer) | ||
return Buffer.concat(buffers); | ||
const size = buffers.reduce((acc, { length }) => acc + length, 0); | ||
@@ -10,0 +6,0 @@ const buf = new Uint8Array(size); |
@@ -8,4 +8,3 @@ import { concat, uint64be } from './buffer_utils.js'; | ||
import { isCryptoKey } from './is_key_like.js'; | ||
let timingSafeEqual = globalThis.process?.getBuiltinModule?.('node:crypto')?.timingSafeEqual; | ||
timingSafeEqual ||= (a, b) => { | ||
async function timingSafeEqual(a, b) { | ||
if (!(a instanceof Uint8Array)) { | ||
@@ -17,13 +16,13 @@ throw new TypeError('First argument must be a buffer'); | ||
} | ||
if (a.length !== b.length) { | ||
throw new TypeError('Input buffers must have the same length'); | ||
} | ||
const len = a.length; | ||
const algorithm = { name: 'HMAC', hash: 'SHA-256' }; | ||
const key = (await crypto.subtle.generateKey(algorithm, false, ['sign'])); | ||
const aHmac = new Uint8Array(await crypto.subtle.sign(algorithm, key, a)); | ||
const bHmac = new Uint8Array(await crypto.subtle.sign(algorithm, key, b)); | ||
let out = 0; | ||
let i = -1; | ||
while (++i < len) { | ||
out |= a[i] ^ b[i]; | ||
while (++i < 32) { | ||
out |= aHmac[i] ^ bHmac[i]; | ||
} | ||
return out === 0; | ||
}; | ||
} | ||
async function cbcDecrypt(enc, cek, ciphertext, iv, tag, aad) { | ||
@@ -43,3 +42,3 @@ if (!(cek instanceof Uint8Array)) { | ||
try { | ||
macCheckPassed = timingSafeEqual(tag, expectedTag); | ||
macCheckPassed = await timingSafeEqual(tag, expectedTag); | ||
} | ||
@@ -46,0 +45,0 @@ catch { |
{ | ||
"name": "jose", | ||
"version": "6.0.3", | ||
"version": "6.0.4", | ||
"description": "JWA, JWS, JWE, JWT, JWK, JWKS for Node.js, Browser, Cloudflare Workers, Deno, Bun, and other Web-interoperable runtimes", | ||
@@ -5,0 +5,0 @@ "keywords": [ |
246036
5987