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.27k stars 643 forks source link

X.509 certificate parsing truncates custom/non-standard extension attributes #570

Closed bestbeforetoday closed 1 year ago

bestbeforetoday commented 1 year ago

When using jsrsasign@10.6.1 to parse an X.509 certificate and extract a custom extension attribute as follows, the attribute value appears to be truncated:

const pem = '-----BEGIN CERTIFICATE-----\n' +
    'MIICoDCCAkegAwIBAgIUJKhPigmSNKidUygsxFnGOxDf9yMwCgYIKoZIzj0EAwIw\n' +
    'czELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNh\n' +
    'biBGcmFuY2lzY28xGTAXBgNVBAoTEG9yZzEuZXhhbXBsZS5jb20xHDAaBgNVBAMT\n' +
    'E2NhLm9yZzEuZXhhbXBsZS5jb20wHhcNMjIxMTIzMTAzODAwWhcNMjMxMTIzMTA0\n' +
    'MzAwWjBCMTAwDQYDVQQLEwZjbGllbnQwCwYDVQQLEwRvcmcxMBIGA1UECxMLZGVw\n' +
    'YXJ0bWVudDIxDjAMBgNVBAMTBXRlc3QyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcD\n' +
    'QgAETKt7K0QONLgI46QIMYAyF17F2TD6Z7bfi6Ej+397VTY+/vy0lUsK4F7hC2GY\n' +
    'fWTmLxyc1IlKNt0ORoG0Ygdv0KOB6TCB5jAOBgNVHQ8BAf8EBAMCB4AwDAYDVR0T\n' +
    'AQH/BAIwADAdBgNVHQ4EFgQUqJT4nxvwJFwhx0iD9CgJQd/sU+gwKwYDVR0jBCQw\n' +
    'IoAgywWoO3TYtt+B+VSkVbaW5XDrzmGGw3ejVOAI7usR0E4wegYIKgMEBQYHCAEE\n' +
    'bnsiYXR0cnMiOnsiZWNlcnQiOiJkZWZhdWx0IiwiaGYuQWZmaWxpYXRpb24iOiJv\n' +
    'cmcxLmRlcGFydG1lbnQyIiwiaGYuRW5yb2xsbWVudElEIjoidGVzdDIiLCJoZi5U\n' +
    'eXBlIjoiY2xpZW50In19MAoGCCqGSM49BAMCA0cAMEQCIBf8RlrQ58cKCgYEqN8K\n' +
    'kSbWPwgl9dcskZ4TbNmfkA+FAiA+li8Qeai87qhO/zA3AuSPi0Y15rcSbX+IaeQh\n' +
    'IuKLbA==\n' +
    '-----END CERTIFICATE-----\n';
const cert = new X509();
cert.readCertPEM(pem);
const params = cert.getParam();
const extension = cert.findExt(params.ext, '1.2.3.4.5.6.7.8.1');

The value of extension returned by the call to cert.findExt() in this case is:

{
    extname: '1.2.3.4.5.6.7.8.1',
    extn: '7b226174747273223a7b226563657274223a2264656661756c74222c2268662e41666669'
}

The value is expected to be the following JSON string:

{"attrs":{"ecert":"default","hf.Affiliation":"org1.department2","hf.EnrollmentID":"test2","hf.Type":"client"}}

Converting the hex extn value above to a string gives the following truncated result:

{"attrs":{"ecert":"default","hf.Affi
kjur commented 1 year ago

Thank you for your report. I'll check.

kjur commented 1 year ago

In my current implementation, "extn" value will not be parsed. https://github.com/kjur/jsrsasign/blob/8625124366ef2f6a4adc438f38d31a482c3456e3/src/x509-1.1.js#L3026-L3028

I'll update to support ASN.1 structure represented by JSON in "extn" by using ASN1HEX.parse in the future version: https://kjur.github.io/jsrsasign/api/symbols/ASN1HEX.html#.parse

BTW, '7b226174747273223a7b226563657274223a2264656661756c74222c2268662e41666669' is not a proper ASN.1 hexadecimal string. This will not be parsed even though I'll support such function as above.

bestbeforetoday commented 1 year ago

BTW, '7b226174747273223a7b226563657274223a2264656661756c74222c2268662e41666669' is not a proper ASN.1 hexadecimal string. This will not be parsed even though I'll support such function as above.

You are absolutely correct! The reason it is not a proper hexadecimal string appears to be that jsrsasign failed to parse the certificate correctly. If you decode the certificate with another tool you can see the expected output. For example in the Raw output section of this decoder:

http://www.sslchecker.com/certdecoder?su=ec5113d4f04beffc8789852b4632a7e6

I see you have closed the issue but I don't see any associated pull request or commit in jsrsasign. Has this issue been resolved and, if so, where can I pick up the fix?

kjur commented 1 year ago

Your private extension is not proper extension value since extnValue is not encapsulated OCTET STRING. That's why no need to any fix.