Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Intermittent ERR_OSSL_ASN1_ILLEGAL_PADDING error decoding certificates #74

Open
achingbrain opened this issue Mar 29, 2024 · 0 comments

Comments

@achingbrain
Copy link

achingbrain commented Mar 29, 2024

I'm not quite sure what's going on here, but sometimes I can generate a self-signed x509 certificate that node's TLSSocket rejects with an ERR_OSSL_ASN1_ILLEGAL_PADDING error.

I think it's related to the serial number field, some values seem to not work

Here are some example certificates:

Serial number 80048117884272

-----BEGIN CERTIFICATE-----
MIIBdDCCARugAwIBAgIIN0FJVxNJMTcwCgYIKoZIzj0EAwIwADAeFw0yNDAzMjkw
NzAwNDlaFw0zNDAzMjcwODAwNDlaMAAwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNC
AAQ1arYefooX/Y3HZBUmx0Z+rlpnR5u+N82aO+77a+qGk5jVArQteAlP9ejlnw/g
DT30Tf9CS5ZKQywIxLe+UBkoo38wfTB7BgorBgEEAYOiWgEBAQH/BGowaAQkCAES
ILTRpIzei9gsWWw9jlM8HUh52s5bJ6f1fIUT10JO0qFCBECXmPerzoBc9288gwRq
gOUaP7XWM7ptrzVyuk2ojUEJrId0gt+WBHL6451bBK65SPw+NS00Lh0MAIT72vrF
+FMAMAoGCCqGSM49BAMCA0cAMEQCIBmkSvawNuaQVbjHDvLAaJZhyXS+yKpOsjBf
o6Q6qCcUAiB6yQxYTQEiWTkjaRaeFTqwmg3WLLjMcL7TU4jx9JyTPg==
-----END CERTIFICATE-----

Serial number 80284629184668

-----BEGIN CERTIFICATE-----
MIIBdTCCARqgAwIBAgIHAChGKRhGaDAKBggqhkjOPQQDAjAAMB4XDTI0MDMyOTA4
MTA0MloXDTM0MDMyNzA5MTA0MlowADBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IA
BM+9jxG60ibilrh/tMckZnZlRy+YKr4wIsdCEVhrkohX3CzQGforRUWj3Gd+fgxC
sjzCqlE1+wEacO8WcG5BQXujfzB9MHsGCisGAQQBg6JaAQEBAf8EajBoBCQIARIg
+Tf7EqCTFrZpts0JeNgacbEtTw9i5eN8PXtE1X5Hi+wEQIAYNPej0VxkWcLPfU29
TUX0OF3binlvEDOXKbSgOgtRh84nMH7ZzxDkP+2nx11azPBG7fe+kfyHzStFer2W
gwAwCgYIKoZIzj0EAwIDSQAwRgIhALA1mqPIpAfV5F5Lbi5fziHlF8ZavyoGZOp2
uUXQW9xxAiEApLXWM+TKI5KkWBZ11yodUR++nao+013OeY1SoEi4YuQ=
-----END CERTIFICATE-----

Serial number 80290967596123

-----BEGIN CERTIFICATE-----
MIIBdDCCARqgAwIBAgIHACkJZ1lhIzAKBggqhkjOPQQDAjAAMB4XDTI0MDMyOTA5
Mzk0MFoXDTM0MDMyNzEwMzk0MFowADBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IA
BJwqZR4Mm9VX9qAp7vLRqXixbrN5ijc59+dAY2kKZZ/73mr1TKymgpmtB1s4/kDr
MxhpCsanxaLTkQmHEK9EwAijfzB9MHsGCisGAQQBg6JaAQEBAf8EajBoBCQIARIg
qNcdQX5sb5EnD38brTMGBxtMJ8ySzQcy85P1CYgjpycEQIsgOFHnDyFMpfqybhrO
7akur71S94GtSeyspn7ye1I6qumJffhVKZbJxf0dbhwu8z5ca22gPZt4UuOh4ayt
UAgwCgYIKoZIzj0EAwIDSAAwRQIgGvZQf/hL0mPGVzw8vC2KxItclYXIOnsU/aka
iYdwuY0CIQDEBHE84znRpGCwzAhmMnhwM5JvTyMi1jBijZhJ5KvPMA==
-----END CERTIFICATE-----

Serial number 8070459553297620

-----BEGIN CERTIFICATE-----
MIIBdjCCARugAwIBAgIIAHBFlVMpdiAwCgYIKoZIzj0EAwIwADAeFw0yNDAzMjkx
MDQ5MDJaFw0zNDAzMjcxMTQ5MDJaMAAwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNC
AARccRhCabh1rQMNXr1zz/jB4Hot/n+VIL4IysnGaBoaEZLo2vqpoWhXgH2Sz7/5
FzvRofDNlDtK5Jp8su+1OoWeo38wfTB7BgorBgEEAYOiWgEBAQH/BGowaAQkCAES
IMZ/hZH1YUoiVmUjNMmxKxp7rzkP1K/cCTPOT481M7xLBEB8eUQ79y7vUgwggOG4
J0pEqTRVi1rh0XzcFUZuwhdA3/TQ/He/1KNSQ2z2x+hxCKnoWzt68jPA2gwNuWRu
qMUEMAoGCCqGSM49BAMCA0kAMEYCIQCQbANLI26dzckKMIWaYIjme6/tBMNAtLXo
3oWWyt3EfgIhAKD8K6As+3sZ0p1SjiLi/BX8x+wAU6NI42SW8ua63doP
-----END CERTIFICATE-----

Weirdly they all begin with 80, I don't know if that means anything or it's just a coincidence.

Serial number 801234

-----BEGIN CERTIFICATE-----
MIIBMjCB2aADAgECAgMAEjQwCgYIKoZIzj0EAwIwIDENMAsGA1UEAxMEVGVzdDEP
MA0GA1UECgwG0JTQvtC8MB4XDTIwMDEwMTAwMDAwMFoXDTIwMDEwMjAwMDAwMFow
IDENMAsGA1UEAxMEVGVzdDEPMA0GA1UECgwG0JTQvtC8MFkwEwYHKoZIzj0CAQYI
KoZIzj0DAQcDQgAEUwBK1GpQJ4VxwktgsRBbl+xcy3Pk6vCKxUDTEuaz49tA1mR/
1JFIh4t0KTrmuLuX0nA8+gc/VKIyDH1APccz4aMCMAAwCgYIKoZIzj0EAwIDSAAw
RQIhAPf7yZpUymNFDOT/SPdtUg9VSXDe5UE6PlxAxyxVXnkfAiBCEV2SOWFKSmPS
NhUpJtcMgxHupLeCWrFon6SSGUDJRw==
-----END CERTIFICATE-----

Here's a reproduction. The serial numbers from above cause new TLSSocket to throw Error: error:068000DD:asn1 encoding routines::illegal padding, the default serial number of "01" does not.

import * as x509 from '@peculiar/x509'
import { Crypto } from '@peculiar/webcrypto'
import { Socket } from 'net'
import { TLSSocket } from 'tls'

const crypto = new Crypto()
x509.cryptoProvider.set(crypto)

const keys = await crypto.subtle.generateKey({
  name: 'ECDSA',
  namedCurve: 'P-256',
}, true, ['sign'])

const cert = await x509.X509CertificateGenerator.createSelfSigned({
  // will throw
  serialNumber: '80048117884272',

  // does not throw
  //serialNumber: '01',

  // ...other certificate parameters
  name: 'CN=Test, O=Дом',
  notBefore: new Date('2020/01/01'),
  notAfter: new Date('2020/01/02'),
  signingAlgorithm: {
    name: 'ECDSA',
    hash: 'SHA-256',
  },
  keys: keys
})

// throws with certain serial numbers
new TLSSocket(new Socket(), {
  cert: cert.toString(),
  key: await privateKeyToPEM(keys)
})

// helper to transform a private key to PEM format
async function privateKeyToPEM (keys) {
  const arrayBuffer = await crypto.subtle.exportKey('spki', keys.privateKey)
  let str = Buffer.from(arrayBuffer).toString('base64')
  let finalString = '-----BEGIN PRIVATE KEY-----\n'

  while (str.length > 0) {
    finalString += str.substring(0, 64) + '\n'
    str = str.substring(64)
  }

  finalString = finalString + '-----END PRIVATE KEY-----'

  return finalString
}
achingbrain added a commit to libp2p/js-libp2p that referenced this issue Mar 31, 2024
This is a hack to work around PeculiarVentures/x509#74
until it is addressed upstream.

It seems serial numbers starting with `80` cause `@peculiar/x509` to
generate invalid certifiates that Node's `TLSSocket` then fails to
parse, throwing an `ERR_OSSL_ASN1_ILLEGAL_PADDING` error, so the hack
is to generate serial numbers until we get one that doesn't start with
`80`.

This can be reverted when the upstream issue is fixed.
achingbrain added a commit to libp2p/js-libp2p that referenced this issue Apr 2, 2024
This is a hack to work around PeculiarVentures/x509#74
until it is addressed upstream.

It seems serial numbers starting with `80` cause `@peculiar/x509` to
generate invalid certifiates that Node's `TLSSocket` then fails to
parse, throwing an `ERR_OSSL_ASN1_ILLEGAL_PADDING` error, so the hack
is to generate serial numbers until we get one that doesn't start with
`80`.

This can be reverted when the upstream issue is fixed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant