o
    &zh/                     @   s   d dl Z d dlmZ d dlmZmZmZmZmZ d dl	m
Z
mZ ddlmZ ddlmZmZmZmZ ddlmZmZ ed	d
G dd dZeeje
jf ZG dd dZdS )    N)	dataclass)	FrozenSetIterableIteratorOptionalUnion)cmsx509   )
AAControls)	AuthorityAuthorityWithCertCertTrustAnchorTrustAnchor)get_ac_extension_valueget_issuer_dnT)frozenc                   @   s*   e Zd ZU eed< 	 eed< 	 eed< dS )QualifiedPolicyissuer_domain_policy_iduser_domain_policy_id
qualifiersN)__name__
__module____qualname__str__annotations__	frozenset r   r   U/var/www/html/kangema/venv/lib/python3.10/site-packages/pyhanko_certvalidator/path.pyr      s   
 r   c                   @   s  e Zd ZU dZdZeee  ed< dZ	de
deej dee fddZed	e
fd
dZedd Zed	ee fddZd	ee fddZd	eej fddZed	ejfddZd	ee fddZdefddZdejdefddZdejfddZdefd d!Zd8d"d#Zd$d% Zd	eee  fd&d'Z d(e!j"d	e#fd)d*Z$ed+d, Z%d-d. Z&d/d0 Z'd1e#d	e(ej fd2d3Z)d4d5 Z*d6d7 Z+dS )9ValidationPathza
    Represents a path going towards an end-entity certificate or attribute
    certificate.
    N_qualified_policiestrust_anchorintermleafc                 C   s*   |r|st dt|| _|| _|| _d S )Nz-Leafless paths cannot have intermediate certs)
ValueErrorlist_interm_root_leaf)selfr!   r"   r#   r   r   r   __init__1   s
   

zValidationPath.__init__returnc                 C      | j S N)r'   r)   r   r   r   r!   =   s   zValidationPath.trust_anchorc                 C   s@   | j j}t|tr|jS | jr| jd S t| jtjr| jS dS )a  
        Returns the current beginning of the path - for a path to be complete,
        this certificate should be a trust root

        .. warning::
            This is a compatibility property, and will return the first non-root
            certificate if the trust root is not provisioned as a certificate.
            If you want the trust root itself (even when it doesn't have a
            certificate), use :attr:`trust_anchor`.

        :return:
            The first asn1crypto.x509.Certificate object in the path
        r   N)	r'   	authority
isinstancer   certificater&   r(   r	   Certificate)r)   rootr   r   r   firstA   s   

zValidationPath.firstc                 C   s.   | j dur| j S | jst| jtr| jjS dS )a<  
        Returns the current leaf certificate (AC or public-key).
        The trust root's certificate will be returned if there is one and
        there are no other certificates in the path.

        If the trust root is certificate-less and there are no certificates,
        the result will be ``None``.
        N)r(   r&   r0   r'   r   r1   r.   r   r   r   r#   X   s
   

zValidationPath.leafc                 C   s.   | j }t|tjr|jjS t|tjrdS d S )Nz<Attribute certificate>)r#   r0   r	   r2   subjecthuman_friendlyr   AttributeCertificateV2r)   r#   r   r   r   describe_leafi   s   zValidationPath.describe_leafc                 C   s   | j }t|tjr|S dS )z
        Returns the current leaf certificate if it is an X.509 public-key
        certificate, and ``None`` otherwise.
        :return:
        N)r#   r0   r	   r2   r8   r   r   r   get_ee_cert_safer   s   zValidationPath.get_ee_cert_safec                 C   s   |   }|r|S t)z
        Returns the last certificate in the path if it is an X.509 public-key
        certificate, and throws an error otherwise.

        :return:
            The last asn1crypto.x509.Certificate object in the path
        )r:   LookupErrorr)   certr   r   r   last   s   	zValidationPath.lastc                 c   s&    | j jV  | jD ]}t|V  q	dS )zU
        Iterate over all authorities in the path, including the trust root.
        N)r'   r/   r&   r   r<   r   r   r   iter_authorities   s
   

zValidationPath.iter_authoritiesr=   c                 C   sx   t |}t|tjr|j}nt|d}|r|d jnd}|  D ]}|j|kr7|j	}|r3|r3||kr3q |  S q t
d)aK  
        Return the issuer of the cert specified, as defined by this path

        :param cert:
            A certificate to get the issuer of

        :raises:
            LookupError - when the issuer of the certificate could not be found

        :return:
            An asn1crypto.x509.Certificate object of the issuer
        authority_key_identifierkey_identifierN6Unable to find the issuer of the certificate specified)r   r0   r	   r2   r@   r   nativer?   namekey_idr;   )r)   r=   issuer_nameakiaki_extr/   keyidr   r   r   find_issuing_authority   s   

z%ValidationPath.find_issuing_authoritynew_leafc                 C   s   t | jtr| jjj|jkrt| jg |dS | j}d}t|D ]\}}|j|jkr-|} nq|du r6tdt| j|d|d  |dS )a  
        Remove all certificates in the path after the cert specified and return
        them in a new path.

        Internal API.

        :param cert:
            An asn1crypto.x509.Certificate object to find

        :param new_leaf:
            A new leaf certificate to append.

        :raises:
            LookupError - when the certificate could not be found

        :return:
            The current ValidationPath object, for chaining
        r"   r#   Nz(Unable to find the certificate specifiedr
   )	r0   r'   r   r1   issuer_serialr   r&   	enumerater;   )r)   r=   rK   certs
cert_indexindexentryr   r   r   truncate_to_and_append   s   z%ValidationPath.truncate_to_and_appendc                 C   s   d}| j j|r|jdkrt| jg ddS t| jg |dS | j}t|D ]\}}|j|j	krD|j
r@|jr@|j
|jkr?|} nq%|} nq%|du rMtdt| j|d|d  |dS )a  
        Remove all certificates in the path after the issuer of the cert
        specified, as defined by this path, and append a new one.

        Internal API.

        :param cert:
            A new leaf certificate to append.

        :raises:
            LookupError - when the issuer of the certificate could not be found

        :return:
            The current ValidationPath object, for chaining
        NmayberL   rB   r
   )r#   )r!   r/   is_potential_issuer_ofself_signedr   r'   r&   rN   r5   issuerrA   r@   r;   )r)   r=   issuer_indexrO   rQ   rR   r   r   r   truncate_to_issuer_and_append   s*   
	z,ValidationPath.truncate_to_issuer_and_appendc                 C   s0   | j d d  }| jr|| j t| j||dS )Nr!   r"   r#   )r&   r(   appendr   r'   )r)   r=   	new_certsr   r   r   copy_and_append  s   zValidationPath.copy_and_appendc                 C   s<   t | jdkr	t| jdd | jd }}t| j||dS )z
        Drop the leaf cert from this path and return a new path with the
        last intermediate certificate set as the leaf.
        r   NrZ   )lenr&   
IndexErrorr   r'   )r)   
new_intermrK   r   r   r   copy_and_drop_leaf  s   z!ValidationPath.copy_and_drop_leafc                 C   s
   || _ d S r-   r    )r)   policiesr   r   r   _set_qualified_policies!  s   
z&ValidationPath._set_qualified_policiesc                 C   r,   r-   rc   r.   r   r   r   qualified_policies$  s   z!ValidationPath.qualified_policiesattr_idc                    s>   dd | D }t dd |D }|sdS t fdd|D S )Nc                 S   s   g | ]}t |qS r   )r   read_extension_value).0r=   r   r   r   
<listcomp>(  s    
z3ValidationPath.aa_attr_in_scope.<locals>.<listcomp>c                 s   s    | ]}|d uV  qd S r-   r   )ri   xr   r   r   	<genexpr>+  s    z2ValidationPath.aa_attr_in_scope.<locals>.<genexpr>Tc                 3   s"    | ]}|d ur|  V  qd S r-   )accept)ri   ctrlrg   r   r   rl   5  s    )anyall)r)   rg   aa_controls_extensionsaa_controls_usedr   ro   r   aa_attr_in_scope'  s   zValidationPath.aa_attr_in_scopec                 C   s   t | j| jr
d S d S )Nr
   r   )r_   r&   r(   r.   r   r   r   pkix_len=  s   zValidationPath.pkix_lenc                 C   s
   d| j  S )Nr
   )ru   r.   r   r   r   __len__A  s   
zValidationPath.__len__c                 C   sX   |dkrt | jd }||kr| jd ur| jS | j|d  S t| jtr(| jjS td)Nr   r
   zRoot has no certificate)r_   r&   r(   r0   r'   r   r1   r;   )r)   keyleaf_ixr   r   r   __getitem__E  s   zValidationPath.__getitem__include_rootc                 C   sN   | j j}|rt|tr|jfnd}| j}t|tjr|fnd}t	|| j
|S )z
        Iterate over the certificates in the path.

        :param include_root:
            Include the root (if it is supplied as a certificate)
        :return:
            An iterator.
        r   )r'   r/   r0   r   r1   r(   r	   r2   	itertoolschainr&   )r)   rz   r3   	from_rootr#   	from_leafr   r   r   
iter_certsT  s   	
zValidationPath.iter_certsc                 C   s   | j ddS )NT)rz   )r   r.   r   r   r   __iter__g  s   zValidationPath.__iter__c                 C   s2   t |tsdS | j|jko| j|jko| j|jkS )NF)r0   r   r!   r&   r(   )r)   otherr   r   r   __eq__l  s   


zValidationPath.__eq__)r+   r   ),r   r   r   __doc__r    r   r   r   r   _path_aa_controlsr   r   r	   r2   Leafr*   propertyr!   r4   r#   r   r9   r:   r>   r   r?   rJ   rS   rY   r]   rb   re   rf   r   AttCertAttributeTypeboolrt   ru   rv   ry   r   r   r   r   r   r   r   r   r   '   sJ   
 

	 &0

r   )r{   dataclassesr   typingr   r   r   r   r   
asn1cryptor   r	   
asn1_typesr   r/   r   r   r   r   utilr   r   r   r2   r7   r   r   r   r   r   r   <module>   s   