Repository navigation
Make XMSS/XMSS^MT generated OIDs and public key format RFC conforming - #5933
falko-strenzke wants to merge 2 commits into
Conversation
randombit
left a comment
There was a problem hiding this comment.
Looks ok to me, needs a rebase to address a merge conflict, also the cli tests are failing, will need to update the expected outputs for the XMSS test.
864c43b to
a707e59
Compare
| // RFC 9802 places the raw XMSS public key directly into the SubjectPublicKeyInfo | ||
| // BIT STRING. Earlier Botan versions (following draft-vangeest-x509-hash-sigs) | ||
| // wrapped the raw key in an OCTET STRING; such keys are still accepted here. | ||
| std::vector<uint8_t> extract_raw_public_key(std::span<const uint8_t> key_bits) { |
There was a problem hiding this comment.
I'm not very familiar with the historical sequence of changes here (esp wrt the spec itself), but
It seems like historically we've accepted either DER or raw bytes under the old draft OID. We always emitted the DER wrapper. And when I dig into the history further it seems like the raw byte encoding was our encoding approach prior to 2.13, and so we retained it for compatibility with old keys after support for the draft spec, which added the DER wrapper, was included. But we also encoded such pre-2.13 raw keys under a Botan private-arc OID which we no longer support....
Under the new OID, the rule is clear - only the raw encoding is valid.
So it seems like at the very least we should, for the new OID, require that it not be DER wrapped, and skip the decoding attempt. And I think that practically, due to the sequence of incompatible changes made to XMSS over the years due to chasing the specification, no keys exist anywhere which both use the draft OID and the raw encoding.
So extract_raw_public_key should imo skip the sniffing altogether and dispatch based on OID instead.
There was a problem hiding this comment.
@randombit
I have implemented that now. It turns out that had to touch the private decoding as well, which previously forwarded an ambigous private key to its public key base. I have generated these figures to illustrate the flows before and after this change.
…based dispatching
This PR fixes the problem that Botan currently emits the pre-RFC XMSS OID 0.4.0.127.0.15.1.1.13.0 (from
draft-vangeest-x509-hash-sigs-03) in SubjectPublicKeyInfo, PKCS#8 keys and
certificate signature AlgorithmIdentifiers. RFC 9802 (June 2025) assigns
1.3.6.1.5.5.7.6.34 (XMSS) and 1.3.6.1.5.5.7.6.35 (XMSS^MT).
There is a related non-compliance that this PR fixes: RFC 9802
§5.2 says the XMSS public key goes into the SPKI BIT STRING with no ASN.1
wrapping, but XMSS_PublicKey::public_key_bits() wraps the raw key in an
OCTET STRING (the draft-era ISARA and BouncyCastle test certs use that wrapping;
the RFC sample cert does not). The decoder already accepts both forms.
Logical changes
legacy name; add both XMSS^MT OIDs; fix HSS-LMS comment.
SPKI matches RFC 9802 §5.2. (Decoding fallback already exists; the PKCS#8
private key payload stays as is, since no standard defines it.)
the two legacy certs as regression tests for the old OID + wrapped key, and
add a unit test asserting the emitted SPKI OID and unwrapped payload.