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

Confusion around generating valid certificate chains #291

Closed wbl closed 3 years ago

wbl commented 3 years ago

Similar to issue #289 I've been trying to write code using PKI.js to generate a valid certificate chain and CRLs, and then verify a certificate. Unfortunately I've been unable to do so: my current efforts at patching together the examples haven't succeeded. I'm sure that this is almost certainly due to my ignorance of X509 related standards, but the lack of a a function similar to go's https://golang.org/pkg/crypto/x509/#CreateRevocationList doesn't help.

Is there an example of doing this that I've missed, or some convenient helper (perhaps in another project) I should be looking for?

rmhrisk commented 3 years ago

@wbl nice to see you here ;)

@microshine will help you but I suspect you may be better served by using the higher-level library we produce https://github.com/PeculiarVentures/x509/#build-a-certificate-chain.

microshine commented 3 years ago
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 raw = fs.readFileSync(path);
  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.cer"); // Cert
  const cert2 = readCertificate("cert2.cer"); // CA
  const cert3 = readCertificate("cert3.cer"); // Root CA

  const crls = [
    readCrl("crl1.crl"),
    readCrl("crl2.crl"),
  ]

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

  const certificateChainEngine = new pkijs.CertificateChainValidationEngine(params);
  certificateChainEngine.certs.push(cert1); // Certificate which must be verified must be at the end of cert array
  const verificationResult = await certificateChainEngine.verify();
  console.log(verificationResult);
}

main().catch(e => console.error(e));
wbl commented 3 years ago

Thanks for your assistance but I think there is some confusion. That reads in an already existing bunch of certificates from the filesystem. I want to generate cert1, cert2, cert3 and the CLRs with the library.

rmhrisk commented 3 years ago

https://github.com/PeculiarVentures/x509#create-a-self-signed-certificate

microshine commented 3 years ago

@peculiar/x509 doesn't implement Certificate Revocation List yet

rmhrisk commented 3 years ago

Can create the CRL with PKIjs directly but eventually we will get around to adding CRL to the higher level package.

wbl commented 3 years ago

Turns out that with empty lists of crls I was able to get it working: it was a bit annoying having to encode and then redecode to translate from x509 to PKI.js. Thank you for your help!

microshine commented 3 years ago

@wbl @peculiar/x509 has got it's own X509ChainBuilder (see example). It makes a simple chain validation (just a signature validation)