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

live example cert chain validation doesn't work #289

Closed themighty1 closed 3 years ago

themighty1 commented 3 years ago

I tried the steps below both in Firefox and Chriome. I went to https://pkijs.org/examples/X509_cert_complex_example.html

Then I opened reddit.com and exported each cert in DER format, I got 3 certificates _.reddit.com DigiCert SHA2 Secure Server CA Builtin Object Token_DigiCert Global Root CA

Then on the live example page I feed to

Select trusted certs (binary): Builtin Object Token_DigiCert Global Root CA

Load intermediate certificates (binary): _.reddit.com DigiCert SHA2 Secure Server CA

Press verify, Verification result: false

I repeated the same steps for youtube.com, also got Verification result: false

Also tried to verify in nodejs, got 'No valid certificate paths found'

rmhrisk commented 3 years ago

Include intermediate in the bag of CA certs also.

Ryan Hurst

Sent from my iPhone

On Oct 3, 2020, at 8:28 AM, themighty1 notifications@github.com wrote:



I tried the steps below both in Firefox and Chriome. I went to https://pkijs.org/examples/X509_cert_complex_example.htmlhttps://nam02.safelinks.protection.outlook.com/?url=https%3A%2F%2Fpkijs.org%2Fexamples%2FX509_cert_complex_example.html&data=02%7C01%7C%7Cad90d47e244b42c0b35708d867b0f7ff%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C637373357050251579&sdata=JoETu2uHxG%2FAfAlDso351UwBbOqL36zk17SVGvZm5kU%3D&reserved=0

Then I opened reddit.com and exported each cert in DER format, I got 3 certificates _.reddit.com DigiCert SHA2 Secure Server CA Builtin Object Token_DigiCert Global Root CA

Then on the live example page I feed to

Select trusted certs (binary): Builtin Object Token_DigiCert Global Root CA

Load intermediate certificates (binary): _.reddit.com DigiCert SHA2 Secure Server CA

Press verify, Verification result: false

I repeated the same steps for youtube.com, also got Verification result: false

Also tried to verify in nodejs, got 'No valid certificate paths found'

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHubhttps://nam02.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2FPeculiarVentures%2FPKI.js%2Fissues%2F289&data=02%7C01%7C%7Cad90d47e244b42c0b35708d867b0f7ff%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C637373357050261571&sdata=E5u5DroypmZkoKe13spzpwRk%2FjmIWV56kzimF52vEeQ%3D&reserved=0, or unsubscribehttps://nam02.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fnotifications%2Funsubscribe-auth%2FAAMLKT3H7LXBGNUIH2PW5DTSI47JRANCNFSM4SCXCUZQ&data=02%7C01%7C%7Cad90d47e244b42c0b35708d867b0f7ff%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C637373357050271565&sdata=RYzM6iBAB%2BRg6kUbo6IZADSG9QfvqjdF7P1ei%2BCxS3Q%3D&reserved=0.

themighty1 commented 3 years ago

Do you mean

Select trusted certs (binary): Builtin Object Token_DigiCert Global Root CA DigiCert SHA2 Secure Server CA

Load intermediate certificates (binary): _.reddit.com

? I get Verification result: false I also tried every possible combination, none worked.

YuryStrozhevsky commented 3 years ago

@themighty1 You forgot about one detail - CRLs for intermediate certificates. Without it verification engine would consider the certificates as invalid and thus the verification result would be "false".

As soon as you worry about verification engine in PKI.js I need to assure you that this part of code was tested against NIST PKITS (PKI Test Suite). This test you could find here. Moreover, this test run on every build on CircleCI.

themighty1 commented 3 years ago

@YuryStrozhevsky, in this particular case there has been no certificate revokation. What kind of file do I need to provide at "Load CRLs (binary):" to show that the CRL is empty?

YuryStrozhevsky commented 3 years ago

@themighty1 You need to provide a real CRL file from trusted authority.

YuryStrozhevsky commented 3 years ago

Just for referense: even if a CRL is empty it must be signed by trusted authority.

YuryStrozhevsky commented 3 years ago

@themighty1 Also do not forget CRLs for all intermediate certificates.

themighty1 commented 3 years ago

@YuryStrozhevsky , thanks, but if CRLs are mandatory, please help me understand why I was getting a correct verification in my code (running in browser environment ) when supplying crls: []

const ccve = new CertificateChainValidationEngine({
      trustedCerts: trustedCertificates,
      certs: chain,
      crls: [],
    });

let pr = await ccve.verify()
return pr.result

would return true.

YuryStrozhevsky commented 3 years ago

@themighty1 Have you tried to run the live example with all necessary CRLs? If so and you got the correct result then please close the issue.

themighty1 commented 3 years ago

Unfortunately, one of the CRL files from http://crl3.digicert.com/ssca-sha2-g6.crl is 17MB in size and when I feed it to the live example page's field "Load CRLs (binary):" my browser consumes 2-3GB of RAM and the tab hangs for 1 minute.

Should I open a separate issue for that or is this expected because the CRL file is so large?

rmhrisk commented 3 years ago

Please create a bug for your new issue.

themighty1 commented 3 years ago

After I used the CRL files, I still got Verification result: false

The site is google.com In Chrome's Certificate Viewer I exported leaf,intermediate and root certs as DER also downloaded CRLs from the URL in the cert's "CRL Distribution Points" http://crl.pki.goog/GTS1O1core.crl http://crl.pki.goog/gsr2/gsr2.crl

Select trusted certs (binary): root (also tried root + intermediate) Load intermediate certificates (binary): leaf + intermediate Load CRLs (binary): CRL for leaf and CRL for intermediate

rmhrisk commented 3 years ago

@YuryStrozhevsky please advise

YuryStrozhevsky commented 3 years ago

Please attach all user certificates here

themighty1 commented 3 years ago

leaf cert:

_.google.com.txt

intermediate:

GTS CA 1O1.txt

root cert:

Builtin Object Token_GlobalSign Root CA - R2.txt

microshine commented 3 years ago

Here is NodeJS example. cert1, cert2 and cert3 are google certificates

const pkijs = require("pkijs");
const asn1js = require("asn1js");
const fs = require("fs");
const { Crypto } = require("@peculiar/webcrypto");

const crypto = new Crypto();
const name = "@peculiar/webcrypto";
pkijs.setEngine(name,
  new pkijs.CryptoEngine({ name, crypto, subtle: crypto.subtle }),
  new pkijs.CryptoEngine({ name, crypto, subtle: crypto.subtle }))

function readCertificate(path) {
  const pem = fs.readFileSync(path, {encoding: "utf-8"});
  let base64 = pem
    .replace(/-{5}(BEGIN|END) CERTIFICATE-{5}/g, "")
    .replace(/[\r\n ]/g, "");
  const raw = Buffer.from(base64, "base64");
  const cert = new pkijs.Certificate({ schema: asn1js.fromBER(new Uint8Array(raw).buffer).result });
  return cert
}

function readCrl(path) {
  const raw = fs.readFileSync(path);
  const cert = new pkijs.CertificateRevocationList({ schema: asn1js.fromBER(new Uint8Array(raw).buffer).result });
  return cert
}

async function main() {
  const cert1 = readCertificate("cert1.pem"); // Cert
  const cert2 = readCertificate("cert2.pem"); // CA
  const cert3 = readCertificate("cert3.pem"); // Root CA

  const crls = [
    readCrl("gsr2.crl"),
    readCrl("GTS1O1core.crl"),
  ]

  const params = {
    checkDate: new Date(),
    certs: [cert2, cert3],
    crls,
    trustedCerts: [cert3],
  };

  const certificateChainEngine = new pkijs.CertificateChainValidationEngine(params);
  certificateChainEngine.certs.push(cert1); // leaf certificate must be last in the list
  const verificationResult = await certificateChainEngine.verify();
  console.log(verificationResult);
}

main().catch(e => console.error(e));

Out

{
  result: true,
  resultCode: 0,
  resultMessage: '',
  authConstrPolicies: [ '2.23.140.1.2.2' ],
  userConstrPolicies: [ '2.5.29.32.0' ],
  explicitPolicyIndicator: false,
  policyMappings: [ <2 empty items> ],
  certificatePath: [
    Certificate {
      tbs: [ArrayBuffer],
      version: 2,
      serialNumber: [Integer],
      signature: [AlgorithmIdentifier],
      issuer: [RelativeDistinguishedNames],
      notBefore: [Time],
      notAfter: [Time],
      subject: [RelativeDistinguishedNames],
      subjectPublicKeyInfo: [PublicKeyInfo],
      signatureAlgorithm: [AlgorithmIdentifier],
      signatureValue: [BitString],
      extensions: [Array]
    },
    Certificate {
      tbs: [ArrayBuffer],
      version: 2,
      serialNumber: [Integer],
      signature: [AlgorithmIdentifier],
      issuer: [RelativeDistinguishedNames],
      notBefore: [Time],
      notAfter: [Time],
      subject: [RelativeDistinguishedNames],
      subjectPublicKeyInfo: [PublicKeyInfo],
      signatureAlgorithm: [AlgorithmIdentifier],
      signatureValue: [BitString],
      extensions: [Array]
    },
    Certificate {
      tbs: [ArrayBuffer],
      version: 2,
      serialNumber: [Integer],
      signature: [AlgorithmIdentifier],
      issuer: [RelativeDistinguishedNames],
      notBefore: [Time],
      notAfter: [Time],
      subject: [RelativeDistinguishedNames],
      subjectPublicKeyInfo: [PublicKeyInfo],
      signatureAlgorithm: [AlgorithmIdentifier],
      signatureValue: [BitString],
      extensions: [Array]
    }
  ]
}