commit e61aa56e05f2da8cb3af1665a7834e78c8783afe
parent a4ecc2c17f7e9bd0cb0c93e3ca346f6c58667d28
Author: Michael Camilleri <[email protected]>
Date: Fri, 12 Jun 2026 05:44:56 +0900
Remove diagnostic logging in Cloudflare Worker
Diffstat:
1 file changed, 0 insertions(+), 205 deletions(-)
diff --git a/Workers/push-worker.js b/Workers/push-worker.js
@@ -128,7 +128,6 @@ export class PushRegistry {
// as an ECDSA-SHA256 *message*, so the digest under the signature is
// SHA256(nonce). WebCrypto applies that second hash.
const assertionNonce = await sha256Bytes(signedBytes);
- const keySource = registration.publicKeySPKI ? "spki" : "jwk";
const publicKey = await this.importAppAttestPublicKey(registration);
const verified = await crypto.subtle.verify(
{ name: "ECDSA", hash: "SHA-256" },
@@ -137,104 +136,6 @@ export class PushRegistry {
assertionNonce
);
if (!verified) {
- const diagnostic = {
- signatureLength: assertion.signature.length,
- authenticatorDataLength: assertion.authenticatorData.length,
- clientDataHashLength: clientDataHash.length,
- signedBytesLength: signedBytes.length,
- keySource,
- hasPublicKeySPKI: Boolean(registration.publicKeySPKI),
- signCount: authData.signCount,
- storedSignCount: registration.signCount || 0,
- rawOverDoubleHash: false,
- derOverCanonicalHash: false,
- rawOverCanonicalString: false,
- rawSha384OverCanonicalHash: false,
- rawSha512OverCanonicalHash: false,
- rawOverPrehashedNonce: false,
- rawOverClientDataHashOnly: false,
- rawOverAuthenticatorDataOnly: false
- };
- try {
- diagnostic.rawOverDoubleHash = await crypto.subtle.verify(
- { name: "ECDSA", hash: "SHA-256" },
- publicKey,
- derECDSASignatureToRaw(assertion.signature),
- concatBytes(assertion.authenticatorData, await sha256Bytes(clientDataHash))
- );
- } catch {
- diagnostic.rawOverDoubleHash = "error";
- }
- try {
- diagnostic.derOverCanonicalHash = await crypto.subtle.verify(
- { name: "ECDSA", hash: "SHA-256" },
- publicKey,
- assertion.signature,
- signedBytes
- );
- } catch {
- diagnostic.derOverCanonicalHash = "error";
- }
- try {
- diagnostic.rawOverCanonicalString = await crypto.subtle.verify(
- { name: "ECDSA", hash: "SHA-256" },
- publicKey,
- derECDSASignatureToRaw(assertion.signature),
- concatBytes(assertion.authenticatorData, new TextEncoder().encode(canonical))
- );
- } catch {
- diagnostic.rawOverCanonicalString = "error";
- }
- try {
- diagnostic.rawSha384OverCanonicalHash = await crypto.subtle.verify(
- { name: "ECDSA", hash: "SHA-384" },
- publicKey,
- derECDSASignatureToRaw(assertion.signature),
- signedBytes
- );
- } catch {
- diagnostic.rawSha384OverCanonicalHash = "error";
- }
- try {
- diagnostic.rawSha512OverCanonicalHash = await crypto.subtle.verify(
- { name: "ECDSA", hash: "SHA-512" },
- publicKey,
- derECDSASignatureToRaw(assertion.signature),
- signedBytes
- );
- } catch {
- diagnostic.rawSha512OverCanonicalHash = "error";
- }
- try {
- diagnostic.rawOverPrehashedNonce = verifyP256ECDSADigest(
- registration.publicKeyJWK,
- derECDSASignatureToRaw(assertion.signature),
- await sha256Bytes(signedBytes)
- );
- } catch {
- diagnostic.rawOverPrehashedNonce = "error";
- }
- try {
- diagnostic.rawOverClientDataHashOnly = await crypto.subtle.verify(
- { name: "ECDSA", hash: "SHA-256" },
- publicKey,
- derECDSASignatureToRaw(assertion.signature),
- clientDataHash
- );
- } catch {
- diagnostic.rawOverClientDataHashOnly = "error";
- }
- try {
- diagnostic.rawOverAuthenticatorDataOnly = await crypto.subtle.verify(
- { name: "ECDSA", hash: "SHA-256" },
- publicKey,
- derECDSASignatureToRaw(assertion.signature),
- assertion.authenticatorData
- );
- } catch {
- diagnostic.rawOverAuthenticatorDataOnly = "error";
- }
- console.warn("App Attest assertion verification failed", diagnostic);
return { ok: false, status: 401, message: "Bad App Attest assertion" };
}
@@ -1082,112 +983,6 @@ function derIntegerToFixed(bytes, length) {
return result;
}
-const P256 = {
- p: 0xffffffff00000001000000000000000000000000ffffffffffffffffffffffffn,
- n: 0xffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551n,
- a: -3n,
- gx: 0x6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296n,
- gy: 0x4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5n
-};
-
-function verifyP256ECDSADigest(publicKeyJWK, rawSignature, digest) {
- if (!publicKeyJWK || publicKeyJWK.crv !== "P-256" || rawSignature.length !== 64 || digest.length !== 32) {
- return false;
- }
- const r = bytesToBigInt(rawSignature.slice(0, 32));
- const s = bytesToBigInt(rawSignature.slice(32));
- if (r <= 0n || r >= P256.n || s <= 0n || s >= P256.n) return false;
- const q = {
- x: bytesToBigInt(base64URLDecode(publicKeyJWK.x)),
- y: bytesToBigInt(base64URLDecode(publicKeyJWK.y))
- };
- if (!p256IsOnCurve(q)) return false;
- const z = bytesToBigInt(digest) % P256.n;
- const w = modInverse(s, P256.n);
- const u1 = mod(z * w, P256.n);
- const u2 = mod(r * w, P256.n);
- const point = p256Add(
- p256Multiply({ x: P256.gx, y: P256.gy }, u1),
- p256Multiply(q, u2)
- );
- return Boolean(point) && mod(point.x, P256.n) === r;
-}
-
-function p256IsOnCurve(point) {
- if (!point || point.x < 0n || point.x >= P256.p || point.y < 0n || point.y >= P256.p) {
- return false;
- }
- const left = mod(point.y * point.y, P256.p);
- const right = mod(point.x * point.x * point.x + P256.a * point.x + p256B(), P256.p);
- return left === right;
-}
-
-function p256B() {
- return 0x5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604bn;
-}
-
-function p256Add(left, right) {
- if (!left) return right;
- if (!right) return left;
- if (left.x === right.x) {
- if (mod(left.y + right.y, P256.p) === 0n) return null;
- return p256Double(left);
- }
- const slope = mod((right.y - left.y) * modInverse(right.x - left.x, P256.p), P256.p);
- const x = mod(slope * slope - left.x - right.x, P256.p);
- const y = mod(slope * (left.x - x) - left.y, P256.p);
- return { x, y };
-}
-
-function p256Double(point) {
- if (!point || point.y === 0n) return null;
- const slope = mod((3n * point.x * point.x + P256.a) * modInverse(2n * point.y, P256.p), P256.p);
- const x = mod(slope * slope - 2n * point.x, P256.p);
- const y = mod(slope * (point.x - x) - point.y, P256.p);
- return { x, y };
-}
-
-function p256Multiply(point, scalar) {
- let result = null;
- let addend = point;
- let value = scalar;
- while (value > 0n) {
- if ((value & 1n) === 1n) result = p256Add(result, addend);
- addend = p256Double(addend);
- value >>= 1n;
- }
- return result;
-}
-
-function mod(value, modulus) {
- const result = value % modulus;
- return result >= 0n ? result : result + modulus;
-}
-
-function modInverse(value, modulus) {
- let low = mod(value, modulus);
- let high = modulus;
- let lowCoefficient = 1n;
- let highCoefficient = 0n;
- while (low > 1n) {
- const ratio = high / low;
- [low, high] = [high - low * ratio, low];
- [lowCoefficient, highCoefficient] = [
- highCoefficient - lowCoefficient * ratio,
- lowCoefficient
- ];
- }
- return mod(lowCoefficient, modulus);
-}
-
-function bytesToBigInt(bytes) {
- let value = 0n;
- for (const byte of bytes) {
- value = (value << 8n) + BigInt(byte);
- }
- return value;
-}
-
async function signProviderJWT({ keyPEM, keyID, teamID, issuedAt }) {
if (!keyPEM || !keyID || !teamID) {
throw new Error("APNS_KEY, APNS_KEY_ID, APNS_TEAM_ID must all be set");