kjur / 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 and JSON Web Signature/Token in pure JavaScript.
https://kjur.github.io/jsrsasign
Other
3.25k stars 646 forks source link

Need support to check if a cert is CA or not #132

Closed huma-hamid closed 8 years ago

huma-hamid commented 8 years ago

Does jsrsasign expose that information already or how do check if a cert is ca or not?

kjur commented 8 years ago

I hope the following function can check CA or not.

function isCACert(certPEM) {
  try {
    var hCert = KEYUTIL.getHexFromPEM(certPEM);
    var hExtnValue = X509.getHexOfV_V3ExtValue(hCert, "basicConstraints");
    var result = false;
    var iIdx = ASN1HEX.getNthChildIndex_AtObj(hExtnValue, 0, 0);
    var hCaFlag = ASN1HEX.getHexOfTLV_AtObj(hExtnValue, iIdx);
    if (hCaFlag == "0101FF") return true;
    return result;
  } catch (ex) {
    return false;
  }
}
huma-hamid commented 8 years ago

Great - Thank you

huma-hamid commented 8 years ago

I have tried this code snippet to check two certs, one CA and other not (tested them first using OPENSSL). In both cases I got result equals false. Which means it's not detecting a CA cert correctly. Here is what I got for both the certs:

hExtnValue => '0101ff' iIdx = 4 hCaFlag = 'ff' (which is not equal to expected value of 0101FF).

I have following questions:

Is it possible for X509 class to make this CA flag value available to fetch while reading readCertPEM(), just like we can do in openssl?

Thanks

kjur commented 8 years ago

I'll check it later.

kjur commented 8 years ago

Sorry I've fixed the code and confirmed it works:

I hope the following function can check CA or not.

function isCACert(certPEM) {
  try {
    var hCert = KEYUTIL.getHexFromPEM(certPEM);
    var hExtnValue = X509.getHexOfTLV_V3ExtValue(hCert, "basicConstraints");
    var result = false;
    var iIdx = ASN1HEX.getNthChildIndex_AtObj(hExtnValue, 0, 0);
    var hCaFlag = ASN1HEX.getHexOfTLV_AtObj(hExtnValue, iIdx);
    if (hCaFlag == "0101FF") return true;
    return result;
  } catch (ex) {
    return false;
  }
}
huma-hamid commented 8 years ago

I have verified it works correctly now (for CA and non-CA cert of V3). Thank you!

However, there is one more issue I have found. I was getting a false positive while checking CA for a v1 certificate. On further investigation, I found that the actual issue was that jsrsasign threw exception when I was trying to extract a public key from a v1 cert. openssl extracts public key from the same cert correctly. v3 certificates showed no issues.

Here is what I am doing:

var cert = new jsrsasign.X509();
cert.readCertPEM(certPEM);
var publicKey = jsrsasign.X509.getPublicKeyFromCertPEM(certPEM);

Error:

malformed X.509 certificate PEM (code:003)
kjur commented 8 years ago

I'm sorry but currently v1 certificate not supported. I'll close this ticket. Thanks.

cblair commented 8 years ago

kjur, what sort of effort would be required to support v1? Generally, which sections of code would have to be modified? We're considering making this modification and want gauge the work.

Thanks!

kjur commented 8 years ago

I think x509.js and asn1x509.js are needed to be updated.

cblair commented 8 years ago

Great, thanks!