Note: This is a beta release of Red Hat Bugzilla 5.0. The data contained within is a snapshot of the live data so any changes you make will not be reflected in the production Bugzilla. Also email is disabled so feel free to test any aspect of the site that you want. File any problems you find or give feedback here.
Bug 1514041 - certutil -O output isn't precise when the input is an ambiguous nickname used by multiple certificates [NEEDINFO]
Summary: certutil -O output isn't precise when the input is an ambiguous nickname used...
Status: ON_QA
Alias: None
Product: Red Hat Enterprise Linux 7
Classification: Red Hat
Component: nss
Version: 7.4
Hardware: x86_64
OS: Linux
Target Milestone: rc
: ---
Assignee: Daiki Ueno
QA Contact: BaseOS QE Security Team
Depends On: 1645231
Blocks: 1512952
TreeView+ depends on / blocked
Reported: 2017-11-16 14:44 UTC by Florence Blanc-Renaud
Modified: 2019-04-03 10:39 UTC (History)
11 users (show)

Fixed In Version: nss-3.43.0-2.el7
Doc Type: If docs needed, set a value
Doc Text:
Clone Of:
Last Closed: 2019-02-11 15:39:26 UTC
Target Upstream Version:
hkario: needinfo? (frenaud)

Attachments (Terms of Use)
NSS DB (deleted)
2017-11-16 14:44 UTC, Florence Blanc-Renaud
no flags Details
patch v1 (deleted)
2018-05-11 16:31 UTC, Kai Engert (:kaie) (inactive account)
no flags Details | Diff

System ID Priority Status Summary Last Updated
Mozilla Foundation 1462627 None None None 2019-04-02 12:33:04 UTC

Description Florence Blanc-Renaud 2017-11-16 14:44:32 UTC
Created attachment 1353543 [details]

Description of problem:

In a FreeIPA master, I am using a NSS DB that contains multiple certificates with the same nickname 'caSigningCert cert-pki-ca' (the first one was self-signed, then renewed with an externally-signed cert 'CN=Cert Auth,O=FloAuth', then renewed with a self-signed certificate).

When I run certutil -O -n <nick>, the output displays a wrong certificate chain. 

The behavior was different with earlier versions of nss-tools (3.28.4-1.2.el7_3 for instance)

Version-Release number of selected component (if applicable):
rhel 7.4
nss-tools.x86_64                    3.28.4-15.el7_4

How reproducible:

Steps to Reproduce:
1. using the attached NSSDB:
$ certutil -O -d /tmp/alias -n 'caSigningCert cert-pki-ca'
"CN=Cert Auth,O=FloAuth" [CN=Cert Auth,O=FloAuth]

  "caSigningCert cert-pki-ca" [CN=Certificate Authority,O=DOMAIN.COM]

    "caSigningCert cert-pki-ca" [CN=Certificate Authority,O=DOMAIN.COM]

Actual results:
certutil -O displays twice 'caSigningCert cert-pki-ca', and also shows the external ca.

Expected results:
The most recent version of this certificate is self-signed. I would expect an output like the following:
$ certutil -O -d /tmp/alias -n 'caSigningCert cert-pki-ca'
"caSigningCert cert-pki-ca" [CN=Certificate Authority,O=DOMAIN.COM]

Additional info:
Can be reproduced with the attached NSS DB.
See also BZ 1512952 for the full reproducer with FreeIPA.

Comment 2 Kai Engert (:kaie) (inactive account) 2017-11-29 16:19:47 UTC
IIUC, you're reporting a difference output between the versions
- 3.28.4-1.2.el7_3
- 3.28.4-15.el7_4

That's surprising, because those versions don't have that much differences.

Using your attached example, I ran your scenario on two different computers, one having the older NSS 3.26, and one the newer NSS 3.33, and both produced idential output for me:

$ certutil -d dbm:. -O -n 'caSigningCert cert-pki-ca'
"CN=Cert Auth,O=FloAuth" [CN=Cert Auth,O=FloAuth]

  "caSigningCert cert-pki-ca" [CN=Certificate Authority,O=DOM-235.ABC.IDM.LAB.ENG.BRQ.REDHAT.COM]

    "caSigningCert cert-pki-ca" [CN=Certificate Authority,O=DOM-235.ABC.IDM.LAB.ENG.BRQ.REDHAT.COM]

Based on that, I have 3 comments:

(a) Given that you and I see different results wrt to the stability of this output, it would be interesting to get more results, produced using a greater set of NSS versions. Was this potentially a one-time change, that was already corrected in later upstream?

(b) The input to this command is ambiguous. With an ambiguous input, I believe there isn't any guarantee about the result set. I believe NSS has the right to become more complete, and extend its output with additional information. For example, the "certutil -L -n nickname" command may also print multiple certificates (IIRC) if there are multiple matches.

(c) You reported the difference, but you didn't give a justification why this would be a problem. Can you provide a business reason why a more extensive output would be problematic?

Comment 4 Kai Engert (:kaie) (inactive account) 2017-11-30 15:33:11 UTC
(In reply to Florence Blanc-Renaud from comment #3)
> Regarding (a):
> My bad, I am not able to reproduce this either with rhel 7.3

Please let's clarify what this means for this bug.

Does it mean, you confirm that the behavior hasn't changed?

(If correct, this isn't a regression bug. It's always important to know if a bug is a regression or something else.)

If the behavior hasn't changed and this isn't a regression bug, then your bug report means that you don't like the behavior of certutil.

Any change in behavior of certutil would have to be discussed upstream, get agreed upon, and implemented upstream.

Comment 5 Florence Blanc-Renaud 2017-11-30 15:35:32 UTC
Yes, it's not a regression.

Comment 7 Kai Engert (:kaie) (inactive account) 2017-11-30 15:56:39 UTC
I've read your comment 3.

IIUC, you're trying to use the NSS command line tools for advanced functionality. You want to correctly query the issuer/root certificates of a given input certificate, and use the result for further processing.

Your workflow apparently involves reusing the same nickname over time.

But you are using a tool interface that identifies certificates by nickname, which is ambigious in your environment, and therefore cannot result in precise results.

I think you cannot expect an environment to work, if you know the input to tools can be used in ambigious ways, and you indeed use workflows that involve ambiguity.

Ideally you should start to use unique nicknames for each certificate in your workflows.

Alternatively, maybe you need to develop your own tooling, based on the NSS C APIs, not based on the limited helper tools, to achieve what you need to have done.

Comment 8 Kai Engert (:kaie) (inactive account) 2017-11-30 16:02:00 UTC
Alternatively, if you believe this would help you, we could attempt to implement a more advanced parameter for identifying certificates by the tools. The standard key is "{issuer name, serial number}". If we invented a mechanism, that allowed you to provide issuer name and serial number, instead of the nickname, would that help you? You'd have to list all certificates, pick out the one you're looking for, extract the identifying key from that certificate, and then use that as the input parameter for tooling. This would avoid the ambiguity when requesting output from a tool, because you'd be able to precisely identify the certificate for which you are requesting information.

Comment 9 Florence Blanc-Renaud 2017-12-04 10:25:44 UTC
In my workflow, the certificate is the IPA CA certificate. It is possible to renew this cert with a different cert chain (for instance at install time it is a self-signed cert, then the customer prefers to use an externally signed cert and triggers a renewal with an ext CA). The first cert and the renewed cert are using the same private key. So far, no problem with certutil. Even though there are 2 certs with the same nickname, certutil -O displays the output adapted to the most recent cert (the ext-signed one).

Now if the customer decides to renew this cert a second time but as self-signed, the issue happens because certutil -O is ambiguous. IMHO when the db contains a cert and a renewed cert, certutil -O output should correspond to the most recent one, but I understand that this needs to be discussed with NSS team.

If I need to find the most recent cert corresponding to a given nickname in order to extract the issuer name and serial, the overhead is probably similar to adapting IPA code to handle the self-signed case and I don't really see an interest in the proposed mechanism (based on issuer name, serial number).

Comment 10 Kai Engert (:kaie) (inactive account) 2017-12-04 12:50:51 UTC
Thanks for explaining the expectations in more detail.

I looked at this again, and I see that -O always prints just one chain. It never attempts to display multiple chains, even if there are multiple matches. It attempts to find the best certificate, by using CERT_FindCertByNicknameOrEmailAddrCX, or falling back to PK11_FindCertFromNickname.

Then it proceeds to use CERT_CertChainFromCert to find the chain.

The output you reported (in the initial comment) probably means the following:

It identifies the self-signed certificate as the best match for your nickname, because it's the newest cert.

Then it attempts to find other certificates with the same issuer. There is one. It finds your older certificate, and it proceeds to display that and its chain.

Comment 11 Kai Engert (:kaie) (inactive account) 2017-12-04 14:18:41 UTC
Bob, what's your opinion on the expected behavior for CERT_CertChainFromCert, if it sees a self-signed cert?

Should NSS continue to search for potential other issuer certificates of a self-signed cert? (This is what it is currently doing, apparently).

Or is that a bug, and NSS should stop searching for issuers if it arrives at a self-signed cert (subject == issuer) ?

Comment 12 Rob Crittenden 2018-02-01 14:37:04 UTC

Comment 13 Bob Relyea 2018-02-10 01:42:15 UTC
So one could argue for either semantic. Part of the issue is what our various cert verification schemes do. The default verifier will always stop once it's found a self-signed cert. PKIX verifiers will check all the possible paths. There really isn't anyway for the library to know what the caller wants.

CERT_CertChainFromCert certainly shouldn't search for ever because a self-signed cert was presented.

The whole scenario, though sounds somewhat problematic. You have a self-signed leaf cert with the same subject as a root cert or an intermediate CA? In the same database? Sounds like a recipe for disaster anyway.

Comment 14 Rob Crittenden 2018-02-16 20:13:26 UTC
So what should we do here? Will NSS take this as an RFE to provide both options (ideally)?

IPA uses this to discover the CA chain of a given certificate and to ensure that the entire chain is available. While this switching back and forth between self and externally issued is unusual it isn't unprecedented.

Comment 15 Petr Vobornik 2018-04-16 13:51:52 UTC
Setting needs info - comment 14.

Comment 16 Kai Engert (:kaie) (inactive account) 2018-05-11 15:35:24 UTC
Re-reading and re-thinking about this bug. Let me summarize:

- you have databases that contain multiple certificates with the same
  subject name, old and new ones.

- some of the certificates are self-signed, others are externally signed

- all have the same nicknames

- when you use "certutil -O" to request information about the chain for one
  of those certs, indicated by nickname, and if the most recent one is
  self-signed, then the output includes information about the signers
  of an older cert.

In comment 11, I had made a suggestion, which I had hoped to be a simple solution. I had suggested to "don't show a chain if the best cert is self-signed" as the new default behavior.

Based on comment 13, I conclude my suggestion doesn't work in general. Because a smarter PKIX validator could potentially find a valid issuer certificate that has the same subject.

I understand Bob's comment as: The output of certutil -O should be the smartest that our default chain building code can do. Which means we probably shouldn't change the existing default behavior.

Rob suggested in comment 14 that we should implement both options, one simple option, and one smart option (the full PKIX option). But the PKIX implementation we have in NSS is on a path to get deprecated, because too many users have reported issues with it. Therefore I'm reluctant to implement an option that promises full PKIX chain lookup.

I'd rather prefer an option that promises that you get the simple behavior.

I understand IPA explicitly wants to request the simple beahvior: "Print the chain for the newest cert. Assume we are in a simple, non-PKIX path building world. If it's apparently a self-signed cert, because subject name and issuer name match, then don't attempt to resolve a chain."

We could implement this using a new parameter for -O:

When this option is given together with -O, then certutil could compare subject and issuer, and if they match, don't lookup and don't print any chain, but only print the subject if the self-signed certificate.

Comment 17 Kai Engert (:kaie) (inactive account) 2018-05-11 16:31:27 UTC
Created attachment 1435035 [details]
patch v1

This patch implements an optional --simple-self-sign parameter for -O.

When executing this code against the attached DB, we get this output:

$ certutil -d dbm:. -O -n 'caSigningCert cert-pki-ca' --simple-self-signed
"caSigningCert cert-pki-ca" [CN=Certificate Authority,O=DOM-235.ABC.IDM.LAB.ENG.BRQ.REDHAT.COM]

Would this enhancement solve your issue?

If yes, we can suggest this enhancement upstream.

Comment 18 Kai Engert (:kaie) (inactive account) 2018-05-11 16:32:59 UTC
Bob, would you be OK with this enhancement in general?

In short:

If the additional parameter --simple-self-signed is given, then "certutil -O" will only print the single cert, and not attempt to find a chain.

Comment 19 Florence Blanc-Renaud 2018-05-14 08:11:14 UTC
Hi Kai,

(in reply to comment #c17)
thanks for your proposal. The option would solve our issue and looks good to me.

Comment 31 Simo Sorce 2019-02-11 15:39:26 UTC
This issue was not selected to be included either in Red Hat Enterprise Linux 7.7 because it is seen either as low or moderate impact to a small amount of use-cases. The next release will be in Maintenance Support 1 Phase, which means that qualified Critical and Important Security errata advisories (RHSAs) and Urgent Priority Bug Fix errata advisories (RHBAs) may be released as they become available. We will now close this issue, but if you believe that it qualifies for the Maintenance Support 1 Phase, please re-open; otherwise we recommend moving the request to Red Hat Enterprise Linux 8 if applicable.

Note You need to log in before you can comment on or make changes to this bug.