Skip to content

check request common name in cupsSignCredentialsRequest - #189

Open
tanjiroK-coder wants to merge 2 commits into
OpenPrinting:masterfrom
tanjiroK-coder:csr-commonname-check
Open

tanjiroK-coder wants to merge 2 commits into
OpenPrinting:masterfrom
tanjiroK-coder:csr-commonname-check

Conversation

@tanjiroK-coder

@tanjiroK-coder tanjiroK-coder commented Oct 21, 2026 •

Copy link
Copy Markdown
Contributor

cupsSignCredentialsRequest is given the common name the caller has approved and checks every subjectAltName DNS value in the request against it through the SAN callback, but the request's subject DN is copied into the new certificate without its commonName ever being looked at. A device whose CSR gets signed by the site CA (for example with cups-x509 ca NAME) can list its own name as the only SAN and put any other host in the CN. With OpenSSL the resulting certificate is accepted for the CN host because openssl_validate_name compares the subject CN before the SAN list, and with GnuTLS the signed certificate carries no extensions at all, so gnutls_x509_crt_check_hostname falls back to the CN. Either way cupsGetCredentialsTrust with require_ca returns HTTP_TRUST_OK for the impersonated host, which is what httpConnectURI and the OAuth code rely on. I confirmed it by signing a request for CN=authserver.example.com, DNS:altprinter as "altprinter" against a test site CA: cupsAreCredentialsValidForName("authserver.example.com", ...) was true and the trust check returned OK. The fix rejects a request whose commonName values do not all match the common name being signed, in both backends, the same way a bad subjectAltName is rejected. The new testcreds case uses an embedded CSR (CN=badprinter, DNS:altprinter) that both backends sign on master and refuse with this change, and make test passes with OpenSSL 4.0.3 and GnuTLS 3.8.13. The new error message is not in the .strings files yet.

Proposed changelog entry:

  • Fixed cupsSignCredentialsRequest to reject requests whose subject common name does not match the common name being signed.

@michaelrsweet michaelrsweet self-assigned this Oct 22, 2026
@michaelrsweet michaelrsweet added the investigating Investigating the issue label Oct 22, 2026

@michaelrsweet michaelrsweet left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

See comments; looks reasonable but I just want to confirm that the ASN1 stuff with OpenSSL is giving us a nul-terminated string...

Comment thread cups/tls-openssl.c Outdated
const ASN1_STRING *cn = X509_NAME_ENTRY_get_data(X509_NAME_get_entry(subject, i));
// commonName value

if ((size_t)ASN1_STRING_length(cn) != strlen(common_name) || _cups_strncasecmp((const char *)ASN1_STRING_get0_data(cn), common_name, strlen(common_name)))

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Just to confirm - we know that ASN1_STRING_get0_data returns a nul-terminated ASCII string?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

It doesn't need to be. In practice OpenSSL does nul-terminate it (ASN1_STRING_set allocates len + 1 and writes a trailing nul, and the d2i path goes through that), but the docs don't promise it and a CN can carry embedded nuls, so the check doesn't rely on it: ASN1_STRING_length has to equal strlen(common_name) first, and the compare is bounded by that length, so it never reads past the encoded data. Something like CN=altprinter\0evil fails on the length mismatch.

Pushed a small tweak that keeps the length in cnlen and uses it as the compare bound with a comment saying why. Same behaviour, just more obvious.

Comment thread CHANGES.md Outdated
- Fixed a potential string overrun when loading .strings files (Issue #171)
- Fixed `cupsSignCredentialsRequest` to reject requests with a bad signature
(Issue 172)
- Fixed `cupsSignCredentialsRequest` to reject requests whose subject common

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

In the future, please just put your proposed changelog in the PR description and we'll reword and add the GitHub issue number for tracking later...

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Noted. I've dropped the CHANGES.md hunk from this PR and put the proposed entry in the description instead.

@michaelrsweet michaelrsweet added this to the Stable milestone Oct 23, 2026

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

investigating Investigating the issue

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants