PeculiarVentures / PKI.js

PKI.js is a pure JavaScript library implementing the formats that are used in PKI applications (signing, encryption, certificate requests, OCSP and TSP requests/responses). It is built on WebCrypto (Web Cryptography API) and requires no plug-ins.
http://pkijs.org
Other
1.25k stars 204 forks source link

'crypto.verifyWithPublicKey is not a function' when doing CRL signature check #363

Closed jeffsec-aws closed 1 year ago

jeffsec-aws commented 1 year ago

Hi,

I (re)open the issue listed in https://github.com/PeculiarVentures/PKI.js/issues/199 as:

The initial error message is

{
    "errorType": "Runtime.UnhandledPromiseRejection",
    "errorMessage": "TypeError: crypto.verifyWithPublicKey is not a function",
    "reason": {
        "errorType": "TypeError",
        "errorMessage": "crypto.verifyWithPublicKey is not a function",
        "stack": [
            "TypeError: crypto.verifyWithPublicKey is not a function",
            "    at CertificateRevocationList.verify (/var/task/node_modules/pkijs/build/index.js:9806:23)",
            "    at /var/task/Modules/cert-helper.js:398:13",
            "    at FSReqCallback.readFileAfterClose [as oncomplete] (node:internal/fs/read_file_context:68:3)"
        ]
    },
    "promise": {},
    "stack": [
        "Runtime.UnhandledPromiseRejection: TypeError: crypto.verifyWithPublicKey is not a function",
        "    at process.<anonymous> (file:///var/runtime/index.mjs:1131:17)",
        "    at process.emit (node:events:527:28)",
        "    at process.emit (node:domain:475:12)",
        "    at emit (node:internal/process/promises:140:20)",
        "    at processPromiseRejections (node:internal/process/promises:274:27)",
        "    at processTicksAndRejections (node:internal/process/task_queues:97:32)"
    ]
}

This happens when trying to verify a CRL through:

const crl = new Pkijs.CertificateRevocationList({
        schema: asn1crl.result
      })

var verifyObject = {};

verifyObject.issuerCertificate = temp_cert;
verifyObject.publicKeyInfo = temp_cert.subjectPublicKeyInfo
crl.verify(verifyObject, (result, error) => {
      [...]
});   

It keeps failing even if I had a new Crypto engine through:

var Pkijs = require("pkijs");
const WebCrypto = require("@peculiar/webcrypto");

const webcrypto = WebCrypto();
Pkijs.setEngine("newEngine", webcrypto, new Pkijs.CryptoEngine({ name: "", crypto: webcrypto, subtle: webcrypto.subtle }));

Jeff

jeffsec-aws commented 1 year ago

So I am sure the CryptoEngine is correctly intialized with "@peculiar/webcrypto", still i keep on getting the same error of:

{
    "errorType": "Runtime.UnhandledPromiseRejection",
    "errorMessage": "TypeError: crypto.verifyWithPublicKey is not a function",
    "reason": {
        "errorType": "TypeError",
        "errorMessage": "crypto.verifyWithPublicKey is not a function",
        "stack": [
            "TypeError: crypto.verifyWithPublicKey is not a function",
            "    at CertificateRevocationList.verify (/var/task/node_modules/pkijs/build/index.js:9806:23)",
            "    at /var/task/Modules/cert-helper.js:398:13",
            "    at FSReqCallback.readFileAfterClose [as oncomplete] (node:internal/fs/read_file_context:68:3)"
        ]
    },
    "promise": {},
    "stack": [
        "Runtime.UnhandledPromiseRejection: TypeError: crypto.verifyWithPublicKey is not a function",
        "    at process.<anonymous> (file:///var/runtime/index.mjs:1131:17)",
        "    at process.emit (node:events:527:28)",
        "    at process.emit (node:domain:475:12)",
        "    at emit (node:internal/process/promises:140:20)",
        "    at processPromiseRejections (node:internal/process/promises:274:27)",
        "    at processTicksAndRejections (node:internal/process/task_queues:97:32)"
    ]
}

Adding a catch for crl.verify only stop the Runtime.UnhandledPromiseRejection but keeps on telling me the promise is rejected.

Any advices?

microshine commented 1 year ago

Please see this example. It works and I can't reproduce the same problem

import * as pkijs from "pkijs";
import { Crypto } from "@peculiar/webcrypto";

async function main() {
  pkijs.setEngine("@peculiar/webcrypto", new pkijs.CryptoEngine({
    crypto: new Crypto(),
  }));
  const crlRaw = Buffer.from("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", "base64");
  const caRaw = Buffer.from("MIIDzTCCArWgAwIBAgIQCjeHZF5ftIwiTv0b7RQMPDANBgkqhkiG9w0BAQsFADBaMQswCQYDVQQGEwJJRTESMBAGA1UEChMJQmFsdGltb3JlMRMwEQYDVQQLEwpDeWJlclRydXN0MSIwIAYDVQQDExlCYWx0aW1vcmUgQ3liZXJUcnVzdCBSb290MB4XDTIwMDEyNzEyNDgwOFoXDTI0MTIzMTIzNTk1OVowSjELMAkGA1UEBhMCVVMxGTAXBgNVBAoTEENsb3VkZmxhcmUsIEluYy4xIDAeBgNVBAMTF0Nsb3VkZmxhcmUgSW5jIEVDQyBDQS0zMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEua1NZpkUC0bsH4HRKlAenQMVLzQSfS2WuIg4m4Vfj7+7Te9hRsTJc9QkT+DuHM5ss1FxL2ruTAUJd9NyYqSb16OCAWgwggFkMB0GA1UdDgQWBBSlzjfq67B1DpRniLRF+tkkEIeWHzAfBgNVHSMEGDAWgBTlnVkwgkdYzKz6CFQ2hns6tQRN8DAOBgNVHQ8BAf8EBAMCAYYwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMBIGA1UdEwEB/wQIMAYBAf8CAQAwNAYIKwYBBQUHAQEEKDAmMCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5kaWdpY2VydC5jb20wOgYDVR0fBDMwMTAvoC2gK4YpaHR0cDovL2NybDMuZGlnaWNlcnQuY29tL09tbmlyb290MjAyNS5jcmwwbQYDVR0gBGYwZDA3BglghkgBhv1sAQEwKjAoBggrBgEFBQcCARYcaHR0cHM6Ly93d3cuZGlnaWNlcnQuY29tL0NQUzALBglghkgBhv1sAQIwCAYGZ4EMAQIBMAgGBmeBDAECAjAIBgZngQwBAgMwDQYJKoZIhvcNAQELBQADggEBAAUkHd0bsCrrmNaF4zlNXmtXnYJX/OvoMaJXkGUFvhZEOFp3ArnPEELG4ZKk40Un+ABHLGioVplTVI+tnkDB0A+21w0LOEhsUCxJkAZbZB2LzEgwLt4I4ptJIsCSDBFelpKU1fwg3FZs5ZKTv3ocwDfjhUkV+ivhdDkYD7fa86JXWGBPzI6UAPxGezQxPk1HgoE6y/SJXQ7vTQ1unBuCJN0yJV0ReFEQPaA1IwQvZW+cwdFD19Ae8zFnWSfda9J1CZMRJCQUzym+5iPDuI9yP+kHyCREU3qzuWFloUwOxkgAyXVjBYdwRVKD05WdRerw6DEdfgkfCv4+3ao8XnTSrLE=", "base64");
  const crl = pkijs.CertificateRevocationList.fromBER(crlRaw);
  const ca = pkijs.Certificate.fromBER(caRaw);
  const ok = await crl.verify({
    issuerCertificate: ca,
  });
  console.log(ok); // true
}

main().catch(e => {
  console.error(e);
  process.exit(1)
})
jeffsec-aws commented 1 year ago

In fact pkijs.setEngine is deprecated now.

So for unknown reasons, the Crypto Engine is not set to the one I initialized and seems to run with a default one which does not contains the verifyWithPublicKey function.

My code works if I set Crypto engine as part of the call to crl.verify as per the function protoype allows:

public async verify(parameters: CertificateRevocationListVerifyParams = {}, crypto = common.getCrypto(true)): Promise<boolean>