PeculiarVentures / pvutils

pvutils is a set of common utility functions used in various Peculiar Ventures Javascript based projects.
Other
7 stars 13 forks source link

bufferToHexCodes with initial "00" in certificate serial number #15

Open a-tortevois opened 1 month ago

a-tortevois commented 1 month ago

Hello,

The initial "00" does not appear to be significant and is not implemented on the standard node:crypto X509Certificate when we get the serial number. Source: https://stackoverflow.com/questions/45821143/ssl-certificates-leading-zeros-are-displayed-in-windows-but-not-unix-ksh-shell https://openssl-users.openssl.narkive.com/Pds1yxYr/leading-zeros-in-serial-numbers#

How to reproduce this issue :

Generate a random 12-bytes serial number

openssl rand -hex 12
87d2fc16d9e738998f1f92c1

Convert it as integer

BigInt('0x87d2fc16d9e738998f1f92c1')
42035541205884290034770612929n

Create a certificate with the following openssl command:

openssl req -x509 -new -newkey rsa:2048 -days 365 -nodes -keyout key.pem -out cert.crt -set_serial 42035541205884290034770612929

Then on node:

import crypto from 'node:crypto';
import fs from 'node:fs';

const pem = fs.readFileSync('cert.crt', 'utf8').toString();
const certificate = new crypto.X509Certificate(pem);
console.log(certificate);

Result:

X509Certificate {
  subject: 'C=AU\nST=Some-State\nO=Internet Widgits Pty Ltd',
  subjectAltName: undefined,
  issuer: 'C=AU\nST=Some-State\nO=Internet Widgits Pty Ltd',
  infoAccess: undefined,
  validFrom: 'Jul 25 11:43:39 2024 GMT',
  validTo: 'Jul 25 11:43:39 2025 GMT',
  fingerprint: 'D4:C3:55:4C:33:11:9F:0D:93:29:3F:C0:B3:C5:D1:D6:EF:A9:7D:A7',
  fingerprint256: '36:35:19:84:3F:22:05:6D:73:6E:FB:A9:6A:60:C0:74:09:4E:7D:35:4A:9B:F0:E6:9A:9B:8D:BE:0B:BB:82:BF',
  fingerprint512: 'E1:40:0B:6F:E6:34:73:8C:85:C2:F8:F7:02:0E:93:74:AA:EE:7F:45:F1:6E:DF:C2:A1:50:38:39:83:C3:20:A3:69:82:B7:F0:43:AE:44:24:9F:EF:BF:BD:2C:F5:DC:33:6E:B3:AE:82:B6:BF
:1F:8E:EA:E0:32:66:1F:49:15:97',
  keyUsage: undefined,
  serialNumber: '87D2FC16D9E738998F1F92C1'
}

Now with this code:

import fs from 'node:fs';
import asn1 from 'asn1js';
import pkijs from 'pkijs';
import pvutils from 'pvutils';

const pem = fs.readFileSync('cert.crt', 'utf8').toString();
const b64 = pem.replace(/(-----(BEGIN|END) CERTIFICATE-----|[\n\r])/g, '')
const der = Buffer.from(b64, 'base64')
const ber = Buffer.from(new Uint8Array(der))
const asn1Cert = asn1.fromBER(ber)
const certificate = new pkijs.Certificate({ schema: asn1Cert.result })
const serialNumber = pvutils.bufferToHexCodes(certificate.serialNumber.valueBlock.valueHexView)
console.log('serialNumber', serialNumber);

Result:

serialNumber 0087D2FC16D9E738998F1F92C1

Check with openssl

openssl x509 -in cert.crt -noout -text
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number:
            87:d2:fc:16:d9:e7:38:99:8f:1f:92:c1
        Signature Algorithm: sha256WithRSAEncryption

Could you fix the bufferToHexCodes method to not return the initial "00" if they are not needed ?

yadvendrapalsingh commented 1 month ago

We are also facing the same issue on our project. We are verifying the serial numbers but the lost 00 is causing issues.