Bug 160387 - security/ca_root_nss: Allow user to trust extra local certificates
Summary: security/ca_root_nss: Allow user to trust extra local certificates
Status: Closed FIXED
Alias: None
Product: Ports & Packages
Classification: Unclassified
Component: Individual Port(s) (show other bugs)
Version: Latest
Hardware: Any Any
: Normal Affects Only Me
Assignee: Ports Security Team
Depends on:
Reported: 2011-09-02 11:00 UTC by Romain Tartière
Modified: 2020-07-24 13:50 UTC (History)
10 users (show)

See Also:


Note You need to log in before you can comment on or make changes to this bug.
Description Romain Tartière freebsd_committer 2011-09-02 11:00:24 UTC
When building packages for multiple FreeBSD boxes that will access internal
resources using self-made certificates / other organisations certificates, it
would be handy to add these certificates to the generated file.  

This way, it is directly possible to use many programs (e.g. epiphany, curl)
without first editing this file by hand (or with some tools such as puppet).

Beyond the benefit of not having to tweak this file manually, 'pkg_info -g'
would not complain about mismatching files checksum unless something bad

Fix: If the certificates are available at compile time, adding a feature to
'register' them along with the others is somewhat trivial:

I don't think "regular" users would use that feature so maybe presenting an
OPTION is overkill.  But maybe a message saying to 'set CA_ROOT_NSS_EXTRA_CERTS
to the list of local certificates to trust' just before the build may be a

What is your opinion about such a feature?
Content-Type: text/plain; name="ca_root_nss.patch"
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment; filename="ca_root_nss.patch"

--- Makefile.orig	2011-09-02 10:17:54.489639211 +0200
+++ Makefile	2011-09-02 10:22:48.659844571 +0200
@@ -69,6 +69,9 @@
 	@${PERL} ${WRKDIR}/ca-bundle.pl < ${WRKDIR}/certdata.txt > \
+	@${CAT} ${CA_ROOT_NSS_EXTRA_CERTS} >> ${WRKDIR}/ca-root-nss.crt
1. Have some domain protected by some self-made certificate or e.g. cacert
2. Install security/ca_root_nss and ftp/curl
3. curl https://some.domain.example.com/
  ** fails **
4. cat cert >> /usr/local/share/certs/ca-root-nss.crt
5. curl https://some.domain.example.com/
  ** success **
Comment 1 Edwin Groothuis freebsd_committer 2011-09-02 11:00:39 UTC
Responsible Changed
From-To: freebsd-ports-bugs->brooks

Over to maintainer (via the GNATS Auto Assign Tool)
Comment 2 Mark Linimon freebsd_committer freebsd_triage 2011-11-20 23:23:46 UTC
Responsible Changed
From-To: brooks->gecko

Over to current maintainer.
Comment 3 Jan Beich freebsd_committer 2013-01-31 19:30:34 UTC
Romain Tartiere <romain@FreeBSD.org> writes:

> 1. Have some domain protected by some self-made certificate or e.g. cacert
> 2. Install security/ca_root_nss and ftp/curl
> 3. curl https://some.domain.example.com/
>   ** fails **
> 4. cat cert >> /usr/local/share/certs/ca-root-nss.crt
> 5. curl https://some.domain.example.com/
>   ** success **

This mostly depends on the app e.g.,

- openssl(1) only uses CA certs with -CApath or -CAfile
- subversion (neon), lynx, etc. call SSL_CTX_set_default_verify_paths()
- curl (openssl) hardcodes either /etc/ssl/certs/ or
  ${LOCALBASE}/share/certs/ca-root-nss.crt (CA_BUNDLE option)
- curl (gnutls) hardcodes /etc/ssl/cert.pem
- epiphany2 (gnutls?) accepts self-signed certificates without
  warning but otherwise hardcodes path to ca-root-nss.crt
- firefox and chromium use hardcode CA certs into libnssckbi.so from a
  bundled copy of certdata.txt in nss port (not ca_root_nss)

and a bit more detailed

  # add a shared self-signed certificate
  $ mkdir /etc/ssl/certs; cd /etc/ssl/certs
  $ openssl s_client -connect trillian.chruetertee.ch:https </dev/null 2>&0 |
    openssl x509 -text -fingerprint >freebsd-gecko.crt
  $ ln -sf freebsd-gecko.crt $(openssl x509 -hash -noout -in freebsd-gecko.crt).0

  $ openssl s_client -connect trillian.chruetertee.ch:https -CApath /var/empty
        Verify return code: 0 (ok)
  $ curl https://trillian.chruetertee.ch/svn/freebsd-gecko/trunk/
  <?xml version="1.0"?>

  $ HOME=/var/empty svn ls https://trillian.chruetertee.ch/svn/freebsd-gecko/trunk/

It may be worth to look at how other distros tried to solve the mess.

Comment 4 Martin Wilke freebsd_committer 2016-01-17 14:09:12 UTC
over new to new maintainer.
Comment 5 Mark Felder freebsd_committer 2016-01-17 17:56:53 UTC
I was just dealing with this at work on a RHEL-based distro, so yes the ability to ship certs and not worry about an update breaking them would be greatly appreciated.
Comment 6 Michael Osipov 2016-06-24 09:57:35 UTC
I am highly in favor of this feature because our company (350 000 employees) has a complete chain of CAs. I have added them with cat(1) to the pem file (via Makefile) but this isn't a real solutions. The define sounds like a good options for this.
Comment 7 Walter Schwarzenfeld freebsd_triage 2018-01-16 09:40:43 UTC
Any news here?
Comment 8 Michael Osipov 2018-06-25 08:46:34 UTC
Can we have this finally?
Comment 9 Mark Felder freebsd_committer 2018-07-10 11:38:46 UTC
(In reply to Michael Osipov from comment #8)

I'm looking at this and wondering how we include the certificate in the package reliably. Sure, you could set CA_ROOT_NSS_EXTRA_CERTS to some file and it might work if you did a regular port build (cd /usr/ports/security/ca_root_nss && make install clean) but it wouldn't work if building the packages with poudriere as the certificate file wouldn't exist in the build jail.
Comment 10 Michael Osipov 2018-07-19 10:10:57 UTC
(In reply to Mark Felder from comment #9)

That is really a good question I cannot really answer because it sounds like a chiken-and-egg problem. But consider that you do not test the contents fo the PEM bundle anyway. So if the cat(1) does not have an extras file to append, so what? Nothing will break. Of course, you can host the file externally via HTTPS, but one would still need to provide the URL, hence we are back to the same problem.

There must be some reasonable solution to this problem.

Note that I have filed the same issue for the Java truststore and likely see the approach of Debian/Ubuntu implemented where the truststore is derived from the Mozilla CA store and supplied via symlink to the appropriate JDK (7,8).
Comment 11 Mark Felder freebsd_committer 2018-07-19 13:31:37 UTC
(In reply to Michael Osipov from comment #10)

HTTPS/network fetching wouldn't work either as network connectivity is not allowed during build time (after initially fetching distfiles) in poudriere.

CentOS/RHEL solves this properly. They have a tool that is used to merge your own CAs into the default trust stores for standard OpenSSL format, Java keystore, and possibly even the bizarre format that Mono uses. This tool reads your CAs out of /etc/ssl and merges them in for you. I believe it is also handled automatically upon each update of the package. As we are unlikely to find this in base anytime soon, we have to make this functionality as part of our ca_root_nss.

As nobody else is solving this and this itch is long overdue from being scratched, I feel it is worthwhile to write something. This could be accomplished with a shell script, so that is my aim. I am going to crank something out that I believe solves the initial problem. It will be up to someone else to add in Java keystore and Mono functionality after standardizing the way those ports (e.g. openjdk6/7/8/9) get their trust stores. Ideally they will all begin sharing one with the help of symlinks.

I will open a review with a rough draft which also hooks it into the package's post-install script. This will need testers and reviewers. The end result should be acceptable for solving the initial problem, and then we can open bugs for the remaining issues for Java and Mono so they can be solved cooperatively with the maintainers.
Comment 12 Mark Felder freebsd_committer 2018-07-19 13:43:18 UTC
For the record, the RHEL utility is documented here: https://www.unix.com/man-page/centos/8/update-ca-trust/

I expect we will only implement a subset of this functionality for now.
Comment 13 Michael Osipov 2018-07-19 16:40:55 UTC
(In reply to Mark Felder from comment #11)

I'd be more than happy to test that here at work with our CAs. Here is the appropriate Java issue: https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=229329
Comment 14 Mark Felder freebsd_committer 2018-07-19 17:37:47 UTC
Review here:

Comment 15 Michael Osipov 2018-10-04 12:50:19 UTC
I have left a few comments on it regarding a more complex setup in a huge enterprise like ours. If those are resolved this will be a good solution for a lot of people.
Comment 16 Michael Osipov 2020-02-22 19:24:40 UTC
Anyone want to pick this up?

This has been working for me for more than a year now.
Comment 17 Helge Oldach 2020-02-23 10:03:04 UTC
(In reply to Michael Osipov from comment #16)
Actually tweaking ca_root_nss is getting kind of obsolete with the new caroot infrastructure in base. Also caroot deals nicely with private CAs.
Comment 18 Michael Osipov 2020-02-23 18:35:27 UTC
(In reply to Helge Oldach from comment #17)

That sounds promising. I see it in freebsd/secure/caroot. I need to verify whether this properly replaces the proposed scripts. Will report in a week or so.
Comment 19 Michael Osipov 2020-02-28 13:15:13 UTC
(In reply to Helge Oldach from comment #17)

I have left a prolonged comment here: https://reviews.freebsd.org/D16857#524890

It is a foundation, but not fully integrated yet.
Comment 20 Michael Osipov 2020-05-04 20:22:40 UTC
I think this is obsolete with certctl(8).
Comment 21 Ivan Rozhuk 2020-05-05 02:53:31 UTC
(In reply to Michael Osipov from comment #20)

I do not see how certctl will manage certs in ${LOCALBASE}/share/certs/ca-root-nss.crt.
Comment 22 Helge Oldach 2020-05-05 07:17:05 UTC
(In reply to rozhuk.im from comment #21)
It doesn't. But it's also not needed since ports relying on OpenSSL will happily pick up certificates deployed by base (secure/caroot) if the CA_BUNDLE knob is disabled.

Note the subject is "extra local certificates" which is not currently handled by the security/ca_root_nss port, however the base secure/caroot infrastructure handles this case nicely.
Comment 23 Michael Osipov 2020-05-05 10:42:08 UTC
(In reply to rozhuk.im from comment #21)

security/caroot operated on the NSS bundle and splits into individual PEM files. I don't see need to manage the same piece of information twice.
Comment 24 Ivan Rozhuk 2020-05-05 11:42:28 UTC
(In reply to Michael Osipov from comment #23)

truss shows that some programs read only /usr/local/share/certs/ca-root-nss.crt and parse it internal, so after any certs update I must run:

cat /usr/local/etc/ssl/ca-trust/source/anchors/jabber.netlab.linkpc.net.crt >> /usr/local/share/certs/ca-root-nss.crt

to keep my cert trusted.
Comment 25 Helge Oldach 2020-05-05 11:59:27 UTC
(In reply to rozhuk.im from comment #24)
What are these "some programs"?

Again, if - for example - you build ftp/curl without CA_BUNDLE, curl will automatically pick up the cert bundles (including your local certs for example from /usr/local/etc/ssl/certs/) that were prepared with certctl. No need to tinker with /usr/local/share/certs/ca-root-nss.crt manually. You can simply remove it.
Comment 26 Ivan Rozhuk 2020-05-05 12:10:59 UTC
(In reply to Helge Oldach from comment #25)

This is does not work for Dino and probably for FireFox.
Dino uses gnutls (as I remember), ff - nss.
Comment 27 Michael Osipov 2020-05-05 13:26:04 UTC
(In reply to rozhuk.im from comment #24)

The the application is broken. If an application uses OpenSSL and does not pass any cert bundle, OpenSSL will automatically use the certs dir as described in comment #25.
Comment 28 Michael Osipov 2020-05-05 13:28:19 UTC
(In reply to rozhuk.im from comment #26)

and it won't because NSS has a completely difference database format for certs. It has to be updated manually :-( I don't know for GnuTLS. At best, certctl(8) would also distill a PEM bundle from the certs dir for other TLS implementations which cannot read the certs/ dir or application which do not use OpenSSL.
Comment 29 Jochen Neumeister freebsd_committer 2020-07-23 16:31:22 UTC
I'll close up here. If there are any problems, please reopen.
Comment 30 Michael Osipov 2020-07-24 13:50:36 UTC
(In reply to Jochen Neumeister from comment #29)

I think closed fixed is truly the wrong status here. Nothing has been fixed here, but rather supeseded by certctl(8).