Bug 269473 - security/openssl, security/libressl: Use base system CA certificates
Summary: security/openssl, security/libressl: Use base system CA certificates
Status: Open
Alias: None
Product: Ports & Packages
Classification: Unclassified
Component: Individual Port(s) (show other bugs)
Version: Latest
Hardware: Any Any
: --- Affects Some People
Assignee: Bernard Spil
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2023-02-10 21:32 UTC by Tijl Coosemans
Modified: 2023-10-09 17:05 UTC (History)
6 users (show)

See Also:
bugzilla: maintainer-feedback? (brnrd)


Attachments
OpenSSL patch (5.63 KB, patch)
2023-02-10 21:34 UTC, Tijl Coosemans
no flags Details | Diff
LibreSSL patch (2.75 KB, patch)
2023-02-10 21:35 UTC, Tijl Coosemans
no flags Details | Diff
OpenSSL patch2 (10.85 KB, patch)
2023-09-22 10:24 UTC, Tijl Coosemans
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Tijl Coosemans freebsd_committer freebsd_triage 2023-02-10 21:32:32 UTC
For OpenSSL, link ${OPENSSLDIR}/certs to /etc/ssl/certs so certificates can be verified out of the box.

For LibreSSL, link ${PREFIX}/etc/ssl/certs to /etc/ssl/certs so certificates can be verified out of the box.
Comment 1 Tijl Coosemans freebsd_committer freebsd_triage 2023-02-10 21:34:35 UTC
Created attachment 240059 [details]
OpenSSL patch
Comment 2 Tijl Coosemans freebsd_committer freebsd_triage 2023-02-10 21:35:30 UTC
Created attachment 240060 [details]
LibreSSL patch
Comment 3 Michael Osipov 2023-06-23 10:01:56 UTC
Your patch is incomplete, OpenSSL uses two locations for verification: OSSLDIR/certs/ and OSSLDIR/cert.pem. See these functions: https://www.openssl.org/docs/man1.1.1/man3/SSL_CTX_set_default_verify_paths.html
If someone chooses to drop off a cert.pem then it will not work.

I wonder wether symlinks or C code patch would be better here...In anyway, with enterprise CA certs the ports are unusable for me.
Comment 4 commit-hook freebsd_committer freebsd_triage 2023-09-16 13:11:35 UTC
A commit in branch main references this bug:

URL: https://cgit.FreeBSD.org/ports/commit/?id=a054ac48dddb63f5a2995d279d56700f90306369

commit a054ac48dddb63f5a2995d279d56700f90306369
Author:     Bernard Spil <brnrd@FreeBSD.org>
AuthorDate: 2023-09-16 13:08:00 +0000
Commit:     Bernard Spil <brnrd@FreeBSD.org>
CommitDate: 2023-09-16 13:10:36 +0000

    security/libressl: Use CA bundle from base

    PR:             269473
    Reported by:    tijl

 security/libressl-devel/Makefile  | 3 +++
 security/libressl-devel/pkg-plist | 2 +-
 security/libressl/Makefile        | 3 +++
 security/libressl/pkg-plist       | 2 +-
 4 files changed, 8 insertions(+), 2 deletions(-)
Comment 5 Tassilo Philipp 2023-09-20 09:42:23 UTC
Hi, this change led to a conflict on some systems I administer, so I'll ask here what the best practices are or should be.

So I have a setup where I put company wide root certificates from an own CA in $PREFIX/etc/ssl/certs. After upgrading libressl to the latest ports version, they were moved to $PREFIX/etc/ssl/certs.pkgsave, which broke some services relying on those certs. No big deal, I moved them back and it's fine.... (by "moving them back", they are now under /etc/ssl/certs, which is not quite where I would like them to be, though). Question:

What are the best practices on where to store such certs for my use case? I tried checking the doc, but didn't see anything obvious in hier(7) or so. Any pointers/thoughts?

Sorry if I'm missing the obvious, somewhere...

Thanks
Comment 6 Michael Osipov 2023-09-20 09:49:07 UTC
(In reply to Tassilo Philipp from comment #5)

The best practice, regardless of this port, that all certs, especially those for your enterpise, like here, are managed through certctl(8). This change aligns openssl from ports to use the system trust store and not to have yet another one.

The question you need to answer yourself: Why do you need to manage another store manually, if you have one in /etc/ssl/certs with certctl(8)?

Maybe a port OPTION should switch between system wide store and the PREFIX'ed store. Default would be system wide in base. Though, I consider it as a global pain to have a second store to maintain.
Here are my custom CAs, bundled into a seprate port:
osipovmi@deblndw011x:/usr/local/share/certs
$ ls -1
ca-root-nss.crt
digicert-cert-1.crt
quovadis-cert-1.crt
quovadis-cert-2.crt
quovadis-cert-3.crt
quovadis-cert-4.crt
quovadis-cert-5.crt
quovadis-cert-6.crt
quovadis-cert-7.crt
siemens-onead-cert-01.crt
siemens-onead-cert-02.crt
siemens-onead-cert-03.crt
siemens-onead-cert-04.crt
siemens-onead-cert-05.crt
siemens-onead-cert-06.crt
siemens-onead-cert-07.crt
siemens-onead-cert-08.crt
siemens-onead-cert-09.crt
siemens-onead-cert-10.crt
siemens-onead-cert-11.crt
siemens-onead-cert-12.crt
siemens-onead-cert-13.crt
siemens-pki-cert-01.crt
siemens-pki-cert-02.crt
siemens-pki-cert-03.crt
siemens-pki-cert-04.crt
siemens-pki-cert-05.crt
siemens-pki-cert-06.crt
siemens-pki-cert-07.crt
siemens-pki-cert-08.crt
siemens-pki-cert-09.crt
siemens-pki-cert-10.crt
siemens-pki-cert-11.crt
siemens-pki-cert-12.crt
siemens-pki-cert-13.crt
siemens-pki-cert-14.crt
siemens-pki-cert-15.crt
siemens-pki-cert-16.crt
siemens-pki-cert-17.crt
siemens-pki-cert-18.crt

It just works.
Comment 7 Michael Osipov 2023-09-20 09:49:51 UTC
Disregard ca-root-nss.crt, it comes from the ca_root_nss port.
Comment 8 Tassilo Philipp 2023-09-20 09:54:53 UTC
Thanks for your reply, that's great info indeed! I did know about certctl(8), and actually also use it in some build scripts, but didn't actually think about it at all, this morning, after running into this issue.

Thanks for pointing that out, I'll look at certctl(8) more closely! :)
Comment 9 Tassilo Philipp 2023-09-20 13:22:35 UTC
Sorry to get back to this once more. I fully understand the reasoning outlined above for this change, but given the bottom section of certctl(8) I think this might be confusing, potentially. certctl(8) states:

     TRUSTPATH         List of paths to search for trusted certificates.
                       Default: <DESTDIR>/usr/share/certs/trusted
                       <DESTDIR>/usr/local/share/certs
                       <DESTDIR>/usr/local/etc/ssl/certs

     CERTDESTDIR       Destination directory for symbolic links to trusted
                       certificates.  Default: <DESTDIR>/etc/ssl/certs

By itself not a problem, on a default install, that's the case, everything in /etc/ssl/certs is symlinks pointing to certificates in /usr/share/certs/trusted.

But "installing" certs to /usr/local/etc/ssl/certs would result in files being written under /etc/ssl/certs instead of symlinks. So... I would derive from that that best practice would be to put own, additional certs exclusively in /usr/local/share/certs?



Also, on a sidenote... doesn't security/linux-c7-ca-certificates conflict with the libressl ports, as it puts its own symlink at $PREFIX/etc/ssl/certs (regardless of this change)?
Comment 10 Michael Osipov 2023-09-20 13:49:47 UTC
(In reply to Tassilo Philipp from comment #9)

You spotted correctly, using
> <DESTDIR>/usr/local/etc/ssl/certs
is plain wrong and I noticed this some time ago as well. Kyle Evans, who developed this back then and I tested it, he is not available anymore. I will create an bug report to have this deprecated and removed. This dir is solely output for hashing and input for OpenSSL and nothing else. Your certs should live in /usr/local/share/certs exclusively, just like mine do for years now.

Regarding security/linux-c7-ca-certificates:

This needs to be reporting with the maintainer. I bet, there are more issues like this in the tree which require a cleanup. In my option, that port should like in /compat/linux only.
Comment 11 Michael Osipov 2023-09-20 14:00:48 UTC
Here there are, some are valid though, if course:
# grep -r etc/ssl/certs .
./mail/postfix-current/files/patch-conf_main.cf:+smtp_tls_CApath = /etc/ssl/certs
./mail/mpop/Makefile:           -e 's,/etc/ssl/certs,${LOCALBASE}/share/certs,' \
./mail/ssmtp/files/patch-ssmtp.conf:-#TLSCert=/etc/ssl/certs/ssmtp.pem
./mail/ssmtp/files/patch-ssmtp.c:-char *tls_cert = "/etc/ssl/certs/ssmtp.pem";  /* Default Certificate */
./mail/postfix/files/patch-conf_main.cf:+smtp_tls_CApath = /etc/ssl/certs
./mail/cclient/Makefile:        @${REINPLACE_CMD} -e "s:/etc/ssl/certs:${PREFIX}/certs:g; \
./mail/msmtp/Makefile:  @${REINPLACE_CMD} -e 's|/etc/ssl/certs/ca\\-certificates.crt|${CERTSFILE}|' \
./mail/panda-cclient/Makefile:  ${REINPLACE_CMD} -e "s:/etc/ssl/certs:${PREFIX}/certs:g; \
./security/gnutls/Makefile:             --with-default-trust-store-dir=/etc/ssl/certs \
./security/linux-c7-ca-certificates/pkg-plist:etc/ssl/certs
./security/libressl/pkg-plist-libtls:@dir etc/ssl/certs
./security/libressl/pkg-plist:@dir etc/ssl/certs
./security/libressl-devel/pkg-plist:@dir etc/ssl/certs
./security/libressl-devel/pkg-plist-libtls:@dir etc/ssl/certs
./devel/git/work-default/git-2.39.2/Documentation/RelNotes/1.9.0.txt:   /etc/ssl/certs/ directory exists but cannot be used as SSL_ca_path
./devel/git/work-default/git-2.39.2/Documentation/RelNotes/1.8.5.5.txt:   /etc/ssl/certs/ directory exists but cannot be used as SSL_ca_path
./www/py-woob/Makefile: @${REINPLACE_CMD} -e 's|/etc/ssl/certs|${LOCALBASE}/etc/ssl|g' ${WRKSRC}/woob/browser/nss.py
./www/mod_gnutls/files/pkg-message.in:        GnuTLSKeyFile %%PREFIX%%/etc/ssl/certs/private/example_com.key.pem
./www/mod_gnutls/files/pkg-message.in:        GnuTLSCertificateFile %%PREFIX%%/etc/ssl/certs/example_com.crt.pem
./www/mod_gnutls/files/pkg-message.in:        GnuTLSClientCAFile %%PREFIX%%/etc/ssl/certs/example_com.ca.pem
./www/glewlwyd/files/glewlwyd.conf.sample.in:secure_connection_key_file="/etc/ssl/certs/cert.key"
./www/glewlwyd/files/glewlwyd.conf.sample.in:secure_connection_pem_file="/etc/ssl/certs/cert.pem"
./www/glewlwyd/files/glewlwyd.conf.sample.in:secure_connection_ca_file="/etc/ssl/certs/ca.crt"
./www/py-restclient/files/patch-2to3:                     example ca_certs='/etc/ssl/certs/ca-certificates.crt'
./net/guacamole-server/files/guacd.conf.sample:#server_certificate = /usr/local/etc/ssl/certs/guacd.crt
./finance/odoo15/pkg-plist:%%PYTHON_SITELIBDIR%%/odoo/addons/point_of_sale/tools/posbox/overwrite_after_init/etc/ssl/certs/nginx-cert.crt
./finance/odoo/pkg-plist:%%PYTHON_SITELIBDIR%%/odoo/addons/point_of_sale/tools/posbox/overwrite_after_init/etc/ssl/certs/nginx-cert.crt
./finance/odoo14/pkg-plist:%%PYTHON_SITELIBDIR%%/odoo/addons/point_of_sale/tools/posbox/overwrite_after_init/etc/ssl/certs/nginx-cert.crt
./sysutils/fusefs-httpfs/files/patch-Makefile:-    CERT_STORE := /etc/ssl/certs/ca-certificates.crt
./sysutils/fusefs-httpfs/files/patch-Makefile:+#   CERT_STORE := /etc/ssl/certs/ca-certificates.crt
Comment 12 Tassilo Philipp 2023-09-20 14:21:35 UTC
Thanks for the feedback and confirmation.

I also ran the exact same grep on /usr/ports, and except for the linux-c7 port which I found that way, all others look ok (b/c they just disable default paths in configs, change default paths, etc..)
Comment 13 Michael Osipov 2023-09-20 14:31:49 UTC
(In reply to Tassilo Philipp from comment #12)

I consider these as NOT OK:
# grep -r /etc/ssl/certs .
./mail/mpop/Makefile:           -e 's,/etc/ssl/certs,${LOCALBASE}/share/certs,' \
./mail/ssmtp/files/patch-ssmtp.conf:-#TLSCert=/etc/ssl/certs/ssmtp.pem
./mail/ssmtp/files/patch-ssmtp.c:-char *tls_cert = "/etc/ssl/certs/ssmtp.pem";  /* Default Certificate */
./mail/cclient/Makefile:        @${REINPLACE_CMD} -e "s:/etc/ssl/certs:${PREFIX}/certs:g; \
./mail/panda-cclient/Makefile:  ${REINPLACE_CMD} -e "s:/etc/ssl/certs:${PREFIX}/certs:g; \
./www/py-woob/Makefile: @${REINPLACE_CMD} -e 's|/etc/ssl/certs|${LOCALBASE}/etc/ssl|g' ${WRKSRC}/woob/browser/nss.py
./www/mod_gnutls/files/pkg-message.in:        GnuTLSKeyFile %%PREFIX%%/etc/ssl/certs/private/example_com.key.pem
./www/mod_gnutls/files/pkg-message.in:        GnuTLSCertificateFile %%PREFIX%%/etc/ssl/certs/example_com.crt.pem
./www/mod_gnutls/files/pkg-message.in:        GnuTLSClientCAFile %%PREFIX%%/etc/ssl/certs/example_com.ca.pem
./www/glewlwyd/files/glewlwyd.conf.sample.in:secure_connection_key_file="/etc/ssl/certs/cert.key"
./www/glewlwyd/files/glewlwyd.conf.sample.in:secure_connection_pem_file="/etc/ssl/certs/cert.pem"
./www/glewlwyd/files/glewlwyd.conf.sample.in:secure_connection_ca_file="/etc/ssl/certs/ca.crt"
./www/py-restclient/files/patch-2to3:                     example ca_certs='/etc/ssl/certs/ca-certificates.crt'
./net/guacamole-server/files/guacd.conf.sample:#server_certificate = /usr/local/etc/ssl/certs/guacd.crt
./finance/odoo15/pkg-plist:%%PYTHON_SITELIBDIR%%/odoo/addons/point_of_sale/tools/posbox/overwrite_after_init/etc/ssl/certs/nginx-cert.crt
./finance/odoo/pkg-plist:%%PYTHON_SITELIBDIR%%/odoo/addons/point_of_sale/tools/posbox/overwrite_after_init/etc/ssl/certs/nginx-cert.crt
./finance/odoo14/pkg-plist:%%PYTHON_SITELIBDIR%%/odoo/addons/point_of_sale/tools/posbox/overwrite_after_init/etc/ssl/certs/nginx-cert.crt
./sysutils/fusefs-httpfs/files/patch-Makefile:-    CERT_STORE := /etc/ssl/certs/ca-certificates.crt
./sysutils/fusefs-httpfs/files/patch-Makefile:+#   CERT_STORE := /etc/ssl/certs/ca-certificates.crt

They are two categories:
* Replacing /etc/ssl/certs with /usr/local/etc/ssl/certs which breaks the default trust store
* Recommending to put your server certs into the structure, but only CA certs belong there, according to the OpenSSL approach.
Comment 14 Tassilo Philipp 2023-09-20 14:43:18 UTC
Mh... things like mail/ssmtp just remove those paths via the patch, so that should be ok, no?

Since you mentioned "only CA certs belong there", that brings up another question I was wondering about: I also make use of client certificates (like cert-based authed connections to some service).

Since whatever is using client certs is usually pretty usage specific and points to them directly, I don't see any point to put those into the certctl(8) locations (and have certctl(8) rehash them and so on...). Thoughts on where they should be put best?

(Sorry if this question is a bit off-topic.)
Comment 15 Tassilo Philipp 2023-09-20 14:49:25 UTC
Disregard the mail/ssmtp comment, I should've looked at the complete patch, first. I'm with you on that one.
Comment 16 Michael Osipov 2023-09-20 15:05:56 UTC
(In reply to Tassilo Philipp from comment #14)


Right, you need to spilt between
* CA certificates: is handled by certctl(8) and nothing else. No other cert types
* server certificates: no standard, but I tend to store them like this:
/etc/ssl/deblndw011x.ad001.siemens.net/
├── ...
├── 2021
│   ├── cert.crt
│   ├── csr.crt
│   ├── key.crt
│   └── password
├── 2022
│   ├── cert.crt
│   ├── csr.crt
│   ├── key.crt
│   └── password
├── 2023
│   ├── cert.crt
│   ├── csr.crt
│   ├── key.crt
│   └── password
├── cert.crt -> 2023/cert.crt
├── key.crt -> 2023/key.crt
└── password -> 2023/password

with appropriate mode and perms, of course. So, one tree per hostname.
* client certifcates: these are really application-specific. Since I consider them as sensitive configuration data, I put them into the etc/ or conf/ dir of the application.
Comment 17 Tassilo Philipp 2023-09-20 15:44:10 UTC
Thanks for sharing your thoughts on this.
I agree to your line of thought. The client certs being "sensitive configuration data", and given that some are in shared use by different applications, is the reason why I put them in etc, but yeah in /usr/local/etc/ssl/certs, which wasn't the appropriate place to begin with. Hence my first comment on this issue.
Comment 18 Bernard Spil freebsd_committer freebsd_triage 2023-09-20 17:54:59 UTC
(In reply to Tijl Coosemans from comment #0)

Leads to errors on install. The directory exists and isn't removed with the uninstall? Then creation of the symlink fails because of an existing directory.
Comment 19 Tijl Coosemans freebsd_committer freebsd_triage 2023-09-21 17:55:23 UTC
(In reply to Bernard Spil from comment #18)
If the certs directory isn't empty it isn't deleted when deleting the old package, and then "make install" of the new version seems to fail, while "pkg add" does work because it renames the directory to certs.pkgsave.  I'd say this is a bug in pkg.  "make install" should have the same behaviour as "pkg add".  For now we could add the following to pkg-plist:

For openssl ports:

@preexec if [ -d %D/openssl/certs ]; then [ ! -e %D/openssl/certs.pkgsave ] && mv %D/openssl/certs %D/openssl/certs.pkgsave; fi

For libressl ports:

@preexec if [ -d %D/etc/ssl/certs ]; then [ ! -e %D/etc/ssl/certs.pkgsave ] && mv %D/etc/ssl/certs %D/etc/ssl/certs.pkgsave; fi


There should also be an UPDATING entry for situations like comment #5.  Something like this:

--
AFFECTS: users of security/openssl* and security/libressl*
AUTHOR: brnrd@freebsd.org

The directories /usr/local/openssl/certs and /usr/local/etc/ssl/certs have been replaced with symbolic links to /etc/ssl/certs.  Any CA certificates in these directories should be moved to /usr/local/share/certs and then installed to /etc/ssl/certs using "certctl rehash".  See certctl(8) for more information.

If the directory certs exists when installing the package it will be renamed certs.pkgsave.  If certs.pkgsave exists package installation will fail.
--
Comment 20 Michael Osipov 2023-09-22 07:45:55 UTC
(In reply to Tijl Coosemans from comment #19)

Guys, I am truly confused. Since all of the OpenSSL derivates define CONFLICTS_INSTALL (mutually exclusive) I don't understand why security/openssl* does:
> CONFIGURE_ARGS=	--openssldir=${OPENSSLDIR}
It makes logically no sense to me. I'd expect any derivative be in /usr/local/etc/ssl. I mean, we dont have /usr/openssl...
Comment 21 Michael Osipov 2023-09-22 07:57:56 UTC
(In reply to Tassilo Philipp from comment #9)

I have now reported: Bug 274016
Comment 22 Tijl Coosemans freebsd_committer freebsd_triage 2023-09-22 10:24:42 UTC
Created attachment 245112 [details]
OpenSSL patch2

OpenSSL patch updated to include preexec command, UPDATING entry and openssl32.