Bug#1140227: apt: HTTPS acquire fails under OpenSSL FIPS-only mode (missing ERR_clear_error before SSL_read/write)

Michael Hamill <[email protected]> Wed, 17 Jun 2026 09:00:09 -0400
Newsgroups gmane.linux.debian.apt.devel
Message-ID <CAB_Va8MKm97t9P0VMfg1kbdxm-XpEhb=dHE3EPdnmhSs5hdb9Q__14190.4462406941$1781701291$gmane$org@mail.gmail.com>
--0000000000006be57e065472a4aa
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: quoted-printable

Package: apt
Version: 3.0.3
Severity: important

Dear Maintainer,

With OpenSSL configured in FIPS-only mode (only the "base" and "fips"
providers
active; the "default" provider disabled), "apt-get update"/"install"
against an
HTTPS repository intermittently fails with:

  Err:N https://...repo...
    OpenSSL error: error:0308010C:digital envelope routines::unsupported
    Error reading from server - read (5: Input/output error)

Root cause
----------
During the TLS handshake, libssl performs an implicit EVP_MD_fetch() for th=
e
legacy MD5 / MD5-SHA1 digests (used for pre-TLS-1.2 handshake signing and
the
TLS 1.0/1.1 PRF). Under a FIPS-only provider configuration those digests ar=
e
unavailable (they exist only in the default provider), so the fetch fails
and
leaves "error:0308010C ... unsupported" on the thread's OpenSSL error queue=
.

This is benign: the handshake completes fine. "openssl s_client" to the sam=
e
host under the identical FIPS config connects successfully with the very
same
failed MD5/MD5-SHA1 fetches (verifiable with an LD_PRELOAD trace of
EVP_MD_fetch).

The actual failure is that apt does not clear the OpenSSL error queue
before its
TLS I/O. In methods/connect.cc, TlsFd::Read() and TlsFd::Write() call
SSL_read()/SSL_write() and then HandleError() -> SSL_get_error() WITHOUT a
preceding ERR_clear_error(). When SSL_read() later returns <=3D 0 for a ben=
ign
reason, SSL_get_error() consults the non-empty error queue, returns
SSL_ERROR_SSL, and apt reports the stale MD5 error as a fatal read failure
(errno =3D EIO -> "Error reading from server").

This violates the documented precondition in SSL_get_error(3): "The current
thread's error queue must be empty before the TLS/SSL I/O operation is
attempted, [...] as the SSL_get_error() function uses the error queue
[...]."

PostgreSQL fixed the identical class of bug (stale FIPS-mode error-queue
entry
misreported later) by calling ERR_clear_error() "on the way in"; libpq
already
does this around its OpenSSL I/O.

This did not occur before Debian 13 / apt 3.0: apt 2.6 (bookworm) used
GnuTLS
for its TLS transport, which does not touch OpenSSL's providers or error
queue.

Reproduction (Debian 13)
------------------------------
Minimal, self-contained Dockerfile. The build itself fails at the final RUN
(installing Docker from an HTTPS repo) -- "docker build ." is the whole
repro:

    FROM debian:13-slim
    SHELL ["/bin/bash", "-o", "pipefail", "-c"]

    # FIPS-only OpenSSL: install the FIPS provider, then activate base +
fips and
    # disable the default provider.
    RUN apt-get update --yes \
     && apt-get install --yes --no-install-recommends \
            ca-certificates openssl openssl-provider-fips \
     && MODULES_DIR=3D"$(openssl version -m | cut -d'"' -f2)" \
     && openssl fipsinstall -out /etc/ssl/fipsmodule.cnf -module
"${MODULES_DIR}/fips.so"
    RUN sed -i 's|^#\s*\.include\s\+fipsmodule.cnf|.include
/etc/ssl/fipsmodule.cnf|' /etc/ssl/openssl.cnf \
     && sed -i 's/^default\s*=3D\s*default_sect/# default =3D default_sect/=
'
/etc/ssl/openssl.cnf \
     && sed -i 's/^#\s*fips\s*=3D\s*fips_sect/fips =3D fips_sect\nbase =3D
base_sect\n\n[base_sect]\nactivate =3D 1/' /etc/ssl/openssl.cnf
    # ("openssl list -providers" now shows only base + fips.)

    # Install Docker from its official HTTPS apt repo (any HTTPS repo
triggers it;
    # this is just a convenient public one). This RUN fails:
    #   OpenSSL error: error:0308010C ... Error reading from server
    #   E: Package 'docker-ce' has no installation candidate
    RUN apt-get install --no-install-recommends -y ca-certificates curl
gnupg \
     && install -m 0755 -d /etc/apt/keyrings \
     && curl -fsSL https://download.docker.com/linux/debian/gpg | gpg
--dearmor -o /etc/apt/keyrings/docker.gpg \
     && echo "deb [signed-by=3D/etc/apt/keyrings/docker.gpg]
https://download.docker.com/linux/debian trixie stable" \
          > /etc/apt/sources.list.d/docker.list \
     && apt-get update \
     && apt-get install --no-install-recommends -y docker-ce docker-ce-cli
containerd.io

Build it:

    docker build .

The build fails at the final RUN with the error:0308010C / "Error reading
from
server" message above. (The underlying trigger is a read returning <=3D 0
while
the stale error is queued, so in principle a fluke pass is possible; in
practice
fetching the Docker repo over HTTPS this way fails on essentially every
build,
matching what we see in CI. If a build does pass, rebuild with --no-cache.)

For contrast, the connection itself is fine and the failed MD5 fetch is
benign --
both of these succeed under the identical FIPS config:

    # same handshake, succeeds, proving MD5 is not actually needed:
    openssl s_client -connect download.docker.com:443 -servername
download.docker.com </dev/null
    # and apt works if the default provider is made available:
    OPENSSL_CONF=3D/dev/null apt-get update     # (with the docker.list
source above)

System information
------------------
Debian release: 13 (trixie), amd64

Versions of relevant packages:
  apt          3.0.3
  libssl3t64   3.5.6-1~deb13u2   (OpenSSL; apt's TLS backend in 3.0)
  openssl      3.5.6-1~deb13u2
  libc6        2.41-12+deb13u3

Reproduced in a stock debian:13-slim container (see Dockerfile above).

Suggested fix
-------------
Clear the OpenSSL error queue immediately before each
SSL_read()/SSL_write() in
methods/connect.cc, mirroring libpq:

    ssize_t Read(void *buf, size_t count) override {
       assert(ssl);
    +  ERR_clear_error();
       return HandleError(SSL_read(ssl, buf, count));
    }
    ssize_t Write(void *buf, size_t count) override {
       assert(ssl);
    +  ERR_clear_error();
       return HandleError(SSL_write(ssl, buf, count));
    }

This makes apt robust to any benign leftover OpenSSL error, not just the
FIPS/MD5 case.

Michael Hamill
Senior Software Engineer II
[email protected]
www.wellhive.com


WELLHIVE CONFIDENTIALITY NOTICE: The contents of this email message and any=
 attachments are intended solely for the addressee(s). Unless otherwise ind=
icated, it contains information that is confidential, privileged and/or exe=
mpt from disclosure under applicable law. If you are not the named addresse=
e, you are not authorized to read, print, retain, copy or disseminate this =
message or any part of it. If you have received this message in error, plea=
se notify the sender immediately by e-mail and delete all copies of the mes=
sage.=20

--0000000000006be57e065472a4aa
Content-Type: multipart/related; boundary="=-GkqDXpLl9ezT2U8GiX+1xg=="

--=-GkqDXpLl9ezT2U8GiX+1xg==
Content-Type: text/html; charset=utf-8
Content-Transfer-Encoding: quoted-printable

<html><head></head><body><div dir=3D"ltr">Package: apt<br>Version: 3.0.3<br=
>Severity: important<br><br>Dear Maintainer,<br><br>With OpenSSL configured=
 in FIPS-only mode (only the &quot;base&quot; and &quot;fips&quot; provider=
s<br>active; the &quot;default&quot; provider disabled), &quot;apt-get upda=
te&quot;/&quot;install&quot; against an<br>HTTPS repository intermittently =
fails with:<br><br>=C2=A0 Err:N https://...repo...<br>=C2=A0 =C2=A0 OpenSSL=
 error: error:0308010C:digital envelope routines::unsupported<br>=C2=A0 =C2=
=A0 Error reading from server - read (5: Input/output error)<br><br>Root ca=
use<br>----------<br>During the TLS handshake, libssl performs an implicit =
EVP_MD_fetch() for the<br>legacy MD5 / MD5-SHA1 digests (used for pre-TLS-1=
.2 handshake signing and the<br>TLS 1.0/1.1 PRF). Under a FIPS-only provide=
r configuration those digests are<br>unavailable (they exist only in the de=
fault provider), so the fetch fails and<br>leaves &quot;error:0308010C ... =
unsupported&quot; on the thread&#39;s OpenSSL error queue.<br><br>This is b=
enign: the handshake completes fine. &quot;openssl s_client&quot; to the sa=
me<br>host under the identical FIPS config connects successfully with the v=
ery same<br>failed MD5/MD5-SHA1 fetches (verifiable with an LD_PRELOAD trac=
e of<br>EVP_MD_fetch).<br><br>The actual failure is that apt does not clear=
 the OpenSSL error queue before its<br>TLS I/O. In methods/connect.cc, TlsF=
d::Read() and TlsFd::Write() call<br>SSL_read()/SSL_write() and then Handle=
Error() -&gt; SSL_get_error() WITHOUT a<br>preceding ERR_clear_error(). Whe=
n SSL_read() later returns &lt;=3D 0 for a benign<br>reason, SSL_get_error(=
) consults the non-empty error queue, returns<br>SSL_ERROR_SSL, and apt rep=
orts the stale MD5 error as a fatal read failure<br>(errno =3D EIO -&gt; &q=
uot;Error reading from server&quot;).<br><br>This violates the documented p=
recondition in SSL_get_error(3): &quot;The current<br>thread&#39;s error qu=
eue must be empty before the TLS/SSL I/O operation is<br>attempted, [...] a=
s the SSL_get_error() function uses the error queue [...].&quot;<br><br>Pos=
tgreSQL fixed the identical class of bug (stale FIPS-mode error-queue entry=
<br>misreported later) by calling ERR_clear_error() &quot;on the way in&quo=
t;; libpq already<br>does this around its OpenSSL I/O.<br><br>This did not =
occur before Debian 13 / apt 3.0: apt 2.6 (bookworm) used GnuTLS<br>for its=
 TLS transport, which does not touch OpenSSL&#39;s providers or error queue=
.<br><br>Reproduction (Debian 13)<br>------------------------------<br>Mini=
mal, self-contained Dockerfile. The build itself fails at the final RUN<br>=
(installing Docker from an HTTPS repo) -- &quot;docker build .&quot; is the=
 whole repro:<br><br>=C2=A0 =C2=A0 FROM debian:13-slim<br>=C2=A0 =C2=A0 SHE=
LL [&quot;/bin/bash&quot;, &quot;-o&quot;, &quot;pipefail&quot;, &quot;-c&q=
uot;]<br><br>=C2=A0 =C2=A0 # FIPS-only OpenSSL: install the FIPS provider, =
then activate base + fips and<br>=C2=A0 =C2=A0 # disable the default provid=
er.<br>=C2=A0 =C2=A0 RUN apt-get update --yes \<br>=C2=A0 =C2=A0 =C2=A0&amp=
;&amp; apt-get install --yes --no-install-recommends \<br>=C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0 ca-certificates openssl openssl-provider-fips \<br=
>=C2=A0 =C2=A0 =C2=A0&amp;&amp; MODULES_DIR=3D&quot;$(openssl version -m | =
cut -d&#39;&quot;&#39; -f2)&quot; \<br>=C2=A0 =C2=A0 =C2=A0&amp;&amp; opens=
sl fipsinstall -out /etc/ssl/fipsmodule.cnf -module &quot;${MODULES_DIR}/fi=
ps.so&quot;<br>=C2=A0 =C2=A0 RUN sed -i &#39;s|^#\s*\.include\s\+fipsmodule=
.cnf|.include /etc/ssl/fipsmodule.cnf|&#39; /etc/ssl/openssl.cnf \<br>=C2=A0=
 =C2=A0 =C2=A0&amp;&amp; sed -i &#39;s/^default\s*=3D\s*default_sect/# defa=
ult =3D default_sect/&#39; /etc/ssl/openssl.cnf \<br>=C2=A0 =C2=A0 =C2=A0&a=
mp;&amp; sed -i &#39;s/^#\s*fips\s*=3D\s*fips_sect/fips =3D fips_sect\nbase=
 =3D base_sect\n\n[base_sect]\nactivate =3D 1/&#39; /etc/ssl/openssl.cnf<br=
>=C2=A0 =C2=A0 # (&quot;openssl list -providers&quot; now shows only base +=
 fips.)<br><br>=C2=A0 =C2=A0 # Install Docker from its official HTTPS apt r=
epo (any HTTPS repo triggers it;<br>=C2=A0 =C2=A0 # this is just a convenie=
nt public one). This RUN fails:<br>=C2=A0 =C2=A0 # =C2=A0 OpenSSL error: er=
ror:0308010C ... Error reading from server<br>=C2=A0 =C2=A0 # =C2=A0 E: Pac=
kage &#39;docker-ce&#39; has no installation candidate<br>=C2=A0 =C2=A0 RUN=
 apt-get install --no-install-recommends -y ca-certificates curl gnupg \<br=
>=C2=A0 =C2=A0 =C2=A0&amp;&amp; install -m 0755 -d /etc/apt/keyrings \<br>=C2=
=A0 =C2=A0 =C2=A0&amp;&amp; curl -fsSL <a href=3D"https://download.docker.c=
om/linux/debian/gpg">https://download.docker.com/linux/debian/gpg</a> | gpg=
 --dearmor -o /etc/apt/keyrings/docker.gpg \<br>=C2=A0 =C2=A0 =C2=A0&amp;&a=
mp; echo &quot;deb [signed-by=3D/etc/apt/keyrings/docker.gpg] <a href=3D"ht=
tps://download.docker.com/linux/debian">https://download.docker.com/linux/d=
ebian</a> trixie stable&quot; \<br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 &gt; =
/etc/apt/sources.list.d/docker.list \<br>=C2=A0 =C2=A0 =C2=A0&amp;&amp; apt=
-get update \<br>=C2=A0 =C2=A0 =C2=A0&amp;&amp; apt-get install --no-instal=
l-recommends -y docker-ce docker-ce-cli <a href=3D"http://containerd.io">co=
ntainerd.io</a><br><br>Build it:<br><br>=C2=A0 =C2=A0 docker build .<br><br=
>The build fails at the final RUN with the error:0308010C / &quot;Error rea=
ding from<br>server&quot; message above. (The underlying trigger is a read =
returning &lt;=3D 0 while<br>the stale error is queued, so in principle a f=
luke pass is possible; in practice<br>fetching the Docker repo over HTTPS t=
his way fails on essentially every build,<br>matching what we see in CI. If=
 a build does pass, rebuild with --no-cache.)<br><br>For contrast, the conn=
ection itself is fine and the failed MD5 fetch is benign --<br>both of thes=
e succeed under the identical FIPS config:<br><br>=C2=A0 =C2=A0 # same hand=
shake, succeeds, proving MD5 is not actually needed:<br>=C2=A0 =C2=A0 opens=
sl s_client -connect <a href=3D"http://download.docker.com:443">download.do=
cker.com:443</a> -servername <a href=3D"http://download.docker.com">downloa=
d.docker.com</a> &lt;/dev/null<br>=C2=A0 =C2=A0 # and apt works if the defa=
ult provider is made available:<br>=C2=A0 =C2=A0 OPENSSL_CONF=3D/dev/null a=
pt-get update =C2=A0 =C2=A0 # (with the docker.list source above)<br><br>Sy=
stem information<br>------------------<br>Debian release: 13 (trixie), amd6=
4<br><br>Versions of relevant packages:<br>=C2=A0 apt =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A03.0.3<br>=C2=A0 libssl3t64 =C2=A0 3.5.6-1~deb13u2 =C2=A0 (Open=
SSL; apt&#39;s TLS backend in 3.0)<br>=C2=A0 openssl =C2=A0 =C2=A0 =C2=A03.=
5.6-1~deb13u2<br>=C2=A0 libc6 =C2=A0 =C2=A0 =C2=A0 =C2=A02.41-12+deb13u3<br=
><br>Reproduced in a stock debian:13-slim container (see Dockerfile above).=
<br><br>Suggested fix<br>-------------<br>Clear the OpenSSL error queue imm=
ediately before each SSL_read()/SSL_write() in<br>methods/connect.cc, mirro=
ring libpq:<br><br>=C2=A0 =C2=A0 ssize_t Read(void *buf, size_t count) over=
ride {<br>=C2=A0 =C2=A0 =C2=A0 =C2=A0assert(ssl);<br>=C2=A0 =C2=A0 + =C2=A0=
ERR_clear_error();<br>=C2=A0 =C2=A0 =C2=A0 =C2=A0return HandleError(SSL_rea=
d(ssl, buf, count));<br>=C2=A0 =C2=A0 }<br>=C2=A0 =C2=A0 ssize_t Write(void=
 *buf, size_t count) override {<br>=C2=A0 =C2=A0 =C2=A0 =C2=A0assert(ssl);<=
br>=C2=A0 =C2=A0 + =C2=A0ERR_clear_error();<br>=C2=A0 =C2=A0 =C2=A0 =C2=A0r=
eturn HandleError(SSL_write(ssl, buf, count));<br>=C2=A0 =C2=A0 }<br><br>Th=
is makes apt robust to any benign leftover OpenSSL error, not just the<br>F=
IPS/MD5 case.<br><input name=3D"virtru-metadata" type=3D"hidden" value=3D"{=
&quot;email-policy&quot;:{&quot;disableCopyPaste&quot;:false,&quot;disableP=
rint&quot;:false,&quot;disableForwarding&quot;:false,&quot;enableNoauth&quo=
t;:false,&quot;expires&quot;:false,&quot;sms&quot;:false,&quot;expirationNu=
m&quot;:1,&quot;expirationUnit&quot;:&quot;days&quot;,&quot;expirationDate&=
quot;:null,&quot;isManaged&quot;:false},&quot;attachments&quot;:{},&quot;co=
mpose-id&quot;:&quot;1&quot;,&quot;compose-window&quot;:{&quot;secure&quot;=
:false}}"></div>
<div dir=3D"ltr" style=3D"mso-line-height-rule:exactly;-webkit-text-size-ad=
just:100%;font-size:1px;direction:ltr;"><table dir=3D"ltr" cellpadding=3D"0=
" cellspacing=3D"0" border=3D"0" style=3D"width:100%;direction:ltr;border-c=
ollapse:collapse;font-size:1px;color:#000001;font-style:normal;font-weight:=
400;white-space:nowrap;"><tr style=3D"font-size:0;"><td align=3D"left" styl=
e=3D"vertical-align:top;"><table cellpadding=3D"0" cellspacing=3D"0" border=
=3D"0" style=3D"border-collapse:collapse;font-size:0;"><tr style=3D"font-si=
ze:0;"><td align=3D"left" style=3D"padding:15px 0 20px;vertical-align:top;"=
><table cellpadding=3D"0" cellspacing=3D"0" border=3D"0" style=3D"border-co=
llapse:collapse;font-size:0;"><tr style=3D"font-size:0;"><td align=3D"cente=
r" style=3D"padding:10px;vertical-align:top;"><table cellpadding=3D"0" cell=
spacing=3D"0" border=3D"0" style=3D"border-collapse:collapse;font-size:0;li=
ne-height:normal;"><tr style=3D"font-size:0;"><td align=3D"center" style=3D=
"padding:10px 15px;vertical-align:top;"><img src=3D"cid:image985900.png@410=
D6375.4A9EA34D" width=3D"60" height=3D"70" border=3D"0" alt=3D"" style=3D"w=
idth:60px;min-width:60px;max-width:60px;height:70px;min-height:70px;max-hei=
ght:70px;font-size:0;" /></td></tr></table></td><td align=3D"left" style=3D=
"padding:10px 10px 10px 15px;border-top:none;border-right:none;border-botto=
m:none;border-left:solid 1px #A1A1A1;vertical-align:top;"><table cellpaddin=
g=3D"0" cellspacing=3D"0" border=3D"0" style=3D"border-collapse:collapse;fo=
nt-size:0;"><tr style=3D"font-size:0;"><td align=3D"left" style=3D"vertical=
-align:top;"><table cellpadding=3D"0" cellspacing=3D"0" border=3D"0" style=3D=
"border-collapse:collapse;font-size:0;color:#3D3D3D;font-style:normal;font-=
weight:700;white-space:nowrap;"><tr style=3D"font-size:15px;"><td align=3D"=
left" style=3D"vertical-align:top;font-family:Arial;">Michael&nbsp;Hamill</=
td></tr><tr style=3D"font-size:13.33px;font-style:italic;font-weight:400;">=
<td align=3D"left" style=3D"vertical-align:top;font-family:Arial;">Senior&n=
bsp;Software&nbsp;Engineer&nbsp;II</td></tr></table></td></tr><tr style=3D"=
font-size:0;"><td align=3D"left" style=3D"vertical-align:top;"><table cellp=
adding=3D"0" cellspacing=3D"0" border=3D"0" style=3D"border-collapse:collap=
se;font-size:0;"><tr style=3D"font-size:0;"><td align=3D"left" style=3D"pad=
ding:10px 2px 2px 0;vertical-align:top;"><table cellpadding=3D"0" cellspaci=
ng=3D"0" border=3D"0" style=3D"border-collapse:collapse;font-size:0;color:#=
3D3D3D;font-style:normal;font-weight:400;white-space:nowrap;"><tr style=3D"=
font-size:13.33px;"><td align=3D"left" style=3D"vertical-align:top;font-siz=
e:0;"><table cellpadding=3D"0" cellspacing=3D"0" border=3D"0" style=3D"bord=
er-collapse:collapse;font-size:0;line-height:normal;"><tr style=3D"font-siz=
e:0;"><td align=3D"left" style=3D"padding:0 7px 0 0;vertical-align:top;"><i=
mg src=3D"cid:[email protected]" width=3D"18" height=3D"18"=
 border=3D"0" alt=3D"" style=3D"width:18px;min-width:18px;max-width:18px;he=
ight:18px;min-height:18px;max-height:18px;font-size:0;" /></td></tr></table=
></td><td align=3D"left" style=3D"vertical-align:top;font-family:Arial;">mi=
[email protected]<br /></td></tr></table></td></tr></table></td></t=
r><tr style=3D"font-size:0;"><td align=3D"left" style=3D"vertical-align:top=
;"><table cellpadding=3D"0" cellspacing=3D"0" border=3D"0" style=3D"border-=
collapse:collapse;font-size:0;"><tr style=3D"font-size:0;"><td align=3D"lef=
t" style=3D"padding:2px 2px 2px 0;vertical-align:top;"><table cellpadding=3D=
"0" cellspacing=3D"0" border=3D"0" style=3D"border-collapse:collapse;font-s=
ize:0;color:#3D3D3D;font-style:normal;font-weight:400;white-space:nowrap;">=
<tr style=3D"font-size:13.33px;"><td align=3D"left" style=3D"vertical-align=
:top;font-size:0;"><table cellpadding=3D"0" cellspacing=3D"0" border=3D"0" =
style=3D"border-collapse:collapse;font-size:0;line-height:normal;"><tr styl=
e=3D"font-size:0;"><td align=3D"left" style=3D"padding:0 7px 0 0;vertical-a=
lign:top;"><img src=3D"cid:[email protected]" width=3D"18" =
height=3D"18" border=3D"0" alt=3D"" style=3D"width:18px;min-width:18px;max-=
width:18px;height:18px;min-height:18px;max-height:18px;font-size:0;" /></td=
></tr></table></td><td align=3D"left" style=3D"vertical-align:top;font-fami=
ly:Arial;">www.<a href=3D"https://www.wellhive.com/" target=3D"_blank" id=3D=
"LPlnk689713" title=3D"WellHive" style=3D"text-decoration:none;color:#3D3D3=
D;">wellhive.com</a></td></tr></table></td></tr></table></td></tr></table><=
/td></tr></table></td></tr></table></td></tr><tr style=3D"font-size:14.67px=
;"><td align=3D"left" style=3D"vertical-align:top;font-family:Arial;"><br /=
></td></tr></table></div><div dir=3D"ltr" style=3D"mso-line-height-rule:exa=
ctly;-webkit-text-size-adjust:100%;font-size:1px;direction:ltr;"><table dir=
=3D"ltr" cellpadding=3D"0" cellspacing=3D"0" border=3D"0" style=3D"width:10=
0%;direction:ltr;border-collapse:collapse;font-size:1px;"><tr style=3D"font=
-size:1px;"><td align=3D"left" style=3D"vertical-align:top;font-size:0;"><t=
able cellpadding=3D"0" cellspacing=3D"0" border=3D"0" style=3D"white-space:=
normal;color:#000001;font-size:14.67px;font-family:Calibri,Arial,sans-serif=
;font-weight:400;font-style:normal;text-align:justify;width:100%;border-col=
lapse:collapse;"><tr style=3D"font-size:13px;"><td style=3D"font-family:Cal=
ibri;">WELLHIVE CONFIDENTIALITY NOTICE: The contents of this email message =
and any attachments are intended solely for the addressee(s). Unless otherw=
ise indicated, it contains information that is confidential, privileged and=
/or exempt from disclosure under applicable law. If you are not the named a=
ddressee, you are not authorized to read, print, retain, copy or disseminat=
e this message or any part of it. If you have received this message in erro=
r, please notify the sender immediately by e-mail and delete all copies of =
the message.&nbsp;<br /></td></tr></table></td><td><span style=3D"font-fami=
ly:remialcxesans;font-size:1px;color:#FFFFFF;line-height:1px;">&#8203;<span=
 style=3D"font-family:&#39;template-DfPSVQa9Ee20eygYeG7fbQ&#39;;">&#8203;</=
span><span style=3D"font-family:&#39;zone-1&#39;;">&#8203;</span><span styl=
e=3D"font-family:&#39;zones-AQ&#39;;">&#8203;</span></span></td></tr></tabl=
e></div></body></html>=

--=-GkqDXpLl9ezT2U8GiX+1xg==
Content-Type: image/png; name=image985900.png
Content-Transfer-Encoding: base64
Content-Id: <[email protected]>
Content-Description: image985900.png
Content-Disposition: inline; filename=image985900.png; size=3645;
	creation-date="Wed, 17 Jun 2026 13:00:24 +0000";
	modification-date="Wed, 17 Jun 2026 13:00:24 +0000"

iVBORw0KGgoAAAANSUhEUgAAADwAAABGCAYAAACQRffVAAAACXBIWXMAAC4jAAAuIwF4pT92AAAG
xmlUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0w
TXBDZWhpSHpyZVN6TlRjemtjOWQiPz4gPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRh
LyIgeDp4bXB0az0iQWRvYmUgWE1QIENvcmUgNi4wLWMwMDIgNzkuMTY0MzUyLCAyMDIwLzAxLzMw
LTE1OjUwOjM4ICAgICAgICAiPiA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3Jn
LzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPiA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0i
IiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtbG5zOmRjPSJodHRw
Oi8vcHVybC5vcmcvZGMvZWxlbWVudHMvMS4xLyIgeG1sbnM6cGhvdG9zaG9wPSJodHRwOi8vbnMu
YWRvYmUuY29tL3Bob3Rvc2hvcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNv
bS94YXAvMS4wL21tLyIgeG1sbnM6c3RFdnQ9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9z
VHlwZS9SZXNvdXJjZUV2ZW50IyIgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgMjEu
MSAoTWFjaW50b3NoKSIgeG1wOkNyZWF0ZURhdGU9IjIwMTktMTEtMTRUMTI6NDc6MzYtMDU6MDAi
IHhtcDpNb2RpZnlEYXRlPSIyMDIwLTA1LTIyVDE1OjI3OjQ1LTA0OjAwIiB4bXA6TWV0YWRhdGFE
YXRlPSIyMDIwLTA1LTIyVDE1OjI3OjQ1LTA0OjAwIiBkYzpmb3JtYXQ9ImltYWdlL3BuZyIgcGhv
dG9zaG9wOkNvbG9yTW9kZT0iMyIgcGhvdG9zaG9wOklDQ1Byb2ZpbGU9InNSR0IgSUVDNjE5NjYt
Mi4xIiB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOmRhNzI4OGMzLTA1YjItNGRmZS1iNjRmLWJm
MTUyYTZlZmYxNSIgeG1wTU06RG9jdW1lbnRJRD0iYWRvYmU6ZG9jaWQ6cGhvdG9zaG9wOjQ1YzY0
ODEyLWY4YzMtM2Q0NC1hMjc2LTE0NTg0ZGYwMDEzYSIgeG1wTU06T3JpZ2luYWxEb2N1bWVudElE
PSJ4bXAuZGlkOjc4NmEwYmU5LTBmZjQtNDVmZi05NGExLWExZTRjOTFmOWJhOSI+IDx4bXBNTTpI
aXN0b3J5PiA8cmRmOlNlcT4gPHJkZjpsaSBzdEV2dDphY3Rpb249ImNyZWF0ZWQiIHN0RXZ0Omlu
c3RhbmNlSUQ9InhtcC5paWQ6Nzg2YTBiZTktMGZmNC00NWZmLTk0YTEtYTFlNGM5MWY5YmE5IiBz
dEV2dDp3aGVuPSIyMDE5LTExLTE0VDEyOjQ3OjM2LTA1OjAwIiBzdEV2dDpzb2Z0d2FyZUFnZW50
PSJBZG9iZSBQaG90b3Nob3AgMjEuMSAoTWFjaW50b3NoKSIvPiA8cmRmOmxpIHN0RXZ0OmFjdGlv
bj0ic2F2ZWQiIHN0RXZ0Omluc3RhbmNlSUQ9InhtcC5paWQ6M2EyZDMyZGItODFlNy00NThjLWI4
NjUtMzQ5YjljN2E0ZmFkIiBzdEV2dDp3aGVuPSIyMDIwLTA0LTEwVDE2OjU5OjI3LTA0OjAwIiBz
dEV2dDpzb2Z0d2FyZUFnZW50PSJBZG9iZSBQaG90b3Nob3AgMjEuMSAoTWFjaW50b3NoKSIgc3RF
dnQ6Y2hhbmdlZD0iLyIvPiA8cmRmOmxpIHN0RXZ0OmFjdGlvbj0ic2F2ZWQiIHN0RXZ0Omluc3Rh
bmNlSUQ9InhtcC5paWQ6ZGE3Mjg4YzMtMDViMi00ZGZlLWI2NGYtYmYxNTJhNmVmZjE1IiBzdEV2
dDp3aGVuPSIyMDIwLTA1LTIyVDE1OjI3OjQ1LTA0OjAwIiBzdEV2dDpzb2Z0d2FyZUFnZW50PSJB
ZG9iZSBQaG90b3Nob3AgMjEuMSAoTWFjaW50b3NoKSIgc3RFdnQ6Y2hhbmdlZD0iLyIvPiA8L3Jk
ZjpTZXE+IDwveG1wTU06SGlzdG9yeT4gPC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94
OnhtcG1ldGE+IDw/eHBhY2tldCBlbmQ9InIiPz4CR+oAAAAHHUlEQVR42u2bXWwU1xWAv3tn9t/r
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

--=-GkqDXpLl9ezT2U8GiX+1xg==
Content-Type: image/png; name=image218692.png
Content-Transfer-Encoding: base64
Content-Id: <[email protected]>
Content-Description: image218692.png
Content-Disposition: inline; filename=image218692.png; size=448;
	creation-date="Wed, 17 Jun 2026 13:00:24 +0000";
	modification-date="Wed, 17 Jun 2026 13:00:24 +0000"

iVBORw0KGgoAAAANSUhEUgAAABIAAAASCAYAAABWzo5XAAAAAXNSR0IArs4c6QAAAARnQU1BAACx
jwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAFVSURBVDhP3ZM9S8NQFIbzTQYHh45dBMe6tdA1
WzIILo6Ojo4dnPwJzlLB/gDBRSKZ0s1RQcFF0EFw6dDBId/xfW9vo4GIySY+cDjn3Jz73nM/ovxf
VOkFvu/3VVU1ZPornue9yvBLKAiCW4iMZdqWR9M0R47jRBqzMAw34IaMOzKI47jPQAhB8QNuxrgj
c9d1nxlUHVmWdVyW5TnzllxjW/uY22MihKIo6qVpyjM6K4piF4ILjjeBb+z+MM/zoyRJbrIsG3Bc
CEm2UUSxIUR3kF+uhmvMsRC/KZqmPbBWjILvQgqvHnaClq+w4gTCB7Alu4DAhFvRdf0UpVPU8YIq
akJrUDTGinfwNs5ui4Z4ga084fPeqqpOoxDBxE24KSa/w16QX8DEwTbxo9AadgWrbaMJIWTb9htc
9dzbwrMzDOOecfWL8C3hKju9borgMS9l+qdQlE8AznuZYagu9gAAAABJRU5ErkJggg==

--=-GkqDXpLl9ezT2U8GiX+1xg==
Content-Type: image/png; name=image653561.png
Content-Transfer-Encoding: base64
Content-Id: <[email protected]>
Content-Description: image653561.png
Content-Disposition: inline; filename=image653561.png; size=626;
	creation-date="Wed, 17 Jun 2026 13:00:24 +0000";
	modification-date="Wed, 17 Jun 2026 13:00:24 +0000"

iVBORw0KGgoAAAANSUhEUgAAABIAAAASCAYAAABWzo5XAAAAAXNSR0IArs4c6QAAAARnQU1BAACx
jwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAIHSURBVDhPtZSvT1tRFMf7Ky0CgUBUkGwCMZL9
AzgaaHkkNc1CMkFD5pZsJAgIEkEIAsGfAAlmAkGyJ15VJ0qCqNjUJourQEwgXtrXls/39t7y3p4d
3+S8c+/58b3nnnvazP9C1uoUgiB4h/Ly+fwb7Uej0UMul+vUarWu9v8iReT7frlYLF6z3NB+Mpn8
zWazC1oL7LtI0/O8P9ZkkCCyJG2tCT5FhVTRR39gvy+7RX88HlfiZDMiR6IKhsNho16vi0BXPIDs
nOUt8oTfo8JF1gmynD6CvU4BXXUkAok3JOyR3KM/TfaryD2uMgd8n0bZitRYjL8JiJAGp/jGG0O7
3Z5DFaIoOoN4x/WN9RbxgavI0wdnAVFCCpVKJRwMBvskfnYkAq+6Lm2I3BMLBO1yesFuZ2i1Wh/x
negwazLgBm+lnTHurFP+OWSH2lDFDsHzEHwx3jRMrqlIwybtoPLVizAMlyC4RC4gW7LuBPD1pA0R
jf4h7YBzDrKv2NfQejEfmbfuBPDfSRsijT0nJkZfZIiqOcP3C5NOvkLiE91nXDRfL3NEcBM1mx8H
VYIcs/zGgZ+QFdYB8U/Yt3nNyMTp42DnST+R8tTyAq7QKJVKHXp3pB4St1WtVjvWnf7RWjJN7PLU
MsNPqnhPFY+qJE4ipIgcINRfyCbJZk5I7qmx6om7zisgk3kGL/L1gF4YudEAAAAASUVORK5CYII=

--=-GkqDXpLl9ezT2U8GiX+1xg==--

--0000000000006be57e065472a4aa--