U
    �Acj2  ã                   @  s  d Z ddlmZ ddlZddlZddlmZmZmZm	Z	 ddl
Z
ddlmZmZmZmZmZmZmZ zddlZW n ek
rˆ   dZY nX e
jdd�G d	d
„ d
ƒƒZdddddœdd„Zddddœdd„Zddddœdd„Zdddœdd„Ze
jdd�G dd„ dƒƒZe
jdd�G d d!„ d!ƒƒZe
jdd�G d"d#„ d#ƒƒZe
jdd�G d$d%„ d%ƒƒZeeeeef Ze	G d&d'„ d'eƒƒZ e
jd(dd)�G d*d+„ d+ƒƒZ!e
jdd�G d,d-„ d-ƒƒZ"e
jd(dd)�G d.d/„ d/ƒƒZ#e
jd(dd)�G d0d1„ d1ƒƒZ$d2d2dd3œd4d5„Z%d2d6d7œd8d9„Z&e' (d:d;¡Z)dS )<z
Common verification code.
é    )ÚannotationsN)ÚProtocolÚSequenceÚUnionÚruntime_checkableé   )ÚCertificateErrorÚDNSMismatchÚIPAddressMismatchÚMismatchÚSRVMismatchÚURIMismatchÚVerificationErrorT)Úslotsc                   @  s2   e Zd ZU dZe ¡ Zded< e ¡ Zded< dS )ÚServiceMatchz<
    A match of a service id and a certificate pattern.
    Ú	ServiceIDÚ
service_idÚCertificatePatternÚcert_patternN)	Ú__name__Ú
__module__Ú__qualname__Ú__doc__ÚattrÚibr   Ú__annotations__r   © r   r   ú;/tmp/pip-unpacked-wheel-uq4fiwuu/service_identity/hazmat.pyr      s   
r   zSequence[CertificatePattern]zSequence[ServiceID]zlist[ServiceMatch])Úcert_patternsÚobligatory_idsÚoptional_idsÚreturnc                 C  sœ   | sd}t |ƒ‚g }t| |ƒt| |ƒ }dd„ |D ƒ}|D ]}||kr:| |j|d�¡ q:|D ]*}||kr^t| |jƒr^| |j|d�¡ q^|r˜t|d�‚|S )zä
    Verify whether *cert_patterns* are valid for *obligatory_ids* and
    *optional_ids*.

    *obligatory_ids* must be both present and match.  *optional_ids* must match
    if a pattern of the respective type is present.
    z3Certificate does not contain any `subjectAltName`s.c                 S  s   g | ]
}|j ‘qS r   )r   )Ú.0Úmatchr   r   r   Ú
<listcomp>>   s     z+verify_service_identity.<locals>.<listcomp>)Zmismatched_id)Úerrors)r   Ú_find_matchesÚappendÚerror_on_mismatchÚ_contains_instance_ofÚpattern_classr   )r   r   r    Úmsgr%   ÚmatchesZmatched_idsÚir   r   r   Úverify_service_identity)   s2    
 ÿ
ÿ
 ÿ
ÿ
r.   )r   Úservice_idsr!   c                 C  s8   g }|D ]*}| D ] }|  |¡r| t||d�¡ qq|S )z„
    Search for matching certificate patterns and service_ids.

    Args:
        service_ids: List of service IDs like DNS_ID.
    )r   r   )Úverifyr'   r   )r   r/   r,   ZsidZcidr   r   r   r&   W   s    


ÿr&   zSequence[object]ÚtypeÚbool)ÚseqÚclr!   c                   s   t ‡ fdd„| D ƒƒS )Nc                 3  s   | ]}t |ˆ ƒV  qd S ©N)Ú
isinstance)r"   Úe©r4   r   r   Ú	<genexpr>m   s     z(_contains_instance_of.<locals>.<genexpr>)Úany)r3   r4   r   r8   r   r)   l   s    r)   zstr | bytes©Úpatternr!   c                 C  sˆ   t | tƒr0z|  d¡} W n tk
r.   Y dS X zt| ƒ W n tk
rP   Y nX dS zt |  dd¡¡ W n tk
r‚   Y dS X dS )zÆ
    Check whether *pattern* could be/match an IP address.

    Args:
        pattern: A pattern for a host name.

    Returns:
        `True` if *pattern* could be an IP address, else `False`.
    ÚasciiFTÚ*Ú1)	r6   ÚbytesÚdecodeÚUnicodeErrorÚintÚ
ValueErrorÚ	ipaddressÚ
ip_addressÚreplace©r<   r   r   r   Ú_is_ip_addressp   s    

rI   c                   @  s@   e Zd ZU dZe ¡ Zded< e 	d¡Z
edd dœdd„ƒZdS )	Ú
DNSPatternz7
    A DNS pattern as extracted from certificates.
    r@   r<   ó   ^[a-z0-9\-_.]+$r;   c                 C  sn   t |tƒsd}t|ƒ‚| ¡ }|dks6t|ƒs6d|krJd|›d�}t|ƒ‚| t¡}d|krdt|ƒ | |d�S )Nz'The DNS pattern must be a bytes string.ó    ó    zInvalid DNS pattern Ú.ó   *rH   )	r6   r@   Ú	TypeErrorÚstriprI   r   Ú	translateÚ_TRANS_TO_LOWERÚ_validate_pattern)Úclsr<   r+   r   r   r   Ú
from_bytesš   s    

zDNSPattern.from_bytesN)r   r   r   r   r   r   r<   r   ÚreÚcompileÚ_RE_LEGAL_CHARSÚclassmethodrV   r   r   r   r   rJ   �   s
   

rJ   c                   @  s6   e Zd ZU dZe ¡ Zded< edd dœdd„ƒZ	dS )	ÚIPAddressPatternz?
    An IP address pattern as extracted from certificates.
    ú-ipaddress.IPv4Address | ipaddress.IPv6Addressr<   r@   )Úbsr!   c                 C  sB   z| t  |¡d�W S  tk
r<   d|›d�}t|ƒd ‚Y nX d S )NrH   zInvalid IP address pattern rN   )rE   rF   rD   r   )rU   r]   r+   r   r   r   rV   ¶   s
    zIPAddressPattern.from_bytesN)
r   r   r   r   r   r   r<   r   rZ   rV   r   r   r   r   r[   ­   s   
r[   c                   @  sF   e Zd ZU dZe ¡ Zded< e ¡ Zded< e	dd dœdd„ƒZ
d	S )
Ú
URIPatternz8
    An URI pattern as extracted from certificates.
    r@   Úprotocol_patternrJ   Údns_patternr;   c                 C  sp   t |tƒsd}t|ƒ‚| ¡  t¡}d|ks<d|ks<t|ƒrPd|›d�}t|ƒ‚| d¡\}}| |t	 
|¡d�S )Nz'The URI pattern must be a bytes string.ó   :rO   zInvalid URI pattern rN   )r_   r`   ©r6   r@   rP   rQ   rR   rS   rI   r   ÚsplitrJ   rV   )rU   r<   r+   r_   Úhostnamer   r   r   rV   Ê   s    
þzURIPattern.from_bytesN)r   r   r   r   r   r   r_   r   r`   rZ   rV   r   r   r   r   r^   ¿   s
   
r^   c                   @  sF   e Zd ZU dZe ¡ Zded< e ¡ Zded< e	dd dœdd„ƒZ
d	S )
Ú
SRVPatternz8
    An SRV pattern as extracted from certificates.
    r@   Úname_patternrJ   r`   r;   c                 C  s†   t |tƒsd}t|ƒ‚| ¡  t¡}|d dksHd|ksHd|ksHt|ƒr\d|›d�}t|ƒ‚| dd¡\}}| |dd … t	 
|¡d	�S )
Nz'The SRV pattern must be a bytes string.r   é_   ó   .rO   zInvalid SRV pattern rN   r   )rf   r`   rb   )rU   r<   r+   Únamerd   r   r   r   rV   é   s&    

ÿþýü
 ÿzSRVPattern.from_bytesN)r   r   r   r   r   r   rf   r   r`   rZ   rV   r   r   r   r   re   Þ   s
   
re   c                   @  s@   e Zd Zeddœdd„ƒZeddœdd„ƒZdd	d
œdd„ZdS )r   ztype[CertificatePattern])r!   c                 C  s   d S r5   r   ©Úselfr   r   r   r*     s    zServiceID.pattern_classztype[Mismatch]c                 C  s   d S r5   r   rj   r   r   r   r(     s    zServiceID.error_on_mismatchr   r2   r;   c                 C  s   d S r5   r   ©rk   r<   r   r   r   r0     rL   zServiceID.verifyN)r   r   r   Úpropertyr*   r(   r0   r   r   r   r   r   	  s
   r   F)Úinitr   c                   @  sR   e Zd ZU dZe ¡ Zded< e 	d¡Z
eZeZddœdd„Zd	d
dœdd„ZdS )ÚDNS_IDz)
    A DNS service ID, aka hostname.
    r@   rd   rK   Ústr)rd   c                 C  sž   t |tƒsd}t|ƒ‚| ¡ }|r*t|ƒr6d}t|ƒ‚tdd„ |D ƒƒrftrXt |¡}qpd}t	|ƒ‚n
| d¡}| 
t¡| _| j | j¡d kršd}t|ƒ‚d S )NzDNS-ID must be a text string.zInvalid DNS-ID.c                 s  s   | ]}t |ƒd kV  qdS )é   N)Úord)r"   Úcr   r   r   r9   +  s     z"DNS_ID.__init__.<locals>.<genexpr>z+idna library is required for non-ASCII IDs.r=   )r6   rp   rP   rQ   rI   rD   r:   ÚidnaÚencodeÚImportErrorrR   rS   rd   rY   r#   )rk   rd   r+   Zascii_idr   r   r   Ú__init__!  s"    


zDNS_ID.__init__r   r2   r;   c                 C  s   t || jƒrt|j| jƒS dS )zC
        https://tools.ietf.org/search/rfc6125#section-6.4
        F)r6   r*   Ú_hostname_matchesr<   rd   rl   r   r   r   r0   9  s    zDNS_ID.verifyN)r   r   r   r   r   r   rd   r   rW   rX   rY   rJ   r*   r	   r(   rw   r0   r   r   r   r   ro     s   

ro   c                   @  s@   e Zd ZU dZejejd�Zde	d< e
ZeZdddœdd	„Zd
S )ÚIPAddress_IDz#
    An IP address service ID.
    )Ú	converterr\   Úipr   r2   r;   c                 C  s   t || jƒr| j|jkS dS )zC
        https://tools.ietf.org/search/rfc2818#section-3.1
        F)r6   r*   r{   r<   rl   r   r   r   r0   P  s    zIPAddress_ID.verifyN)r   r   r   r   r   r   rE   rF   r{   r   r[   r*   r
   r(   r0   r   r   r   r   ry   C  s   
ÿry   c                   @  sX   e Zd ZU dZe ¡ Zded< e ¡ Zded< e	Z
eZddœdd	„Zd
ddœdd„ZdS )ÚURI_IDz
    An URI service ID.
    r@   Úprotocolro   Údns_idrp   )Úuric                 C  sn   t |tƒsd}t|ƒ‚| ¡ }d|ks.t|ƒr:d}t|ƒ‚| d¡\}}| d¡ t	¡| _
t| d¡ƒ| _d S )NzURI-ID must be a text string.ú:zInvalid URI-ID.r=   ú/)r6   rp   rP   rQ   rI   rD   rc   ru   rR   rS   r}   ro   r~   )rk   r   r+   Zprotrd   r   r   r   rw   f  s    
zURI_ID.__init__r   r2   r;   c                 C  s*   t || jƒr&|j| jko$| j |j¡S dS )zE
        https://tools.ietf.org/search/rfc6125#section-6.5.2
        F)r6   r*   r_   r}   r~   r0   r`   rl   r   r   r   r0   u  s
    þzURI_ID.verifyN)r   r   r   r   r   r   r}   r   r~   r^   r*   r   r(   rw   r0   r   r   r   r   r|   Z  s   
r|   c                   @  sX   e Zd ZU dZe ¡ Zded< e ¡ Zded< e	Z
eZddœdd	„Zd
ddœdd„ZdS )ÚSRV_IDz
    An SRV service ID.
    r@   ri   ro   r~   rp   )Úsrvc                 C  s~   t |tƒsd}t|ƒ‚| ¡ }d|ks:t|ƒs:|d dkrFd}t|ƒ‚| dd¡\}}|dd …  d¡ t	¡| _
t|ƒ| _d S )NzSRV-ID must be a text string.rN   r   Ú_zInvalid SRV-ID.r   r=   )r6   rp   rP   rQ   rI   rD   rc   ru   rR   rS   ri   ro   r~   )rk   rƒ   r+   ri   rd   r   r   r   rw   Ž  s    
zSRV_ID.__init__r   r2   r;   c                 C  s*   t || jƒr&| j|jko$| j |j¡S dS )zE
        https://tools.ietf.org/search/rfc6125#section-6.5.1
        F)r6   r*   ri   rf   r~   r0   r`   rl   r   r   r   r0   �  s
    ÿzSRV_ID.verifyN)r   r   r   r   r   r   ri   r   r~   re   r*   r   r(   rw   r0   r   r   r   r   r‚   ‚  s   
r‚   r@   )r   Úactual_hostnamer!   c                 C  sb   d| krZd|krdS |   dd¡\}}|  dd¡\}}||kr@dS | d¡rNdS |d|fkS | |kS )zT
    :return: `True` if *cert_pattern* matches *actual_hostname*, else `False`.
    rO   rh   Fr   s   xn--)rc   Ú
startswith)r   r…   Z	cert_headZ	cert_tailZactual_headZactual_tailr   r   r   rx   ©  s    
rx   ÚNone)r   r!   c                 C  sš   |   d¡}|dkr&d| ›d�}t|ƒ‚|  d¡}t|ƒdk rPd| ›d�}t|ƒ‚d|d krpd| ›d	�}t|ƒ‚td
d„ |D ƒƒr–d| ›d�}t|ƒ‚dS )zh
    Check whether the usage of wildcards within *cert_pattern* conforms with
    our expectations.
    rO   r   zCertificate's DNS-ID z contains too many wildcards.rh   é   z0 has too few host components for wildcard usage.r   z+ has a wildcard outside the left-most part.c                 s  s   | ]}t |ƒ V  qd S r5   )Úlen)r"   Úpr   r   r   r9   Î  s     z$_validate_pattern.<locals>.<genexpr>z contains empty parts.N)Úcountr   rc   r‰   r:   )r   Zcntr+   Úpartsr   r   r   rT   ½  s    

rT   s   ABCDEFGHIJKLMNOPQRSTUVWXYZs   abcdefghijklmnopqrstuvwxyz)*r   Ú
__future__r   rE   rW   Útypingr   r   r   r   r   Ú
exceptionsr   r	   r
   r   r   r   r   rt   rv   Úsr   r.   r&   r)   rI   rJ   r[   r^   re   r   r   ro   ry   r|   r‚   rx   rT   r@   Ú	maketransrS   r   r   r   r   Ú<module>   sV   $

	.



!
ÿ	
.
'& ÿ