| … | … | @@ -259,8 +259,12 @@ const readDerLength = (bytes, offset) => { |
| 259 | 259 | return { length, read: 1 + numBytes } |
| 260 | 260 | } |
| 261 | 261 | |
| 262 | | const ecdsaDerToJose = (derSignature, size = 32) => { |
| 263 | | const bytes = derSignature instanceof Uint8Array ? derSignature : new Uint8Array(derSignature) |
| 262 | const ecdsaSigToJose = (signature, size = 32) => { |
| 263 | const bytes = signature instanceof Uint8Array ? signature : new Uint8Array(signature) |
| 264 | |
| 265 | // Some runtimes already return the JOSE (raw r||s) format for ECDSA signatures. |
| 266 | if (bytes.length === size * 2 && bytes[0] !== 0x30) return bytes |
| 267 | |
| 264 | 268 | let offset = 0 |
| 265 | 269 | if (bytes[offset++] !== 0x30) throw new Error('Invalid DER signature (no sequence)') |
| 266 | 270 | const seqLen = readDerLength(bytes, offset) |
| … | … | @@ -303,7 +307,7 @@ const createVapidJwt = async (endpoint) => { |
| 303 | 307 | const derSig = new Uint8Array( |
| 304 | 308 | await crypto.subtle.sign({ name: 'ECDSA', hash: 'SHA-256' }, privateKey, encoder.encode(data)) |
| 305 | 309 | ) |
| 306 | | const joseSig = ecdsaDerToJose(derSig) |
| 310 | const joseSig = ecdsaSigToJose(derSig) |
| 307 | 311 | const signature = base64UrlEncodeBytes(joseSig) |
| 308 | 312 | return `${data}.${signature}` |
| 309 | 313 | } |