Skip to content

Fix/verify csr exact subject - #183

Open
benjamsf wants to merge 6 commits into
mainfrom
fix/verify-csr-exact-subject
Open

benjamsf wants to merge 6 commits into
mainfrom
fix/verify-csr-exact-subject

Conversation

@benjamsf

Copy link
Copy Markdown
Member

Description

verify_csr matched the callsign as a substring of the rendered RFC4514 subject and never checked
the request signature.

Old behavior:

CSR subject callsign before
CN=OTTER1X OTTER1 passes
OU=CN=OTTER1,CN=ADMIN OTTER1 passes, and the issued certificate says CN=ADMIN

The CA signs the request as presented and the mTLS edge authorises on the CN it reads from the certificate, so it may issue a working identity for a callsign the requester was never granted if so asked.

The missing signature check means we have no proof the requester holds the private key, and an
unverifiable request is still handed to the CA. The CA rejects it only after
Person.create_with_cert has already committed the Person row, so the callsign is spent for good.

Now it compares the parsed CN attributes and requires exactly one equal to the callsign, plus
csr.is_signature_valid. Attributes other than CN are still allowed: an MDM filling a subject
template may add O or OU, and nothing downstream reads them.

  • Adds a test at tests/test_csr_utils.py

Anything Else You'd Like to Mention

Groundwork for MDM driven device enrolment, where a certificate request is approved without a human
looking at it and this becomes the only subject gate before the CA signs.

…ped through

The check was a substring test on the RFC4514 form of the CSR subject and did not
look at the signature at all. Both matter more than they look.

The subject test accepted a CSR whose CN merely started with the callsign
(CN=OTTER1X for OTTER1), and accepted one that carried the callsign in some other
attribute while the real CN was something else entirely (OU=CN=OTTER1,CN=ADMIN).
The CA signs the request as presented and the mTLS edge authorises on the CN it
reads from the certificate, so the second case issues a working identity for a
callsign the requester was never granted. Compare the parsed CN attributes
instead, and require exactly one equal to the callsign. Other attribute types are
still allowed: an MDM filling a subject template may add O or OU and nothing
downstream reads them.

The missing signature check meant we had no proof the requester held the private
key. Worse, an unverifiable request was still passed to the CA, which rejects it
only after Person.create_with_cert has committed the Person row, spending that
callsign for good.

Adds tests/test_csr_utils.py. Every negative case in it was accepted before.
CN=OTTER1X passed for OTTER1, and OU=CN=OTTER1,CN=ADMIN passed while the cert
the CA issued said ADMIN. Now compares parsed CN attributes, and checks the
signature so an unverifiable request never reaches the CA.
…on-rasenmaeher-api into fix/verify-csr-exact-subject
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.

1 participant