Skip to content

Fix PEM encoding for RSA private keys#180

Merged
cpu merged 1 commit intoC2SP:mainfrom
davidben:fix-pem
Sep 15, 2025
Merged

Fix PEM encoding for RSA private keys#180
cpu merged 1 commit intoC2SP:mainfrom
davidben:fix-pem

Conversation

@davidben
Copy link
Contributor

@davidben davidben commented Sep 3, 2025

The originally generator code systematically encoded RSA private keys in PEM wrong. Fixes #178.

import base64
import json
import sys

def key_to_pem(key: bytes) -> str:
    ret = "-----BEGIN PRIVATE KEY-----\n"
    b64 = base64.b64encode(key).decode("ascii")
    while b64:
        l = min(len(b64), 64)
        ret += b64[:l]
        ret += "\n"
        b64 = b64[l:]
    ret += "-----END PRIVATE KEY-----\n"
    return ret

def fix(path: str):
    with open(path) as f:
        orig = f.read()
        j = json.loads(orig)
    changed = False
    for g in j["testGroups"]:
        if g["type"] not in ("RsaesOaepDecrypt", "RsaesPkcs1Decrypt"):
            continue
        pk8 = bytes.fromhex(g["privateKeyPkcs8"])
        # Spot-check that this is a PKCS #8 blob and not, say, RSAPrivateKey.
        # This is the rsaEncryption OID.
        assert bytes.fromhex("2a864886f70d010101") in pk8
        g["privateKeyPem"] = key_to_pem(pk8)
        changed = True
    if changed:
        with open(path, "w") as f:
            json.dump(j, f, indent=2, separators=(",", " : "))
            f.write("\n")

for arg in sys.argv[1:]:
    fix(arg)

The originally generator code systematically encoded RSA private keys in
PEM wrong. Fixes C2SP#178.

```
import base64
import json
import sys

def key_to_pem(key: bytes) -> str:
    ret = "-----BEGIN PRIVATE KEY-----\n"
    b64 = base64.b64encode(key).decode("ascii")
    while b64:
        l = min(len(b64), 64)
        ret += b64[:l]
        ret += "\n"
        b64 = b64[l:]
    ret += "-----END PRIVATE KEY-----\n"
    return ret

def fix(path: str):
    with open(path) as f:
        orig = f.read()
        j = json.loads(orig)
    changed = False
    for g in j["testGroups"]:
        if g["type"] not in ("RsaesOaepDecrypt", "RsaesPkcs1Decrypt"):
            continue
        pk8 = bytes.fromhex(g["privateKeyPkcs8"])
        # Spot-check that this is a PKCS C2SP#8 blob and not, say, RSAPrivateKey.
        # This is the rsaEncryption OID.
        assert bytes.fromhex("2a864886f70d010101") in pk8
        g["privateKeyPem"] = key_to_pem(pk8)
        changed = True
    if changed:
        with open(path, "w") as f:
            json.dump(j, f, indent=2, separators=(",", " : "))
            f.write("\n")

for arg in sys.argv[1:]:
    fix(arg)
```
Copy link
Member

@cpu cpu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you 🙇 LGTM

@cpu cpu merged commit 999222b into C2SP:main Sep 15, 2025
1 check passed
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

Successfully merging this pull request may close these issues.

PSS privateKeyPem for many tests have incorrect PEM headers

2 participants