Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

"TLS certificate verification failed: unable to get local issuer certificate" on OpenBSD #1234

Closed
kousu opened this issue Dec 1, 2019 · 5 comments · Fixed by profanity-im/libmesode#17
Assignees
Milestone

Comments

@kousu
Copy link

kousu commented Dec 1, 2019

Expected Behavior

Connecting to my server with good encryption should be smooth and transparent.

Current Behavior

On OpenBSD 6.6, profanity doesn't recognize my server certificate. Firefox and Chrome and curl and all the rest are fine using the same cert over https, and even Gajim is fine using the same cert over XMPP.

Steps to Reproduce (for bugs)

  1. Install OpenBSD 6.6 (e.g. in a VM is okay)
  2. doas pkg_add profanity
  3. profanity
  4. Configure an account
  5. /connect
  6. You should get a cert warning. For example, I see
19:01:05 - Connecting with account me as xxxxx@kousu.ca/profanity.Knnk
19:01:05 -
19:01:05 - TLS certificate verification failed: unable to get local issuer certificate
19:01:05 - Certificate:
19:01:05 -   Subject:
19:01:05 -     Common name        : kousu.ca
19:01:05 -   Issuer:
19:01:05 -     Common name        : Let's Encrypt Authority X3
19:01:05 -     Organisation       : Let's Encrypt
19:01:05 -     Country            : US
19:01:05 -   Version             : 3
19:01:05 -   Serial number       : 306985045415726649439109608216956856373463
19:01:05 -   Key algorithm       : rsaEncryption
19:01:05 -   Signature algorithm : sha256WithRSAEncryption
19:01:05 -   Start               : Nov 15 00:45:22 2019 GMT
19:01:05 -   End                 : Feb 13 00:45:22 2020 GMT
19:01:05 -   Fingerprint         : a7f6d906d5af840a1609731c19dccdb15943427d
19:01:05 -
19:01:05 - Use '/tls allow' to accept this certificate.
19:01:05 - Use '/tls always' to accept this certificate permanently.
19:01:05 - Use '/tls deny' to reject this certificate.

Context

I'm trying to log onto my server smoothly. It's not a big deal to manually check and trust my cert, but it's one of those death-by-a-thousand-cuts that the BSDs suffer.

Environment

$ profanity -v      
Profanity, version 0.7.1
Copyright (C) 2012 - 2019 James Booth <boothj5web@gmail.com>.
Copyright (C) 2019 Michael Vetter <jubalh@iodoru.org>.
License GPLv3+: GNU GPL version 3 or later <https://www.gnu.org/licenses/gpl.html>

This is free software; you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Build information:
XMPP library: libmesode
Desktop notification support: Disabled
OTR support: Enabled (libotr 4.1.1)
PGP support: Enabled (libgpgme 1.13.1)
OMEMO support: Enabled
C plugins: Disabled
Python plugins: Enabled (3.7.4)
GTK icons: Disabled
$ uname -a
OpenBSD laptop.lan 6.6 GENERIC.MP#372 amd64

I'm using OpenBSD's fork of OpenSSL:

$ openssl version                                                                                                         
LibreSSL 3.0.2

It's using OpenBSD's bundled libc, of course:

$ ls /usr/lib/libc.* 
/usr/lib/libc.a       /usr/lib/libc.so.95.1

In profanity, /tls certpath gives:

19:11:30 - Trusted certificate path: /etc/ssl

Since using gajim works, I dug into what it's using. Its support library nbxmpp has this line:

https://github.com/gajim/python-nbxmpp/blob/dc337d8c124047863696057a757f6882cdade6fc/nbxmpp/tls.py#L366-L370

I confirmed that commenting out "/etc/ssl" gives me a TLS warning; but that's not the actual file used, the actual file is "/etc/ssl/cert.pem". A few lines lower in nbxmpp you can see it brute-forcing its way to loading all the certs it can find.

My guess is profanity isn't loading this same file, but is instead using "/etc/ssl/certs" as on Linux, or is maybe not recognizing that it needs to open that specific file?

(thanks for the software! it is really slick and efficient for me otherwise!)

@kousu
Copy link
Author

kousu commented Dec 1, 2019

profanity definitely know of "/etc/ssl"

$ strings `which profanity` | grep ssl
libssl.so.47.6
/etc/ssl/certs
/etc/ssl

(plus it shows up in /tls certpath)

if I trace it it seems to look at that folder and then..not actually try to load anything inside it.

$ ktrace profanity 
$ kdump -f ktrace.out
...
 80201 profanity CALL  stat(0x15269744f44f,0x7f7ffffe1ff0)
 80201 profanity NAMI  "/etc/ssl/certs"
 80201 profanity RET   stat -1 errno 2 No such file or directory
 80201 profanity CALL  stat(0x152697452a47,0x7f7ffffe1ff0)
 80201 profanity NAMI  "/etc/pki/tls/certs"
 80201 profanity RET   stat -1 errno 2 No such file or directory
 80201 profanity CALL  stat(0x152697452a5a,0x7f7ffffe1ff0)
 80201 profanity NAMI  "/etc/ssl"
 80201 profanity STRU  struct stat { dev=1024, ino=104189, mode=drwxr-xr-x , nlink=3, uid=0<"root">, gid=0<"wheel">, rdev=418279, atime=1575163535<"Nov 30 20:25:35 2019">.897198064, mtime=1574794860<"Nov 26 14:01:00 2019">.154979709, ctime=1574794860<"Nov 26 14:01:00 2019">.154979709, size=512, blocks=4, blksize=16384, flags=0x0, gen=0x0 }
 80201 profanity RET   stat 0

@kousu
Copy link
Author

kousu commented Dec 1, 2019

I actually had the exact same problem with prosody on OpenBSD before. We ended up fixing by switching to cafile directly:

https://cvsweb.openbsd.org/ports/net/prosody/patches/patch-core_certmanager_lua?rev=1.3&content-type=text/x-cvsweb-markup

but since this works with all these other programs it's...gotta be simpler than that, right?

@kousu
Copy link
Author

kousu commented Dec 1, 2019

I think I've tracked it down. In your analogue of nbxmpp, libmesode, you call SSL_CTX_load_verify_locations() with only a CApath argument but a null CAfile.

https://github.com/profanity-im/libmesode/blob/c3009c34730c97774562fafdafcc362a3d88fb46/src/tls_openssl.c#L323-L325

But see, OpenBSD ships with a CAfile and not a CApath. And I wonder if libressl has further tightened up the rules in their rewrite.

The only reason this works for Gajim is that they brute force their way through every file in a given dir, trying to see if any of them look like certs. It works but they're not following OpenSSL's design.

To fix this properly would mean exposing CAfile to the user, say in /tls cafile and expanding libmesode to support that. Or maybe just add a call to SSL_CTX_set_default_verify_paths() before trying to load a custom path, so that the distro can take care of putting their trust roots where they want.

@kousu
Copy link
Author

kousu commented Dec 1, 2019

^ I tried my second suggestion and it worked peachy.

@kousu kousu closed this as completed Dec 1, 2019
@kousu kousu reopened this Dec 1, 2019
@jubalh jubalh added this to the 0.8.0 milestone Dec 1, 2019
@pasis
Copy link
Member

pasis commented Dec 2, 2019

There is an issue related to CA cert bundle file: #1212, however, not exactly your problem.

If you confirm that SSL_CTX_set_default_verify_paths() fixes the problem, libmesode must be fixed. Also /tls certpath can be easily improved to support cafile when the path is not a directory - a small fix in libmesode.

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 a pull request may close this issue.

3 participants