
    WwgDV                        d dl Z d dlZd dlmZ d dlmZmZmZmZm	Z	m
Z
 d dlmZ d dlmZ ddlmZmZ ddlmZ dd	lmZ dd
lmZ ddlmZmZ  G d de j6                        Z G d dee j6                        Z G d de      Zee
ej>                  ef      Z  G d d      Z! G d de!      Z" G d de      Z# G d d      Z$ G d d      Z% G d d      Z& G d dee         Z' G d  d!e      Z(y)"    N)defaultdict)AsyncGeneratorIterableIteratorListOptionalUnion)x509)
trust_list   )CertTrustAnchorTrustAnchor)PathBuildingError)CertificateFetcher)ValidationPath)CancelableAsyncIteratorConsListc                   N    e Zd ZdZdefdZdefdZdej                  fdZ	d Z
y)	CertificateCollectionzS
    Abstract base class for read-only access to a collection of certificates.
    key_identifierc                 4    | j                  |      }|sy|d   S )z
        Retrieves a cert via its key identifier

        :param key_identifier:
            A byte string of the key identifier

        :return:
            None or an asn1crypto.x509.Certificate object
        Nr   )retrieve_many_by_key_identifier)selfr   
candidatess      U/var/www/horilla/myenv/lib/python3.12/site-packages/pyhanko_certvalidator/registry.pyretrieve_by_key_identifierz0CertificateCollection.retrieve_by_key_identifier   s$     99.I
a=     c                     t         )z
        Retrieves possibly multiple certs via the corresponding key identifiers

        :param key_identifier:
            A byte string of the key identifier

        :return:
            A list of asn1crypto.x509.Certificate objects
        NotImplementedErrorr   r   s     r   r   z5CertificateCollection.retrieve_many_by_key_identifier'   
     "!r   namec                     t         )z
        Retrieves a list certs via their subject name

        :param name:
            An asn1crypto.x509.Name object

        :return:
            A list of asn1crypto.x509.Certificate objects
        r   r   r#   s     r   retrieve_by_namez&CertificateCollection.retrieve_by_name3   r"   r   c                     t         )a]  
        Retrieve a certificate by its ``issuer_serial`` value.

        :param issuer_serial:
            The ``issuer_serial`` value of the certificate.
        :return:
            The certificate corresponding to the ``issuer_serial`` key
            passed in.
        :return:
            None or an asn1crypto.x509.Certificate object
        r   r   issuer_serials     r   retrieve_by_issuer_serialz/CertificateCollection.retrieve_by_issuer_serial?   
     "!r   N)__name__
__module____qualname____doc__bytesr   r   r
   Namer&   r*    r   r   r   r      s4    ! ! 
"e 
"
"TYY 
""r   r   c                   \    e Zd Zdej                  defdZdeej                     fdZd Z	y)CertificateStorecertreturnc                     t         )
        Register a single certificate.

        :param cert:
            Certificate to add.
        :return:
            ``True`` if the certificate was added, ``False`` if it already
            existed in this store.
        r   r   r5   s     r   registerzCertificateStore.registerO   r"   r   certsc                 @    d}|D ]  }|| j                  |      z  } |S )a  
        Register multiple certificates.

        :param certs:
            Certificates to register.
        :return:
            ``True`` if at least one certificate was added, ``False``
            if all certificates already existed in this store.
        Fr:   )r   r;   addedr5   s       r   register_multiplez"CertificateStore.register_multiple[   s0      	)DT]]4((E	)r   c                     t         Nr   r   s    r   __iter__zCertificateStore.__iter__k   s    !!r   N)
r,   r-   r.   r
   Certificateboolr:   r   r?   rC   r2   r   r   r4   r4   N   s7    
"T-- 
"$ 
"x0@0@'A  "r   r4   c                       e Zd ZdZed        Zd Zdej                  de	fdZ
d Zd Zd	efd
Zdej                  fdZd Zy)SimpleCertificateStorez-
    Simple trustless certificate store.
    c                 D     |        }|D ]  }|j                  |        |S rA   r=   )clsr;   resultr5   s       r   
from_certsz!SimpleCertificateStore.from_certst   s)     	"DOOD!	"r   c                 b    i | _         t        t              | _        t        t              | _        y rA   )r;   r   list_subject_map_key_identifier_maprB   s    r   __init__zSimpleCertificateStore.__init__{   s#    
'-#.t#4 r   r5   r6   c                    |j                   | j                  v ry|| j                  |j                   <   | j                  |j                  j                     j                  |       |j                  r)| j                  |j                     j                  |       y| j                  |j                  j                     j                  |       y)r8   FT)
r)   r;   rN   subjecthashableappendr   rO   
public_keysha1r9   s     r   r:   zSimpleCertificateStore.register   s     +)-

4%%&$,,//077=$$T%8%89@@F  $$T__%9%9:AA$Gr   c                      | j                   |   S rA   )r;   )r   items     r   __getitem__z"SimpleCertificateStore.__getitem__   s    zz$r   c                 H    t        | j                  j                               S rA   )iterr;   valuesrB   s    r   rC   zSimpleCertificateStore.__iter__   s    DJJ%%'((r   r   c                      | j                   |   S rA   )rO   r!   s     r   r   z6SimpleCertificateStore.retrieve_many_by_key_identifier   s    ''77r   r#   c                 4    | j                   |j                     S rA   )rN   rS   r%   s     r   r&   z'SimpleCertificateStore.retrieve_by_name   s      //r   c                 ,    	 | |   S # t         $ r Y y w xY wrA   )KeyErrorr(   s     r   r*   z0SimpleCertificateStore.retrieve_by_issuer_serial   s$    	&& 		s    	N)r,   r-   r.   r/   classmethodrK   rP   r
   rD   rE   r:   rY   rC   r0   r   r1   r&   r*   r2   r   r   rG   rG   o   sd      5
T-- $ ( )8e 80TYY 0r   rG   c                   ^    e Zd ZdZdej
                  defdZdej
                  dee	   fdZ
y)TrustManagerz%
    Abstract trust manager API.
    r5   r6   c                     t         z
        Checks if a certificate is in the list of trust roots in this registry

        :param cert:
            An asn1crypto.x509.Certificate object

        :return:
            A boolean - if the certificate is in the CA list
        r   r9   s     r   is_rootzTrustManager.is_root   r"   r   c                     t         )z
        Find potential issuers that might have (directly) issued
        a particular certificate.

        :param cert:
            Issued certificate.
        :return:
            An iterator with potentially relevant trust anchors.
        r   r9   s     r   find_potential_issuersz#TrustManager.find_potential_issuers   r+   r   N)r,   r-   r.   r/   r
   rD   rE   rf   r   r   rh   r2   r   r   rc   rc      s@    
"D,, 
" 
""$$"	+	"r   rc   c                       e Zd ZdZd Ze	 	 ddee   dee   dd fd       Zde	e
ej                  f   fd	Zd
ej                  fdZdeej                     fdZd
ej                  dee
   fdZy)SimpleTrustManagerzk
    Trust manager backed by a list of trust roots, possibly in addition to the
    system trust list.
    c                 J    t               | _        t        t              | _        y rA   )set_rootsr   rM   _root_subject_maprB   s    r   rP   zSimpleTrustManager.__init__   s    e!,T!2r   Ntrust_rootsextra_trust_rootsr6   c                     |%t        j                         D cg c]  }|d   	 }}nt        |      }||j                  |       t	               }|D ]  }|j                  |        |S c c}w )a  
        :param trust_roots:
            If the operating system's trust list should not be used, instead
            pass a list of asn1crypto.x509.Certificate objects. These
            certificates will be used as the trust roots for the path being
            built.

        :param extra_trust_roots:
            If the operating system's trust list should be used, but augmented
            with one or more extra certificates. This should be a list of
            asn1crypto.x509.Certificate objects.
        :return:
        r   )r   get_listrM   extendrj   _register_root)rI   ro   rp   emanager
trust_roots         r   buildzSimpleTrustManager.build   sy    & )3)<)<)>?A1Q4?K?{+K(01$&% 	/J"":.	/ @s   A*rw   c                    t        |t              r|}nt        |      }|| j                  vrZ|j                  }| j                  j                  |       | j                  |j                  j                     j                  |       y y rA   )

isinstancer   r   rm   	authorityaddrn   r#   rS   rT   )r   rw   anchorr{   s       r   rt   z!SimpleTrustManager._register_root   sj    j+.F$Z0F$((IKKOOF#""9>>#:#:;BB6J %r   r5   c                 0    t        |      | j                  v S re   )r   rm   r9   s     r   rf   zSimpleTrustManager.is_root   s     t$33r   c                 (    d | j                   D        S )Nc              3   T   K   | ]   }t        |t              r|j                   " y wrA   )rz   r   certificate).0roots     r   	<genexpr>z0SimpleTrustManager.iter_certs.<locals>.<genexpr>  s(      
$0 
s   &()rm   rB   s    r   
iter_certszSimpleTrustManager.iter_certs  s    

 	
r   c              #      K   |j                   j                  }| j                  |   D ]"  }|j                  j	                  |      s| $ y wrA   )issuerrS   rn   r{   is_potential_issuer_of)r   r5   issuer_hashabler   s       r   rh   z)SimpleTrustManager.find_potential_issuers  sH      ++..**?; 	D~~44T:
	s   AAA)NN)r,   r-   r.   r/   rP   ra   r   TrustRootListrx   r	   r   r
   rD   rt   rf   r   r   rh   r2   r   r   rj   rj      s    
3  0459m, $M2 
	 >K{D<L<L/L)M K4D,, 4
HT%5%56 
$$	+	r   rj   c            	       *    e Zd ZdZdddee   f fdZe	 ddddee	j                     dee   fd       Z	 dde	j                  d	ee	j                     f fd
Zde	j                  dedeeee	j                  f      fdZde	j                  fdZ xZS )CertificateRegistryz
    Contains certificate lists used to build validation paths, and
    is also capable of fetching missing certificates if a certificate
    fetcher is supplied.
    Ncert_fetcherr   c                0    t         |           || _        y rA   )superrP   fetcher)r   r   	__class__s     r   rP   zCertificateRegistry.__init__#  s    #r   r;   c                V     | |      }|D ]  }|j                  |        ||_        |S )a  
        Convenience method to set up a certificate registry and import
        certs into it.

        :param certs:
            Initial list of certificates to import.
        :param cert_fetcher:
            Certificate fetcher to handle retrieval of missing certificates
            (in situations where that is possible).
        :return:
            A populated certificate registry.
        r   )r:   r   )rI   r;   r   rJ   r5   s        r   rx   zCertificateRegistry.build'  s7    ( '*|&D 	"DOOD!	" &r   r#   first_certificatec                     g }d}t         |   |      D ]1  }|r|j                  |j                  k(  r|}!|j                  |       3 |r|j	                  d|       |S )af  
        Retrieves a list certs via their subject name

        :param name:
            An asn1crypto.x509.Name object

        :param first_certificate:
            An asn1crypto.x509.Certificate object that if found, should be
            placed first in the result list

        :return:
            A list of asn1crypto.x509.Certificate objects
        Nr   )r   r&   sha256rT   insert)r   r#   r   outputfirstr5   r   s         r   r&   z$CertificateRegistry.retrieve_by_nameB  sf    & G,T2 	$D %6%=%=%Ld#		$
 MM!U#r   r5   trust_managerr6   c              #   r  K   |j                   j                  }|j                  |      E d {    | j                  |   D ]p  }|j	                  |      r|j
                  r&|j                  r|j
                  |j                  k7  r'G|j                  r|j                  |j                  k7  rm| r y 7 wrA   )	r   rS   rh   rN   rf   authority_key_identifierr   authority_issuer_serialr)   )r   r5   r   r   r   s        r   rh   z*CertificateRegistry.find_potential_issuers`  s      ++.. !77===''8 
	F$$V,,,1F1F00F4I4II--//63G3GGL
	 	>s   +B7B5BB7c                   K   | j                   y | j                   j                  |      2 cg c3 d {   }|7 6 nc c}w }}| j                  |       |D ]  }| 	 y wrA   )r   fetch_cert_issuersr?   )r   r5   r   issuerss       r   fetch_missing_potential_issuersz3CertificateRegistry.fetch_missing_potential_issuersx  sr     << (,||'F'Ft'L
 
#F
 
 
 
 	w' 	FL	s&   +A$?=;
=?=?&A$)r2   rA   )r,   r-   r.   r/   r   r   rP   ra   r   r
   rD   rx   r1   r&   rc   r   r	   r   rh   r   __classcell__)r   s   @r   r   r     s     HL $1C(D $  -/ 6:	(() 12	 : 9=ii $D$4$45<$$5A	%T%5%556	70
$:J:J 
r   r   c                   p    e Zd ZdZdedefdZd Zdej                  fdZ
dej                  dee   fd	Zy
)PathBuilderz(
    Class to handle path building.
    r   registryc                      || _         || _        y rA   )r   r   )r   r   r   s      r   rP   zPathBuilder.__init__  s     + r   c                 J    t        j                  | j                  |            S )a  
        Builds a list of ValidationPath objects from a certificate in the
        operating system trust store to the end-entity certificate

        .. note::
            This is a synchronous equivalent of :meth:`async_build_paths`
            that calls the latter in a new event loop. As such, it can't be used
            from within asynchronous code.

        :param end_entity_cert:
            A byte string of a DER or PEM-encoded X.509 certificate, or an
            instance of asn1crypto.x509.Certificate

        :return:
            A list of pyhanko_certvalidator.path.ValidationPath objects that
            represent the possible paths from the end-entity certificate to one
            of the CA certs.
        )asynciorunasync_build_paths)r   end_entity_certs     r   build_pathszPathBuilder.build_paths  s    & {{411/BCCr   r   c                 p   K   g }| j                  |      2 3 d{   }|j                  |       7 6 |S w)a1  
        Builds a list of ValidationPath objects from a certificate in the
        operating system trust store to the end-entity certificate, returning
        all paths in a single list.

        :param end_entity_cert:
            A byte string of a DER or PEM-encoded X.509 certificate, or an
            instance of asn1crypto.x509.Certificate

        :return:
            A list of pyhanko_certvalidator.path.ValidationPath objects that
            represent the possible paths from the end-entity certificate to one
            of the CA certs.
        N)async_build_paths_lazyrT   )r   r   pathsrJ   s       r   r   zPathBuilder.async_build_paths  sC       ') 77H 	! 	!&LL 	!H s   6313636r6   c                     t        | t        j                  |      t        j                  |j                        g       }t	        ||      S )a  
        Builds a list of ValidationPath objects from a certificate in the
        operating system trust store to the end-entity certificate, and emit
        them as an asynchronous generator.

        :param end_entity_cert:
            A byte string of a DER or PEM-encoded X.509 certificate, or an
            instance of asn1crypto.x509.Certificate

        :return:
            An asynchronous iterator that yields
            pyhanko_certvalidator.path.ValidationPath objects that
            represent the possible paths from the end-entity certificate to one
            of the CA certs, and raises PathBuildingError
            if no paths could be built
        )path
certs_seenfailed_paths)_PathWalkerr   singr)   LazyPathIterator)r   r   walkers      r   r   z"PathBuilder.async_build_paths_lazy  sA    ( /}}_%B%BC	
  88r   N)r,   r-   r.   r/   rc   r   rP   r   r
   rD   r   r   r   r   r2   r   r   r   r     sT    !)!5H!D*t7G7G ,9#//9	 	09r   r   c                       e Zd Zdddej                  dee   fdZed        Z	d Z
d Zd	eeej                  f   fd
Zd	eeej                  f   fdZd Zy)_IssuerFetcherpath_builderr   r5   r   c                     || _         || _        || _        | j                  j                  j	                  || j                  j
                        }t        |      | _        d| _        d| _	        d | _
        d| _        y )Nr   F)r5   r   r   r   rh   r   r[   local_iss_iterlocal_issuers_foundfetched_issuers_found_fetched_cas_fetching_done)r   r   r5   r   local_issuerss        r   rP   z_IssuerFetcher.__init__  s{     	($))22II$##11
 #=1#$ %&" 	 $r   c                 4    | j                   | j                  z   S rA   )r   r   rB   s    r   issuers_foundz_IssuerFetcher.issuers_found  s    ''$*D*DDDr   c                     | S rA   r2   rB   s    r   	__aiter__z_IssuerFetcher.__aiter__      r   c                     | S rA   r2   rB   s    r   rC   z_IssuerFetcher.__iter__  r   r   r6   c                     | j                   D ]O  }t        |t        j                        r|j                  }|| j
                  v r8| xj                  dz  c_        |c S  t        )Nr   )r   rz   r
   rD   r)   r   r   StopIterationr   r   cert_ids      r   __next__z_IssuerFetcher.__next__  s_    )) 	F&$"2"23 ..doo-$$)$M	 r   c                   K   	 t        |       S # t        $ r Y nw xY w| j                  L| j                  s@| j                  s4| j
                  j                  j                  | j                        | _        | j                  R| j                  2 3 d {  7  }|j                  }|| j                  v r%| xj                  dz  c_        |c S 6 d| _        t        w)Nr   T)nextr   r   r   r   r   r   r   r5   r)   r   r   StopAsyncIterationr   s      r   	__anext__z_IssuerFetcher.__anext__  s     	: 		 %,,'' !!**JJII  ( $ 1 1  f ..doo-**a/* !2 #'D  s:   C
 C	CA3CCBCACc                    K   | j                   1| j                   j                          d {    d | _         d| _        y y 7 w)NT)r   acloser   rB   s    r   cancelz_IssuerFetcher.cancel  sB     (##**,,, $D"&D ),s   *AAAN)r,   r-   r.   r
   rD   r   r0   rP   propertyr   r   rC   r	   r   r   r   r   r2   r   r   r   r     s    $#$ $ UO	$( E E%T-=-= => !{D4D4D'D!E !8'r   r   c            
       v    e Zd Zdddeej
                     dee   deeej
                        fdZd Z	d Z
d	 Zy
)r   r   r   r   r   r   c                     || _         || _        || _        |j                  }t	        |t
        j                        sJ t        |||      | _        || _	        d | _
        y rA   )r   r   r   headrz   r
   rD   r   _issuer_fetcherr   _next_level)r   r   r   r   r   r5   s         r   rP   z_PathWalker.__init__%  sZ     	($yy$ 0 0111-lD*M(26r   c                    K   | j                   )| j                   j                          d {    d | _         | j                  *| j                  j                          d {    d | _        y y 7 B7 wrA   )r   r   r   rB   s    r   r   z_PathWalker.cancel5  sn     +&&--///#'D '""))+++#D ( 0 ,s!   *A3A/4A3!A1"A31A3c                     | S rA   r2   rB   s    r   r   z_PathWalker.__aiter__=  r   r   c                   K   | j                   t        d }|| j                  	 | j                   j                          d {   }t        |t              r(t        | j                        }t        ||d d |d         S t        | j                  | j                  j                  |      | j                  j                  |j                         | j
                        | _        	 | j                  j                          d {   }||S 7 # t        $ rI}| j                   j                  s%| j
                  j                  | j                         d | _         |d }~ww xY w7 `# t        $ r
 d | _        Y pw xY ww)N)r   r   r   r   r   r   rT   r   rz   r   rM   r   r   r   consr   r)   )r   	next_pathnext_issuerru   r;   s        r   r   z_PathWalker.__anext__@  sW    '$$	'(,(<(<(F(F(H"HK k;7 OE)+uSbz59MM (3))		{3,,[-F-FG))	(D$("&"2"2"<"<">>	3 8 1 #I) //==))00;+/D(G	( ?% (#' (sx   #E:D DD BE:$E$ E"E$ E:	E:D 	EAEEE:"E$ $E74E:6E77E:N)r,   r-   r.   r   r
   rD   r0   r   rP   r   r   r   r2   r   r   r   r   $  s[    7#7 t''(7 UO	7
 8D$4$4567 $ r   r   c                   ^    e Zd ZU dZee   ed<   dedej                  fdZ
d Zd Zdefd	Zy)
r   N_as_rootr   r5   c                     |j                   j                  j                  |      rt        t	        |      g d       | _        || _        d| _        |j                  j                  | _
        y )Nr   )r   r   rf   r   r   r   _walkeremitted_countrR   human_friendly_name)r   r   r5   s      r   rP   zLazyPathIterator.__init__f  sQ    ,,44T:*?4+@"dKDM.4\\00
r   c                 n   K   | j                   #| j                   j                          d {    y y 7 wrA   )r   r   rB   s    r   r   zLazyPathIterator.canceln  s.     <<#,,%%''' $'s   *535c                     | S rA   r2   rB   s    r   r   zLazyPathIterator.__aiter__r  r   r   r6   c                 F  K   | j                   t        | j                  (| xj                  dz  c_        d | _         | j                  S 	 | j                   j	                          d {   }| xj                  dz  c_        |S 7 # t        $ r Y nw xY w| j                  dk(  rx| j                   j
                  d   j                  }t        |t        j                        sJ |j                  j                  }d | _         t        d| j                   d| d      t        w)Nr   r   z7Unable to build a validation path for the certificate "z" - no issuer matching "z" was found)r   r   r   r   r   r   r   rz   r
   rD   r   r   r   r   )r   r   	path_headmissing_issuer_names       r   r   zLazyPathIterator.__anext__u  s    <<$$]]&!#DL== 	"ll4466I!# 7 " 		 "11!499Ii)9)9:::"+"2"2"A"ADL#ZZL !()7 
 ! s=   AD!
B 'B(B D!B 	BD!BBD!)r,   r-   r.   r   r   r   __annotations__r   r
   rD   rP   r   r   r   r2   r   r   r   r   c  s@    )-Hh~&-1{ 1$2B2B 1(! !r   r   c                   T    e Zd ZdZdee   fdZdefdZde	j                  fdZd Zy	)
LayeredCertificateStorezi
    Trustless certificate store that looks up certificates in other stores
    in a specific order.
    storesc                     || _         y rA   )_stores)r   r   s     r   rP   z LayeredCertificateStore.__init__  s	    r   r   c                 2      fd}t         |             S )Nc               3   f   K   j                   D ]  } | j                        E d {     y 7 wrA   )r   r   )storer   r   s    r   _genzELayeredCertificateStore.retrieve_many_by_key_identifier.<locals>._gen  s3      Q @@PPPQP   $1/1rM   )r   r   r   s   `` r   r   z7LayeredCertificateStore.retrieve_many_by_key_identifier  s    	Q DF|r   r#   c                 2      fd}t         |             S )Nc               3   f   K   j                   D ]  } | j                        E d {     y 7 wrA   )r   r&   )r   r#   r   s    r   r   z6LayeredCertificateStore.retrieve_by_name.<locals>._gen  s1      8 11$77787r   r   )r   r#   r   s   `` r   r&   z(LayeredCertificateStore.retrieve_by_name  s    	8 DF|r   c                 T    | j                   D ]  }|j                  |      }||c S  y rA   )r   r*   )r   r)   r   rJ   s       r   r*   z1LayeredCertificateStore.retrieve_by_issuer_serial  s5    \\ 	E44]CF!	 r   N)r,   r-   r.   r/   r   r   rP   r0   r   r
   r1   r&   r*   r2   r   r   r   r     s:    
t$9: e TYY r   r   ))abcr   collectionsr   typingr   r   r   r   r   r	   
asn1cryptor
   oscryptor   r{   r   r   errorsr   fetchersr   r   r   utilr   r   ABCr   r4   rG   rD   r   rc   rj   r   r   r   r   r   r   r2   r   r   <module>r     s      # L L   3 % (   39"CGG 9"x",cgg "B5- 5p t//<=>" "@O Odf0 fRP9 P9fI' I'X< <~+!.~> +!\3 r   