+
    iHàjy7  ã                  óž  a € 0 t $ R t^ RIHt ^ RIt^ RIt^ RIt^ RIt^ RIH	t	 ^ RI
HtHt ]P                  ! ]4      tRsR]R&   R R ltR	 R
 lt/ tR]R&   ]P*                  ! 4       tR R ltR)R R lltR R lt/ tR]R&   ]P*                  ! 4       tR R ltR R ltR R ltR R ltRs R]R&   R R  lt!R! R" lt"R#RR$RR%R&/R' R( llt#R# )*u@  TLS trust for Hermes. One authority, one trust source.

Trust comes from the platform verifier via ``truststore``: CryptoAPI on
Windows, Security.framework on macOS, and OpenSSL's own store (with a
distro candidate sweep) on Linux. That is the machine's real answer to
"is this chain valid", so a corporate MITM root installed by MDM, an
internal CA, and a locked-down NixOS box all work with no configuration.

``install_truststore()`` runs once at process start and patches
``ssl.SSLContext`` process-wide, so every stack that builds a default
context inherits it â€” httpx, requests/urllib3, aiohttp, AND the stdlib
``urllib.request`` call sites (the llama.cpp engine download among them)
that a certifi-only or requests-only approach never reached.

An exported ``SSL_CERT_FILE`` bundle is trusted ON TOP of the platform
store; only EXPLICIT PER-PROVIDER CONFIG replaces that trust:
``ssl_ca_cert`` (a self-signed or internal endpoint's bundle) and
``ssl_verify: false`` (local development). Those are deliberate
statements about one endpoint, not an ambient guess about the machine.
)ÚannotationsN)ÚPath)ÚAnyÚOptionalzbool | NoneÚ
_installedc               ó   € V ^8„  d   QhRR/# )é   ÚreturnÚbool© )Úformats   "Ú5/home/ubuntu/.hermes/hermes-agent/agent/ssl_verify.pyÚ__annotate__r   $   s   € ÷ ñ ˜Dñ ó    c                 óì   € \         e   \         #  ^ RIp V P                  4        Rs \        P	                  R4       \         #   \
         d(   pRs \        P                  RT4        Rp?\         # Rp?ii ; i)al  Point every default SSLContext at the OS trust store. Idempotent.

Returns True when the platform verifier is in force. A False return
means truststore could not load (an unsupported platform, or a
stripped payload); TLS still works off OpenSSL's compiled-in paths,
it just won't see certificates the OS trusts.

Call before the first HTTPS client is constructed.
NTz&TLS trust: platform store (truststore)Fu­   truststore unavailable (%s); falling back to OpenSSL's default trust paths. Certificates trusted only by the OS store â€” a corporate root, for instance â€” will not verify.)r   Ú
truststoreÚinject_into_sslÚloggerÚdebugÚ	ExceptionÚwarning)r   Úexcs     r   Úinstall_truststorer   $   sy   € ô ÒÜÐð
Ûà×"Ñ"Ô$Øˆ
Ü�‰Ð=Ô>ô Ðøô ô 
Øˆ
Ü�‰ð@ð ÷		
ð 	
ô Ðûð
ús   �+A ÁA3ÁA.Á.A3c               ó    € V ^8„  d   QhRRRR/# )r   Ú
ssl_verifyr   r	   r
   r   )r   s   "r   r   r   B   s   € ÷ ñ  ð ¨ñ r   c                óŒ   € V R J d   R# \        V \        4      '       d&   V P                  4       P                  4       R9   d   R# R # )FT>   Ú0ÚnoÚoffÚfalse)Ú
isinstanceÚstrÚstripÚlower)r   s   &r   Ú_coerce_insecurer$   B   s:   € Ø�UÓÙÜ�*œc×"Ò" z×'7Ñ'7Ó'9×'?Ñ'?Ó'AÐE`Ô'`ÙÙr   z-dict[tuple[str | None, bool], ssl.SSLContext]Ú_CA_CONTEXTSc               ó   € V ^8„  d   QhRR/# )r   r	   ztype[ssl.SSLContext]r   )r   s   "r   r   r   N   s   € ÷  ñ  Ð#7ñ  r   c                 óp   € \         P                  P                  R8X  d   \         P                  # ^ RIHp  V # )u  The un-injected stdlib ``ssl.SSLContext``.

An explicit bundle must REPLACE OS trust, and truststore's context falls
back to the OS verifier whenever the loaded bundle rejects a chain â€” so
the bundle context has to be built from the stdlib class. Once injected
(here, or by pm.launch/pm.worker before this module loads) the only
handle on it is truststore's own saved reference; when nothing is
injected â€” truststore absent or not installed â€” ``ssl.SSLContext`` is
already the stdlib class and truststore must not be imported at all.
Ússl©Ú_original_SSLContext)r(   Ú
SSLContextÚ
__module__Útruststore._ssl_constantsr*   r)   s    r   Ú_stdlib_ssl_context_classr.   N   s)   € ô ‡~�~× Ñ  EÔ)Ü�~‰~ÐÝ>àÐr   c               ó$   € V ^8„  d   QhRRRRRR/# )r   Úca_pathz
str | NoneÚunionr
   r	   ússl.SSLContextr   )r   s   "r   r   r   `   s!   € ÷ ñ ˜Zð °ð Àñ r   c                óª  € \         ;_uu_ 4        \        P                  W34      pVfŒ   V e(   V'       g    \        4       ! \        P
                  4      pM@\        P                  ! \        P
                  4      p\        '       g   VP                  4        V e   VP                  V R7       V\        W3&   VuuRRR4       #   + '       g   i     R# ; i)zÓA stable context identity lets clients reuse the existing transport pool.

``union`` adds ``ca_path`` to the platform store (the ``SSL_CERT_FILE``
contract) instead of replacing it (a provider ``ssl_ca_cert``).
N)Úcafile)
Ú_CA_CONTEXTS_LOCKr%   Úgetr.   r(   ÚPROTOCOL_TLS_CLIENTr+   r   Úload_default_certsÚload_verify_locations)r0   r1   Úctxs   && r   Ú_shared_contextr;   `   sš   € ÷ 
Ö	Ü×Ñ Ð/Ó0ˆØŠ;ØÒ"¯5ô 0Ô1´#×2IÑ2IÓJ‘ä—n’n¤S×%<Ñ%<Ó=�ß!“zØ×*Ñ*Ô,ØÒ"Ø×)Ñ)°Ð)Ô9Ø-0ŒL˜'Ð)Ñ*Ø÷ 
×	×	Ó	ús   �&C¶ACÂ1CÃC	c               ó   € V ^8„  d   QhRR/# )r   r	   r2   r   )r   s   "r   r   r   w   s   € ÷ !ñ !˜nñ !r   c                 ó0  € \        4        \        P                  P                  RR4      P	                  4       p V '       dM   \        V 4      P                  4       '       d.   \        \        \        V 4      P                  4       4      RR7      # \        R4      # )zòThe process-wide client context (cheap after the first call).

An existing ``SSL_CERT_FILE`` bundle is trusted ON TOP of the platform store,
as it was for httpx ``verify=True``; a missing or stale path falls back to
the platform store alone.
ÚSSL_CERT_FILEÚ T)r1   N)
r   ÚosÚenvironr6   r"   r   Úis_filer;   r!   Úresolve)Úcas    r   Úplatform_ssl_contextrE   w   sf   € ô ÔÜ	�‰�‰˜¨Ó	,×	2Ñ	2Ó	4€Bß	Œd�2‹h×Ñ× Ò Üœs¤4¨£8×#3Ñ#3Ó#5Ó6¸dÔCÐCÜ˜4Ó Ð r   zdict[str, Optional[str]]Ú_STALE_BUNDLE_OUTCOMESc               ó   € V ^8„  d   QhRR/# ©r   r	   úOptional[str]r   )r   s   "r   r   r   ‰   s   € ÷ 'ñ '˜]ñ 'r   c                 ó¨   €  ^ RI p T P                  4       p\        T4      P	                  4       '       d   T# \        T4      #   \         d     R# i ; i)uÅ  certifi's CA bundle path, re-derived when a rotation invalidated it.

``certifi.where()`` resolves its path once, against the ``certifi`` package on the
``sys.path`` of the moment it was first called, and caches it in ``certifi.core``:
a process that outlives an install-environment rotation â€” the package manager
creates a new environment directory and deletes the old one â€” keeps pointing into
the deleted directory for the rest of its life, and every TLS client it builds
afterwards fails. Re-importing the package against the live ``sys.path`` repairs it
process-wide; when even that finds nothing, the platform store is the answer and
never an exception.

The repair, and its warning, happen ONCE per dead path: a gateway builds clients
per turn, per cron run and per model-metadata fetch, so an un-cached reload here
would re-execute third-party module code and re-log on every client it builds.

Returns a bundle path that exists on disk, else ``None``.
N)ÚcertifiÚImportErrorÚwherer   rB   Ú_recover_bundle_once)rK   Ústales     r   Úcertifi_bundle_pathrP   ‰   sN   € ð$Ûð �M‰M‹O€EÜˆEƒ{×Ñ×ÒØˆÜ Ó&Ð&øô ô Úðús   ‚A ÁAÁAc               ó    € V ^8„  d   QhRRRR/# )r   rO   r!   r	   rI   r   )r   s   "r   r   r   ¥   s   € ÷ ñ  ð ¨ñ r   c                ót  € \         ;_uu_ 4        V \        9   d=   \        V ,          pVe    \        V4      P                  4       '       d   VuuRRR4       # \	        4       pV\        V &   RRR4       Xe   \
        P                  RV V4       V# \
        P                  RV 4       R#   + '       g   i     LE; i)zíRe-derive ``stale`` at most once, and report it at most once.

A cached outcome is reused while it still holds (a re-derived path that exists, or
an unrecoverable one); a later rotation dead-path is a new key and is repaired on
its own.
NuÈ   TLS trust: certifi's CA bundle %s no longer exists â€” the install environment it belongs to was replaced under this process; re-resolved to %s. TLS clients built before this point used the dead path.z•TLS trust: certifi's CA bundle %s no longer exists and certifi could not be re-resolved; using the platform trust store for the rest of this process.)Ú_STALE_BUNDLE_LOCKrF   r   rB   Ú_reload_certifi_bundler   r   )rO   ÚcachedÚ	recovereds   &  r   rN   rN   ¥   s¦   € ÷ 
Ö	ØÔ*Ô*Ü+¨EÕ2ˆFØŠ~¤ f£×!5Ñ!5×!7Ò!7Ø÷	 
Ò	ô
 +Ó,ˆ	Ø(1Ô˜uÑ%÷ 
ð ÒÜ�‰ðMð Øô	
ð ÐÜ
‡N�Nð	Tàôñ
 ÷+ 
×	ús   �=B'ÁB'Â'B7	c               ó   € V ^8„  d   QhRR/# rH   r   )r   s   "r   r   r   Ä   s   € ÷  ;ñ  ; ñ  ;r   c                 ó`  € ^ RI p ^ RIpRVP                  9  d   R# V P                  4        VP                   Uu. uF$  q"R8X  g   VP	                  R4      '       g   K"  VNK&  	  up Uu/ uF  pW1P                  P                  V4      bK   	  pp V P                  R4      P                  4       pT'       d"   \        T4      P                  4       '       d   T# R# u upi u upi   \         d?   pTP                  P                  T4       \        P                  RTRR7        Rp?R# Rp?ii ; i)u$  Re-import certifi from the live ``sys.path`` so its ``where()`` follows it.

``importlib.reload`` on its own does NOT re-derive the path with the real package:
``certifi.where`` is ``certifi.core.where`` re-exported by ``__init__``, and ``core``
caches the resolved path in a module global, so re-executing ``__init__`` re-binds
``where`` from the still-loaded ``core`` â€” the replaced directory, cached a second
time. Only dropping the package and its submodules from ``sys.modules`` makes both
files re-execute against the live ``sys.path``. They are put back when the import
fails, so the process is never left without the ``certifi`` it already had.

``None`` when certifi was never imported or its package is gone from every
``sys.path`` entry â€” the caller then falls back to the platform store.
NrK   zcertifi.z$certifi could not be re-resolved: %sT©Úexc_info)Ú	importlibÚsysÚmodulesÚinvalidate_cachesÚ
startswithÚpopÚimport_modulerM   r   Úupdater   r   r   rB   )r[   r\   ÚnÚnameÚdroppedÚpathr   s          r   rT   rT   Ä   s  € ó Ûà˜Ÿ™Ô#Ùð ×ÑÔ!ð !$§¢ÓZ¡˜1°I¬~ÀÇÁÈj×AY—Q�Q¡ÒZóáZˆDð 	�k‰k�o‰o˜dÓ#Ò#ÙZð ð ðØ×&Ñ& yÓ1×7Ñ7Ó9ˆ÷
 œD ›J×.Ñ.×0Ò0ˆ4Ð:°dÐ:ùò [ùòøô ô Ø�‰×Ñ˜7Ô#Ü�‰Ð;¸SÈ4ˆÔPÝûðús)   ºCÁCÁ)$CÂC$ Ã$D-Ã/3D(Ä(D-c               ó   € V ^8„  d   QhRR/# )r   r	   z
bool | strr   )r   s   "r   r   r   ç   s   € ÷ ,ñ ,˜ñ ,r   c                 óú  € ^ RI Hp  \        P                  P	                  R4      '       g&   \        P                  P	                  R4      '       d   R# \        V 4      P                  4       '       d   R# \        4       pV'       d   V# \        P                  ! 4       pVP                  VP                  3 F0  pV'       g   K  \        V4      P                  4       '       g   K.  Vu # 	  \        4       ;'       g    R# )uÆ  ``verify`` for a ``requests`` call in this process.

``requests`` resolves ``verify=True`` through ``DEFAULT_CA_BUNDLE_PATH``, a string
frozen when ``requests`` was imported â€” the one certifi consumer a module reload
cannot reach, so a rotated environment leaves every ``requests`` call raising
``OSError: Could not find a suitable TLS CA certificate bundle``. The live bundle
(certifi's, re-derived; else OpenSSL's own default) keeps those calls working;
``True`` only when nothing resolves, which is requests' own default. A healthy
install keeps ``True`` too: requests reads ``REQUESTS_CA_BUNDLE``/``CURL_CA_BUNDLE``
only for ``verify=True``, and an explicit path would silently bypass a user's
proxy CA.
)ÚDEFAULT_CA_BUNDLE_PATHÚREQUESTS_CA_BUNDLEÚCURL_CA_BUNDLET)Úrequests.utilsri   r@   rA   r6   r   rB   rP   r(   Úget_default_verify_pathsr4   ÚcapathÚexistsÚ_platform_store_bundle)ri   ÚbundleÚdefaultsÚ	candidates       r   Úrequests_verifyrt   ç   s®   € õ 6ä	‡z�z‡~�~Ð*×+Ò+¬r¯z©z¯~©~Ð>N×/OÒ/OÙÜÐ"Ó#×+Ñ+×-Ò-ÙÜ Ó"€FßØˆÜ×+Ò+Ó-€HØ—o‘o x§¡Ó7ˆ	ß‰9œ˜i›×/Ñ/×1Ô1ØÒñ 8ô
 "Ó#×+Ð+ tÐ+r   rI   Ú_PLATFORM_STORE_BUNDLEc               ó   € V ^8„  d   QhRR/# rH   r   )r   s   "r   r   r   	  s   € ÷ "ñ " ñ "r   c                 ó@  € \         '       d*   \        \         4      P                  4       '       d   \         # \        4       ! \        P
                  4      p V P                  4        V P                  RR7      pV'       g   R# ^ RIH	p ^ RI
Hp V! 4       R,          R,          p VP                  P                  RRR7       V! VR	P                  R
 V 4       4      4       \%        T4      s \         #   \         d$   p\         P#                  RTRR7        Rp?R# Rp?ii ; i)zLThe OS store's CA certificates written once to a PEM file under HERMES_HOME.T)Úbinary_formN)Úget_hermes_home)Úatomic_write_textÚcachezplatform-ca-bundle.pem)ÚparentsÚexist_okr?   c              3  óN   "  € T F  p\         P                  ! V4      x € K  	  R # 5i)N)r(   ÚDER_cert_to_PEM_cert)Ú.0Úders   & r   Ú	<genexpr>Ú)_platform_store_bundle.<locals>.<genexpr>  s    é € Ð'WÑQVÈ#¬×(@Ò(@À×(EÐ(EÓQVùs   ‚#%z"platform CA bundle not written: %srY   )ru   r   rB   r.   r(   r7   r8   Úget_ca_certsÚhermes_constantsry   Úutilsrz   ÚparentÚmkdirÚjoinÚOSErrorr   r   r!   )r:   Úcertsry   rz   rf   r   s         r   rp   rp   	  så   € ÷ Ó¤$Ô'=Ó">×"FÑ"F×"HÒ"HÜ%Ð%Ü
#Ô
%¤c×&=Ñ&=Ó
>€CØ×ÑÔØ×Ñ¨ÐÓ.€EßÙÝ0Ý'áÓ˜wÕ&Ð)AÕA€DðØ�‰×Ñ $°ÐÔ6Ù˜$ §¡Ñ'WÑQVÓ'WÓ WÔXô ! ›YÐÜ!Ð!øô	 ô Ü�‰Ð9¸3ÈˆÔNÝûðús   Â"<C/ Ã/DÃ:DÄDc               ó   € V ^8„  d   QhRR/# )r   r	   úbool | ssl.SSLContextr   )r   s   "r   r   r   !  s   € ÷ Dñ DÐ.ñ Dr   c                 ó<   € \        4       '       d   R# \        R4      # )ul  ``verify`` for the platform default path.

httpx resolves ``verify=True`` through ``certifi.where()`` at client construction,
which raises ``FileNotFoundError`` on a bundle path a rotation deleted. Hand the
platform context over instead when no bundle can be found; a re-derivable bundle
keeps ``True`` â€” the module reload already repaired certifi process-wide.
TN)rP   r;   r   r   r   Ú_default_verifyr�   !  s   € ô '×(Ò(ˆ4ÐC¬o¸dÓ.CÐCr   Ú	ca_bundler   Úbase_urlr?   c               ó(   € V ^8„  d   QhRRRRRRRR/# )	r   r�   rI   r   r   r‘   r!   r	   r�   r   )r   s   "r   r   r   ,  s2   € ÷ +ñ +àð+ð ð+ð ð	+ð
 ñ+r   c                óL  € \        4        \        V4      '       d#   \        P                  RT;'       g    R4       R# T ;'       g    RP	                  4       pV'       dh   \        V4      P                  4       pVP                  4       '       d#   \        \        VP                  4       4      4      # \        P                  RV4       \        P                  P                  R4      '       g&   \        P                  P                  R4      '       d   \        R4      # \        4       # )	u  Resolve ``verify`` for an HTTP client.

1. ``ssl_verify: false`` â€” verification off (local development only)
2. explicit ``ca_bundle`` (the provider's ``ssl_ca_cert``) â€” that
   bundle INSTEAD of the platform store, for an endpoint whose chain
   the machine has no reason to trust
3. ``True`` â€” the platform store, via the process-wide install, or the
   platform context when the certifi bundle this process resolved at
   import no longer exists (a replaced install environment)

``base_url`` only labels the insecure-mode warning.
u§   TLS certificate verification DISABLED (ssl_verify: false) for %s â€” this is intended for local development only and is unsafe on any network you do not fully control.za custom provider endpointFr?   uH   ssl_ca_cert path does not exist: %s â€” using the OS trust store insteadr>   ÚSSL_CERT_DIRN)r   r$   r   r   r"   r   Ú
expanduserrB   r;   r!   rC   r@   rA   r6   r�   )r�   r   r‘   Úeffective_carf   s   $$$  r   Úresolve_httpx_verifyr—   ,  sÑ   € ô$ Ôä˜
×#Ò#Ü�‰ð0ð ×4Ð4Ð4ô		
ñ à—O�O ×*Ñ*Ó,€LßÜ�LÓ!×,Ñ,Ó.ˆØ�<‰<�>Š>Ü"¤3 t§|¡|£~Ó#6Ó7Ð7Ü�‰ØVØô	
ô 
‡z�z‡~�~�o×&Ò&¬"¯*©*¯.©.¸×*HÒ*HÜ˜tÓ$Ð$ÜÓÐr   )F)$Ú__conditional_annotations__Ú__doc__Ú
__future__r   Úloggingr@   r(   Ú	threadingÚpathlibr   Útypingr   r   Ú	getLoggerÚ__name__r   r   Ú__annotations__r   r$   r%   ÚLockr5   r.   r;   rE   rF   rS   rP   rN   rT   rt   ru   rp   r�   r—   )r˜   s   @r   Ú<module>r£      sÞ   øðôõ* #ã Û 	Û 
Û Ý ß  à	×	Ò	˜8Ó	$€à€
ˆKÓ õõ<ð ?A€Ð;Ó @Ø—N’NÓ$Ð õ ÷$õ.!ð 46Ð Ð0Ó 5Ø—^’^Ó%Ð õ'õ8õ> ;õF,ð> )-Ð ˜Ó ,õ"õ0Dð+à#ð+ð ð+ð ÷	+ñ +r   