trasherdk / jsrsasign

The 'jsrsasign' (RSA-Sign JavaScript Library) is an opensource free cryptography library supporting RSA/RSAPSS/ECDSA/DSA signing/validation, ASN.1, PKCS#1/5/8 private/public key, X.509 certificate, CRL, OCSP, CMS SignedData, TimeStamp, CAdES JSON Web Signature/Token in pure JavaScript.
https://kjur.github.com/jsrsasign
Other
0 stars 0 forks source link

Snippet: Verify Certificate against a root Cert #3

Open trasherdk opened 2 years ago

trasherdk commented 2 years ago

2 snippets to check if I can identify witch intermediate CA signed a client certificate.

/**
 * Takes a PEM encoded certificate chain array and verifies it
 * @param  {String[]} certificates - PEM certificate chain
 * @return {Boolean}               - Returns if certificate chain can be validated
 */
var verifyCertificateChain = (certificates) => {
    let valid = true;

    for(let i = 0; i < certificates.length; i++) {
        let Cert        = certificates[i];
        let certificate = new jsrsasign.X509();
        certificate.readCertPEM(Cert);

        let CACert = '';
        if(i + 1 >= certificates.length) {
            CACert = Cert;
        } else {
            CACert = certificates[i + 1];
        }

        let certStruct   = jsrsasign.ASN1HEX.getTLVbyList(certificate.hex, 0, [0]);
        let algorithm    = certificate.getSignatureAlgorithmField();
        let signatureHex = certificate.getSignatureValueHex()

        // Verify against CA
        let Signature = new jsrsasign.crypto.Signature({alg: algorithm});
        Signature.init(CACert);
        Signature.updateHex(certStruct);
        valid = valid && Signature.verify(signatureHex); // true if CA signed the certificate
    }

    return valid
}

Source: https://github.com/kjur/jsrsasign/issues/176#issuecomment-373639945

And a second, simpler, version:

const verifyCertificateChain = (certificates) => {
    let valid = true;
    for(let i = 0; i < certificates.length; i++) {
    let issuerIndex = i + 1;
    // If i == certificates.length - 1, self signed root ca
    if (i == certificates.length - 1) issuerIndex = i;
    issuerPubKey = jsrsasign.KEYUTIL.getKey(certificates[issuerIndex]);
        const certificate = new jsrsasign.X509(certificates[i]);
        valid = valid && certificate.verifySignature(issuerPubKey);
    }

    return valid;
}

Source: https://github.com/kjur/jsrsasign/issues/176#issuecomment-1073434816

yogeshwar-chaudhari-20 commented 2 years ago

@trasherdk Hey, is there any inbuilt function for validating the certificate chain using a trusted root certificate?

There is a library named node-forge that has this functionality. However, that is not working with apple's certificates.

const rootCert = pki.certificateFromPem(rootCertPemStr); const caStore = pki.createCaStore([rootCert]); const x509CertificateChain = // x509 certificate objects const validity = pki.verifyCertificateChain(caStore, x509CertificateChain);

trasherdk commented 2 years ago

@yogesh-chaudhari-77 Probably not. I think @kjur would have mentioned it in the linked response.

Anyway. The above snippet should run through the certificate chain, so you can verify the signer of your certificate is in there.

trasherdk commented 2 years ago

Or the other way around. Your root should be signing, or actually be, the first cert in the chain.

yogeshwar-chaudhari-20 commented 2 years ago

@trasherdk Thanks for such a prompt response. Yes for time being I appended the root certificate into the certificates and it worked for me as expected. However, certificate chain validation is quite a common use case that should be part of the library itself.