Package: release.debian.org
Severity: normal
Tags: trixie
X-Debbugs-Cc: [email protected]
Control: affects -1 + src:erlang-p1-tls
User: [email protected]
Usertags: pu


[ Reason ]
Let's Encrypt has recently ended the support for TLS Client
Authentication in their certificates, see
https://letsencrypt.org/2025/05/14/ending-tls-client-authentication
and https://blog.prosody.im/2026-letsencrypt-changes/, as well as
Debian bugs #1127369 + #1128568.

This breaks communication with ejabberd servers, as they use the
certificate also in client mode for server-to-server connections.

To permit s2s communication with the new certifcates, both the erlang-p1-tls
package and the ejabberd package must be updated. If the ejabberd-contrib
package is used, that one must also be updated to a version built
against the updated ejabberd package.

[ Impact ]
Without addressing this, federation between XMPP servers (s2s) will become
more and more broken as more and more servers renew certificates which are
then missing the client authentication flag.

[ Tests ]
I have deployed the updated package to my own server together with
updated ejabberd + ejabberd-contrib packages, after which I could
finally contact other ejabberd servers again that already run recent
Let's Encrypt certificates without the client authentication flag.

[ Risks ]
None. Changes are trivial.

[ Checklist ]
  [x] *all* changes are documented in the d/changelog
  [x] I reviewed all changes and I approve them
  [x] attach debdiff against the package in (old)stable
  [x] the issue is verified as fixed in unstable

[ Changes ]
Add upstream commit as patch which allows accepting client certificates without
the client purpose flag.

[ Other info ]
The fix is already part of current ejabberd releases and thereby also fixed in
unstable.

I will upload to proposed-updates right away.
diff -Nru erlang-p1-tls-1.1.22/debian/changelog 
erlang-p1-tls-1.1.22/debian/changelog
--- erlang-p1-tls-1.1.22/debian/changelog       2025-02-09 11:09:55.000000000 
+0100
+++ erlang-p1-tls-1.1.22/debian/changelog       2026-02-10 19:41:06.000000000 
+0100
@@ -1,3 +1,10 @@
+erlang-p1-tls (1.1.22-1+deb13u1) trixie; urgency=medium
+
+  * Add upstream commit which allows accepting client certificates without
+    the sslclient purpose flag (Closes: #1127369)
+
+ -- Philipp Huebner <[email protected]>  Tue, 10 Feb 2026 19:41:06 +0100
+
 erlang-p1-tls (1.1.22-1) unstable; urgency=medium
 
   * New upstream version 1.1.22
diff -Nru 
erlang-p1-tls-1.1.22/debian/patches/f1e55d6d6bdf109ebc48dda880d028c95f349c3b.patch
 
erlang-p1-tls-1.1.22/debian/patches/f1e55d6d6bdf109ebc48dda880d028c95f349c3b.patch
--- 
erlang-p1-tls-1.1.22/debian/patches/f1e55d6d6bdf109ebc48dda880d028c95f349c3b.patch
  1970-01-01 01:00:00.000000000 +0100
+++ 
erlang-p1-tls-1.1.22/debian/patches/f1e55d6d6bdf109ebc48dda880d028c95f349c3b.patch
  2026-02-10 19:41:06.000000000 +0100
@@ -0,0 +1,111 @@
+From f1e55d6d6bdf109ebc48dda880d028c95f349c3b Mon Sep 17 00:00:00 2001
+From: Pawel Chmielowski <[email protected]>
+Date: Mon, 7 Jul 2025 10:13:50 +0200
+Subject: [PATCH] Add flag to allow accepting client cert without sslclient
+ purpose flag
+
+---
+ c_src/fast_tls.c | 22 ++++++++++++++++++++--
+ src/fast_tls.erl |  7 ++++++-
+ 2 files changed, 26 insertions(+), 3 deletions(-)
+
+Index: erlang-p1-tls/c_src/fast_tls.c
+===================================================================
+--- erlang-p1-tls.orig/c_src/fast_tls.c
++++ erlang-p1-tls/c_src/fast_tls.c
+@@ -26,6 +26,7 @@
+ #include <openssl/decoder.h>
+ #include <openssl/provider.h>
+ #endif
++#include <openssl/x509v3.h>
+ #include <sys/types.h>
+ #include <sys/stat.h>
+ #include <stdint.h>
+@@ -263,6 +264,19 @@ static int verify_callback(int preverify
+ }
+ 
+ /*
++ * Override cert purpose, to accept certificates that have only
++ * server purpose flag as client certificate (needed for s2s authentication).
++ */
++static int cert_verify_callback(X509_STORE_CTX *x509, void *ptr) {
++    X509_VERIFY_PARAM *param = X509_STORE_CTX_get0_param(x509);
++    if (param) {
++      X509_VERIFY_PARAM_set_purpose(param, X509_PURPOSE_SSL_SERVER);
++      X509_VERIFY_PARAM_set_trust(param, X509_TRUST_SSL_SERVER);
++    }
++    return X509_verify_cert(x509);
++}
++
++/*
+  * ECDHE is enabled only on OpenSSL 1.0.0e and later.
+  * See http://www.openssl.org/news/secadv_20110906.txt
+  * for details.
+@@ -549,6 +563,7 @@ static int ssl_sni_callback(const SSL *s
+ #define SET_CERTIFICATE_FILE_CONNECT 2
+ #define VERIFY_NONE 0x10000
+ #define COMPRESSION_NONE 0x100000
++#define OVERRIDE_CERT_PURPOSE 0x200000
+ 
+ static ERL_NIF_TERM ssl_error(ErlNifEnv *env, const char *errstr) {
+     size_t rlen;
+@@ -579,6 +594,7 @@ static SSL_CTX *create_new_ctx(char *cer
+                                char *ciphers, unsigned char *dh, size_t 
dh_size,
+                                char *dh_file, char *ca_file,
+                                unsigned int command,
++                               unsigned long flags,
+                                char **err_str) {
+     long verifyopts;
+     int res = 0;
+@@ -650,6 +666,8 @@ static SSL_CTX *create_new_ctx(char *cer
+     SSL_CTX_set_mode(ctx, SSL_MODE_RELEASE_BUFFERS);
+ #endif
+     SSL_CTX_set_verify(ctx, verifyopts, verify_callback);
++    if (flags & OVERRIDE_CERT_PURPOSE)
++        SSL_CTX_set_cert_verify_callback(ctx, cert_verify_callback, NULL);
+ 
+ #ifndef SSL_OP_NO_RENEGOTIATION
+     SSL_CTX_set_info_callback(ctx, &ssl_info_callback);
+@@ -721,7 +739,7 @@ static char *create_ssl_for_cert(char *c
+ 
+         enif_rwlock_rwlock(certs_map_lock);
+         SSL_CTX *ctx = create_new_ctx(cert_file, key_file, ciphers, dh, 
dh_size,
+-                                      dh_file, ca_file, command, &ret);
++                                      dh_file, ca_file, command,options & 
OVERRIDE_CERT_PURPOSE, &ret);
+         if (ret == NULL) {
+             new_info = enif_alloc(sizeof(cert_info_t));
+             if (new_info) {
+@@ -839,7 +857,7 @@ static ERL_NIF_TERM open_nif(ErlNifEnv *
+     state->dh_file = (char*)(state->dh + dh_bin.size + 1);
+     state->ca_file = state->dh_file + dhfile_bin.size + 1;
+     sni = state->ca_file + cafile_bin.size + 1;
+-    state->options = options;
++    state->options = options | (flags & OVERRIDE_CERT_PURPOSE);
+     state->command = command;
+ 
+     memcpy(state->cert_file, certfile_bin.data, certfile_bin.size);
+Index: erlang-p1-tls/src/fast_tls.erl
+===================================================================
+--- erlang-p1-tls.orig/src/fast_tls.erl
++++ erlang-p1-tls/src/fast_tls.erl
+@@ -67,6 +67,7 @@
+ -define(VERIFY_NONE, 16#10000).
+ 
+ -define(COMPRESSION_NONE, 16#100000).
++-define(OVERRIDE_CERT_PURPOSE, 16#200000).
+ 
+ -define(PRINT(Format, Args), io:format(Format, Args)).
+ 
+@@ -148,7 +149,11 @@ tcp_to_tls(TCPSocket, Options) ->
+                      true -> ?COMPRESSION_NONE;
+                      false -> 0
+                  end,
+-        Flags = Flags1 bor Flags2,
++        Flags3 = case lists:member(override_cert_purpose, Options) of
++                     true -> ?OVERRIDE_CERT_PURPOSE;
++                     false -> 0
++                 end,
++        Flags = Flags1 bor Flags2 bor Flags3,
+         Ciphers =
+         case lists:keysearch(ciphers, 1, Options) of
+             {value, {ciphers, C}} ->
diff -Nru erlang-p1-tls-1.1.22/debian/patches/series 
erlang-p1-tls-1.1.22/debian/patches/series
--- erlang-p1-tls-1.1.22/debian/patches/series  1970-01-01 01:00:00.000000000 
+0100
+++ erlang-p1-tls-1.1.22/debian/patches/series  2026-02-10 19:41:06.000000000 
+0100
@@ -0,0 +1 @@
+f1e55d6d6bdf109ebc48dda880d028c95f349c3b.patch

Reply via email to