{"version":3,"file":"certs.cjs","sources":["../../../../../../src/mods/tor/certs/certs.ts"],"sourcesContent":["import { Writable } from \"@hazae41/binary\";\nimport { Bytes } from \"@hazae41/bytes\";\nimport { Ed25519 } from \"@hazae41/ed25519\";\nimport { RsaPublicKey, RsaWasm } from \"@hazae41/rsa.wasm\";\nimport { X509 } from \"@hazae41/x509\";\nimport { CrossCert, Ed25519Cert, RsaCert, UnknownCertExtensionError } from \"../index.js\";\n\nexport type CertError =\n  | DuplicatedCertError\n  | UnknownCertError\n  | ExpectedCertError\n  | ExpiredCertError\n  | PrematureCertError\n  | InvalidSignatureError\n  | UnknownCertExtensionError\n  | InvalidCertError\n\nexport class DuplicatedCertError extends Error {\n  readonly #class = DuplicatedCertError\n  readonly name = this.#class.name\n\n  constructor() {\n    super(`Duplicated certificate`)\n  }\n\n}\n\nexport class UnknownCertError extends Error {\n  readonly #class = UnknownCertError\n  readonly name = this.#class.name\n\n  constructor() {\n    super(`Unknown certificate`)\n  }\n\n}\n\nexport class ExpectedCertError extends Error {\n  readonly #class = ExpectedCertError\n  readonly name = this.#class.name\n\n  constructor() {\n    super(`Expected a certificate`)\n  }\n\n}\n\nexport class ExpiredCertError extends Error {\n  readonly #class = ExpiredCertError\n  readonly name = this.#class.name\n\n  constructor() {\n    super(`Expired certificate`)\n  }\n\n}\n\nexport class PrematureCertError extends Error {\n  readonly #class = PrematureCertError\n  readonly name = this.#class.name\n\n  constructor() {\n    super(`Premature certificate`)\n  }\n\n}\n\nexport class InvalidSignatureError extends Error {\n  readonly #class = InvalidSignatureError\n  readonly name = this.#class.name\n\n  constructor() {\n    super(`Invalid certificate signature`)\n  }\n\n}\n\nexport class InvalidCertError extends Error {\n  readonly #class = InvalidCertError\n  readonly name = this.#class.name\n\n  constructor() {\n    super(`Invalid certificate`)\n  }\n\n}\n\nexport interface Certs {\n  readonly rsa_self: RsaCert,\n  readonly rsa_to_tls?: RsaCert,\n  readonly rsa_to_auth?: RsaCert,\n  readonly rsa_to_ed: CrossCert,\n  readonly ed_to_sign: Ed25519Cert,\n  readonly sign_to_tls: Ed25519Cert,\n  readonly sign_to_auth?: Ed25519Cert,\n}\n\nexport namespace Certs {\n\n  export async function verifyOrThrow(pcerts: Partial<Certs>, tlsCerts?: X509.Certificate[]): Promise<Certs> {\n    const { rsa_self, rsa_to_ed, ed_to_sign, sign_to_tls } = pcerts\n\n    if (tlsCerts == null)\n      throw new ExpectedCertError()\n\n    if (rsa_self == null)\n      throw new ExpectedCertError()\n    if (rsa_to_ed == null)\n      throw new ExpectedCertError()\n    if (ed_to_sign == null)\n      throw new ExpectedCertError()\n    if (sign_to_tls == null)\n      throw new ExpectedCertError()\n\n    const certs = { rsa_self, rsa_to_ed, ed_to_sign, sign_to_tls }\n\n    const result = await Promise.all([\n      verifyRsaSelfOrThrow(certs),\n      verifyRsaToEdOrThrow(certs),\n      verifyEdToSigningOrThrow(certs),\n      verifySigningToTlsOrThrow(certs, tlsCerts),\n    ]).then(all => all.every(x => x === true))\n\n    if (result !== true)\n      throw new Error(`Could not verify certs`)\n\n    return certs\n  }\n\n  async function verifyRsaSelfOrThrow(certs: Certs): Promise<true> {\n    if (certs.rsa_self.verifyOrThrow() !== true)\n      throw new Error(`Could not verify ID_SELF cert`)\n\n    const length = certs.rsa_self.x509.tbsCertificate.subjectPublicKeyInfo.subjectPublicKey.bytes.length\n\n    /**\n     * Only accept 1024-bits (128-bytes) public keys\n     */\n    if (length !== 12 + 128)\n      throw new InvalidCertError()\n\n    const signed = X509.writeToBytesOrThrow(certs.rsa_self.x509.tbsCertificate)\n    const publicKey = X509.writeToBytesOrThrow(certs.rsa_self.x509.tbsCertificate.subjectPublicKeyInfo)\n\n    const signatureAlgorithm = { name: \"RSASSA-PKCS1-v1_5\", hash: { name: \"SHA-256\" } }\n    const signature = certs.rsa_self.x509.signatureValue.bytes\n\n    const key = await crypto.subtle.importKey(\"spki\", publicKey, signatureAlgorithm, true, [\"verify\"]);\n    const verified = await crypto.subtle.verify(\"RSASSA-PKCS1-v1_5\", key, signature, signed)\n\n    if (verified !== true)\n      throw new InvalidSignatureError()\n\n    /**\n     * We don't verify the RSA identity on Snowflake / Meek\n     */\n\n    return true\n  }\n\n  async function verifyRsaToEdOrThrow(certs: Certs): Promise<true> {\n    if (certs.rsa_to_ed.verifyOrThrow() !== true)\n      throw new Error(`Could not verify ID_TO_ED cert`)\n\n    const publicKeyBytes = X509.writeToBytesOrThrow(certs.rsa_self.x509.tbsCertificate.subjectPublicKeyInfo)\n\n    using publicKeyMemory = new RsaWasm.Memory(publicKeyBytes)\n    using publicKeyPointer = RsaPublicKey.from_public_key_der(publicKeyMemory)\n\n    const prefix = Bytes.fromUtf8(\"Tor TLS RSA/Ed25519 cross-certificate\")\n    const prefixed = Bytes.concat([prefix, certs.rsa_to_ed.payload])\n    const hashed = new Uint8Array(await crypto.subtle.digest(\"SHA-256\", prefixed))\n\n    using hashedMemory = new RsaWasm.Memory(hashed)\n    using signatureMemory = new RsaWasm.Memory(certs.rsa_to_ed.signature)\n\n    const verified = publicKeyPointer.verify_pkcs1v15_unprefixed(hashedMemory, signatureMemory)\n\n    if (verified !== true)\n      throw new InvalidSignatureError()\n\n    /**\n     * We don't verify the Ed25519 identity on Snowflake / Meek\n     */\n\n    return true\n  }\n\n  async function verifyEdToSigningOrThrow(certs: Certs): Promise<true> {\n    if (await certs.ed_to_sign.verifyOrThrow() !== true)\n      throw new Error(`Could not verify ED_TO_SIGN cert`)\n\n    using identity = await Ed25519.get().getOrThrow().VerifyingKey.importOrThrow(certs.rsa_to_ed.key)\n    using signature = Ed25519.get().getOrThrow().Signature.importOrThrow(certs.ed_to_sign.signature)\n\n    const verified = await identity.verifyOrThrow(certs.ed_to_sign.payload, signature)\n\n    if (verified !== true)\n      throw new InvalidSignatureError()\n\n    return true\n  }\n\n  async function verifySigningToTlsOrThrow(certs: Certs, tlsCerts: X509.Certificate[]): Promise<true> {\n    if (await certs.sign_to_tls.verifyOrThrow() !== true)\n      throw new Error(`Could not verify SIGNING_TO_TLS cert`)\n\n    using identity = await Ed25519.get().getOrThrow().VerifyingKey.importOrThrow(certs.ed_to_sign.certKey)\n    using signature = Ed25519.get().getOrThrow().Signature.importOrThrow(certs.sign_to_tls.signature)\n\n    const verified = await identity.verifyOrThrow(certs.sign_to_tls.payload, signature)\n\n    if (verified !== true)\n      throw new InvalidSignatureError()\n\n    const tls = Writable.writeToBytesOrThrow(tlsCerts[0].toDER())\n    const hash = new Uint8Array(await crypto.subtle.digest(\"SHA-256\", tls))\n\n    if (Bytes.equals(hash, certs.sign_to_tls.certKey) !== true)\n      throw new InvalidCertError()\n\n    return true\n  }\n\n}"],"names":["Certs","X509","__addDisposableResource","RsaWasm","RsaPublicKey","Bytes","Ed25519","Writable"],"mappings":"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"}