a
    kÄ#d÷‘  ã                   @   sv  d Z ddlmZ ddlmZ ddlZddlZddlZddlmZm	Z	 ddl
m  mZ ddlmZ ddlmZ ddlmZ dd	lmZ dd
lmZmZmZmZmZmZmZmZmZ ddlm Z m!Z!m"Z"m#Z# ddl$m%Z%m&Z& ej'�rddl(m)Z) ddl*m+Z+ ddl,m-Z-m.Z. ddl/m0Z0 dZ1dZ2dZ3ej4j5d:dd„ƒZ6ej4j5dd„ ƒZ7dd„ Z8G dd„ de9ƒZ:G dd„ de;ƒZ<G dd„ de<ƒZ=G d d!„ d!e >e=e9¡ƒZ?G d"d#„ d#e?e"ƒZ@G d$d%„ d%e?ƒZAG d&d'„ d'e<ƒZBG d(d)„ d)eƒZCG d*d+„ d+e >eBe9¡ƒZDG d,d-„ d-eDe"e#ƒZEG d.d/„ d/eDƒZFG d0d1„ d1e<ƒZGG d2d3„ d3e >eGe9¡ƒZHG d4d5„ d5e<ƒZIG d6d7„ d7e >eIe9¡ƒZJG d8d9„ d9eKƒZLdS );a(  
High-level methods for PKI objects (X.509 certificates, CRLs, asymmetric keys).
Supports both RSA and ECDSA objects.

The classes below are wrappers for the ASN.1 objects defined in x509.py.
By collecting their attributes, we bypass the ASN.1 structure, hence
there is no direct method for exporting a new full DER-encoded version
of a Cert instance after its serial has been modified (for example).
If you need to modify an import, just use the corresponding ASN1_Packet.

For instance, here is what you could do in order to modify the serial of
'cert' and then resign it with whatever 'key'::

    f = open('cert.der')
    c = X509_Cert(f.read())
    c.tbsCertificate.serialNumber = 0x4B1D
    k = PrivKey('key.pem')
    new_x509_cert = k.resignCert(c)

No need for obnoxious openssl tweaking anymore. :)
é    )Úabsolute_import)Úprint_functionN)ÚconfÚcrypto_validator)Úwarning)Úbinrepr)ÚASN1_BIT_STRING)Úhash_by_oid)	ÚX509_SubjectPublicKeyInfoÚRSAPublicKeyÚRSAPrivateKeyÚECDSAPublicKeyÚECDSAPrivateKeyÚRSAPrivateKey_OpenSSLÚECDSAPrivateKey_OpenSSLÚ	X509_CertÚX509_CRL)Ú
pkcs_os2ipÚ	_get_hashÚ_EncryptAndVerifyRSAÚ_DecryptAndSignRSA)ÚrawÚbytes_encode)Údefault_backend)Úserialization)ÚrsaÚec)ÚInvalidSignaturei È  i    ÚUNKNOWNc                    sV   d|   ¡ }t | ¡‰ ‡ fdd„tdtˆ ƒdƒD ƒ}|d |¡7 }|d|   ¡ 7 }|S )z=Convert DER octet string to PEM format (with optional header)z-----BEGIN %s-----
c                    s   g | ]}ˆ ||d  … ‘qS )é@   © )Ú.0Úi©Úbase64_stringr    úL/var/www/html/gsl.tools/lib/python3.9/site-packages/scapy/layers/tls/cert.pyÚ
<listcomp>J   ó    zder2pem.<locals>.<listcomp>r   r   ó   
z
-----END %s-----
)ÚencodeÚbase64Ú	b64encodeÚrangeÚlenÚjoin)Ú
der_stringÚobjÚ
pem_stringÚchunksr    r#   r%   Úder2pemD   s    
r3   c                 C   sl   |   dd¡} |  d¡d }|  d|¡dkr2tdƒ‚|  dd	|  d¡¡}| ||… }|  d
d¡ t |¡}|S )z Convert PEM string to DER formató   r'   s   -----
é   ó
   -----BEGINéÿÿÿÿz-pem2der() expects only one PEM-encoded objects   -----r   r(   )ÚreplaceÚfindÚ	ExceptionÚrfindr*   Ú	b64decode)r1   Z	first_idxZlast_idxr$   r/   r    r    r%   Úpem2derP   s    
r=   c                 C   s~   g }| dkrz|   d¡}|dkr qz|   d¡}|dkr:tdƒ‚|   d|¡d }|dkrZt| ƒ}| | ||… ¡ | |d	… } q|S )
zI
    Split PEM objects. Useful to process concatenated certificates.
    r'   r6   r7   s   -----ENDz$Invalid PEM object (missing END tag)r(   é   r   N)r9   r:   r-   Úappend)ÚsZpem_stringsZ	start_idxZend_idxr    r    r%   Ú	split_pem_   s    

rA   c                   @   s   e Zd Zdd„ Zdd„ ZdS )Ú_PKIObjc                 C   s   || _ || _|| _d S ©N)ÚfrmtÚderÚpem)ÚselfrD   rE   rF   r    r    r%   Ú__init__u   s    z_PKIObj.__init__c                 C   s   | j S rC   )rE   ©rG   r    r    r%   Ú__str__}   s    z_PKIObj.__str__N)Ú__name__Ú
__module__Ú__qualname__rH   rJ   r    r    r    r%   rB   t   s   rB   c                   @   s   e Zd Zddd„ZdS )Ú_PKIObjMakerNc                 C   s  d}|d u rt |ƒ‚t|ƒ}d|vr tj |¡r tj |¡}||krLt |ƒ‚z6t|dƒ�}| ¡ }W d   ƒ n1 sv0    Y  W q¤ t yœ   t |ƒ‚Y q¤0 n|}zLd|v rÐd}|}	t|ƒ}
d 	t
t|
ƒ¡}nd}|}d}	|d urît||ƒ}	W n t �y   t |ƒ‚Y n0 t|||	ƒ}|S )	NzUnable to import dataó    Úrbr6   ÚPEMr'   ÚDERÚ )r:   r   ÚosÚpathÚisfileÚgetsizeÚopenÚreadrA   r.   Úmapr=   r3   rB   )ÚclsZobj_pathZobj_max_sizeZ
pem_markerÚ	error_msgÚ_sizeÚfÚ_rawrD   rF   Zder_listrE   Úpr    r    r%   Ú__call__‚   s:    *z_PKIObjMaker.__call__)N)rK   rL   rM   ra   r    r    r    r%   rN   �   s   rN   c                   @   s   e Zd ZdZddd„ZdS )Ú_PubKeyFactoryzª
    Metaclass for PubKey creation.
    It casts the appropriate class on the fly, then fills in
    the appropriate attributes with import_from_asn1pkt() submethod.
    Nc                 C   sR  |d u r6t  | ¡}| tu rt} | |_d|_| ¡  |S t|tƒrdt  | ¡}t|_d|_| 	|¡ |S t
 | |t¡}zlt|jƒ}|j}t|tƒr t|_| |¡ n8t|tƒrÖt|_z| |j¡ W qØ tyÒ   Y qØ0 n‚ d}W nT t�y2   z"t|jƒ}t|_| |¡ d}W n t�y,   tdƒ‚Y n0 Y n0 |jdk�rNt|j|ƒ|_|S )NÚoriginalÚtuples
   PUBLIC KEYs   RSA PUBLIC KEYzUnable to import public keyrR   )Útypera   ÚPubKeyÚ	PubKeyRSAÚ	__class__rD   Úfill_and_storeÚ
isinstancerd   Úimport_from_tuplerN   Ú_MAX_KEY_SIZEr
   rE   ZsubjectPublicKeyr   Úimport_from_asn1pktr   ÚPubKeyECDSAÚimport_from_derÚImportErrorr:   r3   rF   )r[   Úkey_pathr0   ZspkiÚpubkeyÚmarkerr    r    r%   ra   ¾   sP    








z_PubKeyFactory.__call__)N©rK   rL   rM   Ú__doc__ra   r    r    r    r%   rb   ¸   s   rb   c                   @   s   e Zd ZdZdd„ ZdS )rf   ze
    Parent class for both PubKeyRSA and PubKeyECDSA.
    Provides a common verifyCert() method.
    c                 C   s8   |j }|j}t|jj }t|jƒ}| jt|ƒ||dd�S ©z) Verifies either a Cert or an X509_Cert. Úpkcs©ÚhÚt©ÚtbsCertificateÚ	signaturer	   Ú	algorithmÚvalr   ÚsignatureValueÚverify©rG   ÚcertÚtbsCertÚsigAlgry   ÚsigValr    r    r%   Ú
verifyCertú   s
    
zPubKey.verifyCertN)rK   rL   rM   ru   r‡   r    r    r    r%   rf   ô   s   rf   c                   @   sF   e Zd ZdZeddd„ƒZedd„ ƒZdd„ Zddd„Zddd„Z	dS )rg   zˆ
    Wrapper for RSA keys based on _EncryptAndVerifyRSA from crypto/pkcs1.py
    Use the 'key' attribute to access original object.
    Nc                 C   s’   |pd}|s2|pd}t j||tƒ d�}| ¡ | _n<tt|ƒƒ}|rR||krRtdƒ t j||d�}| tƒ ¡| _| j 	¡ }|| _
|j| _|j| _d S )Né  é   ©Zpublic_exponentZkey_sizeÚbackendú$modulus and modulusLen do not match!©ÚnÚe)r   Úgenerate_private_keyr   Ú
public_keyrr   r-   r   r   ÚRSAPublicNumbersÚpublic_numbersÚ_modulusLenrŽ   Ú_modulusr�   Ú_pubExp)rG   ÚmodulusÚ
modulusLenÚpubExpÚreal_modulusLenÚprivate_keyÚpubNumr    r    r%   ri     s"    þ
zPubKeyRSA.fill_and_storec                 C   sf   |\}}}t |tƒrt|ƒ}t |tƒr.t|ƒ}| j||d� | jjtjjtj	j
d�| _t| jƒ| _d S )N©r—   r™   )ÚencodingÚformat)rj   Úbytesr   ri   rr   Zpublic_bytesr   ZEncodingrQ   ZPublicFormatZSubjectPublicKeyInforF   r=   rE   )rG   Útupr�   ÚmZmLenr    r    r%   rk     s    


þzPubKeyRSA.import_from_tuplec                 C   s"   |j j}|jj}| j||d� d S )Nr�   )r—   r   ÚpublicExponentri   )rG   rr   r—   r™   r    r    r%   rm   +  s    zPubKeyRSA.import_from_asn1pktrw   Úsha256c                 C   s   t j| |||||d�S ©N)rz   ry   ÚmgfÚL)r   Úencrypt©rG   Úmsgrz   ry   r¦   r§   r    r    r%   r¨   0  s    zPubKeyRSA.encryptc              	   C   s   t j| ||||||d�S r¥   ©r   r�   ©rG   rª   Úsigrz   ry   r¦   r§   r    r    r%   r�   4  s    ÿzPubKeyRSA.verify)NNN)rw   r¤   NN)rw   r¤   NN)
rK   rL   rM   ru   r   ri   rk   rm   r¨   r�   r    r    r    r%   rg     s   

rg   c                   @   sB   e Zd ZdZeddd„ƒZedd„ ƒZddd	„Zedd
d„ƒZdS )rn   zz
    Wrapper for ECDSA keys based on the cryptography library.
    Use the 'key' attribute to access original object.
    Nc                 C   s(   |pt j}t  |ƒ tƒ ¡}| ¡ | _d S rC   )r   Ú	SECP256R1r�   r   r‘   rr   )rG   Úcurver›   r    r    r%   ri   >  s    
zPubKeyECDSA.fill_and_storec                 C   s   t j|tƒ d�| _d S ©N)r‹   )r   Zload_der_public_keyr   rr   )rG   rr   r    r    r%   ro   D  s    ÿzPubKeyECDSA.import_from_derr¤   c                 K   s   t dƒ‚d S )NzNo ECDSA encryption support)r:   )rG   rª   ry   Úkwargsr    r    r%   r¨   J  s    zPubKeyECDSA.encryptc                 K   s:   z | j  ||t t|ƒ¡¡ W dS  ty4   Y dS 0 d S ©NTF©rr   r�   r   ÚECDSAr   r   ©rG   rª   r­   ry   r±   r    r    r%   r�   N  s
    zPubKeyECDSA.verify)N)r¤   )r¤   )	rK   rL   rM   ru   r   ri   ro   r¨   r�   r    r    r    r%   rn   9  s   

rn   c                   @   s   e Zd ZdZddd„ZdS )Ú_PrivKeyFactoryz«
    Metaclass for PrivKey creation.
    It casts the appropriate class on the fly, then fills in
    the appropriate attributes with import_from_asn1pkt() submethod.
    Nc                 C   sr  |du r6t  | ¡}| tu rt} | |_d|_| ¡  |S t | |t¡}d}zt	|j
ƒ}|j}t|_d}W n° t�y   z"t|j
ƒ}|j}t|_d}d}W nx t�y   zt|j
ƒ}t|_d}W nJ t�y
   zt|j
ƒ}t|_d}W n t�y   tdƒ‚Y n0 Y n0 Y n0 Y n0 z| |¡ W n t�y:   Y n0 |jd	k�rn|�r`tt|ƒ|ƒ|_nt|j
|ƒ|_|S )
zù
        key_path may be the path to either:
            _an RSAPrivateKey_OpenSSL (as generated by openssl);
            _an ECDSAPrivateKey_OpenSSL (as generated by openssl);
            _an RSAPrivateKey;
            _an ECDSAPrivateKey.
        Nrc   Fs   PRIVATE KEYs   EC PRIVATE KEYTs   RSA PRIVATE KEYzUnable to import private keyrR   )re   ra   ÚPrivKeyÚPrivKeyECDSArh   rD   ri   rN   rl   r   rE   Z
privateKeyÚ
PrivKeyRSAr:   r   r   r   rm   rp   r3   r   rF   )r[   rq   r0   ZmultiPEMÚprivkeyrs   r    r    r%   ra   b  sV    




 z_PrivKeyFactory.__call__)Nrt   r    r    r    r%   r¶   \  s   r¶   c                   @   s   e Zd ZdZdd„ ZeZdS )Ú_Raw_ASN1_BIT_STRINGz+A ASN1_BIT_STRING that ignores BER encodingc                 C   s   | j S rC   )Zval_readablerI   r    r    r%   Ú	__bytes__�  s    z_Raw_ASN1_BIT_STRING.__bytes__N)rK   rL   rM   ru   r¼   rJ   r    r    r    r%   r»   ›  s   r»   c                   @   s*   e Zd ZdZd
dd„Zdd„ Zdd„ Zd	S )r·   zx
    Parent class for both PrivKeyRSA and PrivKeyECDSA.
    Provides common signTBSCert() and resignCert() methods.
    r¤   c                 C   sN   |j }|pt|jj }| jt|ƒ|dd�}tƒ }||_||_t	|dd�|_
|S )aÍ  
        Note that this will always copy the signature field from the
        tbsCertificate into the signatureAlgorithm field of the result,
        regardless of the coherence between its contents (which might
        indicate ecdsa-with-SHA512) and the result (e.g. RSA signing MD2).

        There is a small inheritance trick for the computation of sigVal
        below: in order to use a sign() method which would apply
        to both PrivKeyRSA and PrivKeyECDSA, the sign() methods of the
        subclasses accept any argument, be it from the RSA or ECDSA world,
        and then they keep the ones they're interested in.
        Here, t will be passed eventually to pkcs1._DecryptAndSignRSA.sign().
        rw   rx   T)Úreadable)r}   r	   r~   r   Úsignr   r   r|   ZsignatureAlgorithmr»   r€   )rG   r„   ry   r…   r†   Úcr    r    r%   ÚsignTBSCert¨  s    zPrivKey.signTBSCertc                 C   s   | j |jdd�S )z9 Rewrite the signature of either a Cert or an X509_Cert. N)ry   )rÀ   r|   )rG   rƒ   r    r    r%   Ú
resignCert¿  s    zPrivKey.resignCertc                 C   s8   |j }|j}t|jj }t|jƒ}| jt|ƒ||dd�S rv   r{   r‚   r    r    r%   r‡   Ã  s
    
zPrivKey.verifyCertN)r¤   )rK   rL   rM   ru   rÀ   rÁ   r‡   r    r    r    r%   r·   ¢  s   
r·   c                
   @   s:   e Zd ZdZeddd„ƒZdd„ Zdd	d
„Zddd„ZdS )r¹   z†
    Wrapper for RSA keys based on _DecryptAndSignRSA from crypto/pkcs1.py
    Use the 'key' attribute to access original object.
    Nc
              	   C   sÌ   |pd}d |||||	||fv rH|p$d}
t j||
tƒ d�| _| j ¡ | _n`tt|ƒƒ}
|rh|
|krhtdƒ t j	||d�}t j
||||||	|d�}| tƒ ¡| _| j ¡ | _| j ¡ }|
| _|j| _|j| _d S )Nrˆ   r‰   rŠ   rŒ   r�   )r`   ÚqZdmp1Zdmq1ZiqmpÚdr“   )r   r�   r   Úkeyr‘   rr   r-   r   r   r’   ZRSAPrivateNumbersr›   r“   r”   rŽ   r•   r�   r–   )rG   r—   r˜   r™   Úprime1Úprime2ÚcoefficientÚ	exponent1Ú	exponent2ÚprivExprš   rœ   ZprivNumr    r    r%   ri   Ñ  s2    ÿþý
zPrivKeyRSA.fill_and_storec           
   
   C   s^   |j j}|jj}|jj}|jj}|jj}|jj}|jj}|jj}	| j	||||||||	d� d S )N)r—   r™   rÊ   rÅ   rÆ   rÈ   rÉ   rÇ   )
r—   r   r£   ZprivateExponentrÅ   rÆ   rÈ   rÉ   rÇ   ri   )
rG   rº   r—   r™   rÊ   rÅ   rÆ   rÈ   rÉ   rÇ   r    r    r%   rm   ò  s    ýzPrivKeyRSA.import_from_asn1pktrw   r¤   c              	   C   s   t j| ||||||d�S r¥   r«   r¬   r    r    r%   r�      s    ÿzPrivKeyRSA.verifyc                 C   s   t j| |||||d�S r¥   )r   r¾   )rG   Údatarz   ry   r¦   r§   r    r    r%   r¾     s    zPrivKeyRSA.sign)	NNNNNNNNN)rw   r¤   NN)rw   r¤   NN©	rK   rL   rM   ru   r   ri   rm   r�   r¾   r    r    r    r%   r¹   Ì  s      þ 
r¹   c                   @   sF   e Zd ZdZeddd„ƒZedd„ ƒZeddd	„ƒZedd
d„ƒZdS )r¸   z
    Wrapper for ECDSA keys based on SigningKey from ecdsa library.
    Use the 'key' attribute to access original object.
    Nc                 C   s,   |pt j}t  |ƒ tƒ ¡| _| j ¡ | _d S rC   )r   r®   r�   r   rÄ   r‘   rr   )rG   r¯   r    r    r%   ri     s    
zPrivKeyECDSA.fill_and_storec                 C   s(   t jt|ƒd tƒ d�| _| j ¡ | _d S r°   )r   Zload_der_private_keyr   r   rÄ   r‘   rr   )rG   rº   r    r    r%   rm     s    ÿz PrivKeyECDSA.import_from_asn1pktr¤   c                 K   s:   z | j  ||t t|ƒ¡¡ W dS  ty4   Y dS 0 d S r²   r³   rµ   r    r    r%   r�     s
    zPrivKeyECDSA.verifyc                 K   s   | j  |t t|ƒ¡¡S rC   )rÄ   r¾   r   r´   r   )rG   rË   ry   r±   r    r    r%   r¾   #  s    zPrivKeyECDSA.sign)N)r¤   )r¤   rÌ   r    r    r    r%   r¸   	  s   
r¸   c                   @   s   e Zd ZdZdd„ ZdS )Ú
_CertMakerz™
    Metaclass for Cert creation. It is not necessary as it was for the keys,
    but we reuse the model instead of creating redundant constructors.
    c                 C   sN   t  | |td¡}t|_zt|jƒ}W n ty>   tdƒ‚Y n0 | |¡ |S )NÚCERTIFICATEúUnable to import certificate)	rN   ra   Ú_MAX_CERT_SIZEÚCertrh   r   rE   r:   rm   )r[   Ú	cert_pathr0   rƒ   r    r    r%   ra   1  s    ÿ
z_CertMaker.__call__Nrt   r    r    r    r%   rÍ   ,  s   rÍ   c                   @   sh   e Zd ZdZdd„ Zdd„ Zdd„ Zddd„Zddd„Zddd„Z	dd„ Z
ddd„Zdd„ Zdd„ Zd
S )rÑ   zt
    Wrapper for the X509_Cert from layers/x509.py.
    Use the 'x509Cert' attribute to access original object.
    c                 C   sî  d}|| _ |j}|| _|jr,|jjd | _nd| _|jj| _|jjj| _	| 
¡ | _| ¡ | _t| jƒ| _| ¡ | _| ¡ | _t| jƒ| _d | _|jjj| _z|jjj ¡ | _W n tyÈ   t|ƒ‚Y n0 t  d| j¡| _!|jj"j| _#z|jj"j ¡ | _$W n t�y   t|ƒ‚Y n0 t  d| j$¡| _%t&t'|j(ƒƒ| _)|j*�rÒ|j*D ]Š}|j+jdk�r|d| _,|j-j,�rÎ|j-j,jdk | _,nR|j+jdk�r˜|j- .¡ | _/n6|j+jdk�r´|j- 0¡ | _1n|j+jd	k�rF|j-j2j| _�qFt'|j3ƒ| _3t4| j3ƒ| _5d S )
NrÏ   r>   ú%xZbasicConstraintsFr   ÚkeyUsageÚextKeyUsageZauthorityKeyIdentifier)6Zx509Certr|   Úversionr   ÚserialNumberÚserialr}   r~   Úoidnamer…   Ú
get_issuerÚissuerÚget_issuer_strÚ
issuer_strÚhashÚissuer_hashZget_subjectÚsubjectZget_subject_strÚsubject_strÚsubject_hashÚauthorityKeyIDZvalidityZ
not_beforeÚpretty_timeÚnotBefore_strÚdatetimeÚ	timetupleZ	notBeforeÚ
ValueErrorr:   ÚtimeÚstrftimeZnotBefore_str_simpleZ	not_afterÚnotAfter_strÚnotAfterZnotAfter_str_simplerf   r   ZsubjectPublicKeyInfoÚpubKeyÚ
extensionsÚextnIDZcAÚ	extnValueZget_keyUsagerÔ   Zget_extendedKeyUsagerÕ   ZkeyIdentifierr€   r-   ÚsignatureLen)rG   rƒ   r\   r„   Zextnr    r    r%   rm   C  sV    






zCert.import_from_asn1pktc                 C   s   | j |jkrdS |j | ¡S )zƒ
        True if 'other' issued 'self', i.e.:
          - self.issuer == other.subject
          - self is signed by other
        F©rß   râ   rí   r‡   ©rG   Úotherr    r    r%   ÚisIssuerCerty  s    zCert.isIssuerCertc                 C   s   | j | jkr|  | ¡S dS )z£
        Return True if the certificate is self-signed:
          - issuer and subject are the same
          - the signature of the certificate is valid.
        F)rß   râ   rõ   rI   r    r    r%   ÚisSelfSignedƒ  s    
zCert.isSelfSignedrw   r¤   Nc                 C   s   | j j|||||d�S r¥   )rí   r¨   r©   r    r    r%   r¨   �  s    zCert.encryptc                 C   s   | j j||||||d�S r¥   )rí   r�   r¬   r    r    r%   r�   ‘  s    zCert.verifyc                 C   sŒ   |du rt  ¡ }nTt|tƒrfz&d|v r4t  |d¡}nt  |d¡}W n" tyd   tdƒ t  ¡ }Y n0 t  |¡}t  | j¡}|| d }|S )af  
        Based on the value of notAfter field, returns the number of
        days the certificate will still be valid. The date used for the
        comparison is the current and local date, as returned by
        time.localtime(), except if 'now' argument is provided another
        one. 'now' argument can be given as either a time tuple or a string
        representing the date. Accepted format for the string version
        are:

         - '%b %d %H:%M:%S %Y %Z' e.g. 'Jan 30 07:38:59 2008 GMT'
         - '%m/%d/%y' e.g. '01/30/08' (less precise)

        If the certificate is no more valid at the date considered, then
        a negative value is returned representing the number of days
        since it has expired.

        The number of days is returned as a float to deal with the unlikely
        case of certificates that are still just valid.
        Nú/z%m/%d/%yz%b %d %H:%M:%S %Y %Zz7Bad time string provided, will use localtime() instead.g     õ@)	ré   Ú	localtimerj   ÚstrÚstrptimer:   r   Úmktimerì   )rG   ÚnowZnftÚdiffr    r    r%   ÚremainingDays”  s    


zCert.remainingDaysc                 C   sn   |D ]d}| j durB|j durB| j |j krB| jdd„ |jD ƒv   S | j|jkr| jdd„ |jD ƒv   S qdS )aÂ  
        Given a list of trusted CRL (their signature has already been
        verified with trusted anchors), this function returns True if
        the certificate is marked as revoked by one of those CRL.

        Note that if the Certificate was on hold in a previous CRL and
        is now valid again in a new CRL and bot are in the list, it
        will be considered revoked: this is because _all_ CRLs are
        checked (not only the freshest) and revocation status is not
        handled.

        Also note that the check on the issuer is performed on the
        Authority Key Identifier if available in _both_ the CRL and the
        Cert. Otherwise, the issuers are simply compared.
        Nc                 s   s   | ]}|d  V  qdS ©r   Nr    ©r!   Úxr    r    r%   Ú	<genexpr>Í  r'   z!Cert.isRevoked.<locals>.<genexpr>c                 s   s   | ]}|d  V  qdS rÿ   r    r   r    r    r%   r  Ï  r'   F)rã   rØ   Úrevoked_cert_serialsrÛ   )rG   Zcrl_listr¿   r    r    r%   Ú	isRevoked¹  s    
ÿ
þzCert.isRevokedrR   c                 C   sX   t |dƒ�:}|dkr"| | j¡ n|dkr6| | j¡ W d  ƒ n1 sJ0    Y  dS )zT
        Export certificate in 'fmt' format (DER or PEM) to file 'filename'
        ÚwbrR   rQ   N)rX   ÚwriterE   rF   )rG   ÚfilenameÚfmtr^   r    r    r%   ÚexportÒ  s
    zCert.exportc                 C   sB   t d| j ƒ t d| j ƒ t d| j ƒ t d| j| jf ƒ d S )Nz
Serial: %súIssuer: z	Subject: zValidity: %s to %s)ÚprintrØ   rÝ   rá   rå   rë   rI   r    r    r%   ÚshowÜ  s    z	Cert.showc                 C   s   d| j | jf S )Nz#[X.509 Cert. Subject:%s, Issuer:%s])rá   rÝ   rI   r    r    r%   Ú__repr__â  s    zCert.__repr__)rw   r¤   NN)rw   r¤   NN)N)rR   )rK   rL   rM   ru   rm   rõ   rö   r¨   r�   rþ   r  r	  r  r  r    r    r    r%   rÑ   =  s   6




%

rÑ   c                   @   s   e Zd ZdZdd„ ZdS )Ú	_CRLMakerz˜
    Metaclass for CRL creation. It is not necessary as it was for the keys,
    but we reuse the model instead of creating redundant constructors.
    c                 C   sN   t  | |td¡}t|_zt|jƒ}W n ty>   tdƒ‚Y n0 | |¡ |S )NzX509 CRLúUnable to import CRL)	rN   ra   Ú_MAX_CRL_SIZEÚCRLrh   r   rE   r:   rm   )r[   rÒ   r0   Úcrlr    r    r%   ra   ï  s    
z_CRLMaker.__call__Nrt   r    r    r    r%   r  ê  s   r  c                   @   s0   e Zd ZdZdd„ Zdd„ Zdd„ Zdd	„ Zd
S )r  zr
    Wrapper for the X509_CRL from layers/x509.py.
    Use the 'x509CRL' attribute to access original object.
    c              	   C   s  d}|| _ |j}t|ƒ| _|jr0|jjd | _nd| _|jjj| _| 	¡ | _
| ¡ | _t| jƒ| _|jj| _|jj}|d dkrŒ|d d… }zt |d¡| _W n ty¸   t|ƒ‚Y n0 t d| j¡| _d | _d | _|j�rJ|jj| _|jj}|d dk�r
|d d… }zt |d¡| _W n t�y8   t|ƒ‚Y n0 t d| j¡| _|j�rz|jD ] }|jjdk�rX|jjj| _ �qXg }|j!�rú|j!D ]l}|j"j}	|j#j}
|
d dk�rº|
d d… }
zt |
d¡ W n t�yæ   t|ƒ‚Y n0 | $|	|
f¡ �qŒ|| _%t|j&ƒ| _&t'| j&ƒ| _(d S )Nr  r>   r7   ÚZz%y%m%d%H%M%SrÓ   Ú	cRLNumber))Zx509CRLÚtbsCertListr   rÖ   r   r}   r~   rÙ   r…   rÚ   rÛ   rÜ   rÝ   rÞ   rß   Zthis_updaterä   ÚlastUpdate_strré   rú   Ú
lastUpdater:   rê   ZlastUpdate_str_simpleÚ
nextUpdateZnextUpdate_str_simpleZnext_updateÚnextUpdate_strZcrlExtensionsrï   rð   r  ÚnumberZrevokedCertificatesr×   ZrevocationDater?   r  r€   r-   rñ   )rG   r  r\   r  r  r  Ú	extensionZrevokedrƒ   rØ   Údater    r    r%   rm      sf    






zCRL.import_from_asn1pktc                 C   s   | j |jkrdS |j | ¡S )NFrò   ró   r    r    r%   rõ   >  s    zCRL.isIssuerCertc                    s   t ‡ fdd„|D ƒƒS )Nc                 3   s   | ]}ˆ   |¡V  qd S rC   )rõ   )r!   ÚarI   r    r%   r  F  r'   zCRL.verify.<locals>.<genexpr>)Úany)rG   Úanchorsr    rI   r%   r�   D  s    z
CRL.verifyc                 C   sJ   t d| j ƒ t d| j ƒ t d| j ƒ t d| j ƒ t d| j ƒ d S )NzVersion: %dzsigAlg: r
  zlastUpdate: %sznextUpdate: %s)r  rÖ   r…   rÝ   r  r  rI   r    r    r%   r  H  s
    zCRL.showN)rK   rL   rM   ru   rm   rõ   r�   r  r    r    r    r%   r  ú  s
   >r  c                   @   s@   e Zd ZdZddd„Zddd„Zddd„Zdd	d
„Zdd„ ZdS )ÚChainz/
    Basically, an enhanced array of Cert.
    Nc                 C   s¢   t  | d¡ |r|  |¡ n*|D ]$}| ¡ r |  |¡ | |¡  qFq t| ƒdkrž|ržt| ƒ}|D ]*}| | d ¡rb|  |¡ | |¡  qŽqbt| ƒ|krRqžqRdS )a¶  
        Construct a chain of certificates starting with a self-signed
        certificate (or any certificate submitted by the user)
        and following issuer/subject matching and signature validity.
        If there is exactly one chain to be constructed, it will be,
        but if there are multiple potential chains, there is no guarantee
        that the retained one will be the longest one.
        As Cert and CRL classes both share an isIssuerCert() method,
        the trailing element of a Chain may alternatively be a CRL.

        Note that we do not check AKID/{SKID/issuer/serial} matching,
        nor the presence of keyCertSign in keyUsage extension (if present).
        r    r   r7   N)ÚlistrH   r?   rö   Úremover-   rõ   )rG   ZcertListZcert0Zroot_candidateZtmp_lenr¿   r    r    r%   rH   Y  s$    



zChain.__init__c                    sv   |pg }|D ]d}t | | |ƒ‰ tˆ ƒdkr,qt‡ fdd„| D ƒƒrˆ D ]}| ¡ dk rF q\qF|ˆ d u rˆ   S qdS )aƒ  
        Perform verification of certificate chains for that certificate.
        A list of anchors is required. The certificates in the optional
        untrusted list may be used as additional elements to the final chain.
        On par with chain instantiation, only one chain constructed with the
        untrusted candidates will be retained. Eventually, dates are checked.
        r>   c                 3   s   | ]}|ˆ d d… v V  qdS )r>   Nr    ©r!   r¿   ©Úchainr    r%   r  ‹  r'   z$Chain.verifyChain.<locals>.<genexpr>r   r7   N)r   r-   r  rþ   )rG   r  Ú	untrustedr  r¿   r    r$  r%   ÚverifyChain}  s    
zChain.verifyChainc                 C   sÜ   z6t |dƒ�}| ¡ }W d  ƒ n1 s*0    Y  W n tyP   tdƒ‚Y n0 dd„ t|ƒD ƒ}d}|rÐz6t |dƒ�}| ¡ }W d  ƒ n1 s–0    Y  W n ty¼   tdƒ‚Y n0 dd„ t|ƒD ƒ}|  ||¡S )zÒ
        Does the same job as .verifyChain() but using the list of anchors
        from the cafile. As for .verifyChain(), a list of untrusted
        certificates can be passed (as a file, this time).
        rP   NzCould not read from cafilec                 S   s   g | ]}t |ƒ‘qS r    ©rÑ   r#  r    r    r%   r&   Ÿ  r'   z/Chain.verifyChainFromCAFile.<locals>.<listcomp>ú"Could not read from untrusted_filec                 S   s   g | ]}t |ƒ‘qS r    r(  r#  r    r    r%   r&   ¨  r'   )rX   rY   r:   rA   r'  )rG   ÚcafileÚuntrusted_filer^   Úca_certsr  r&  Úuntrusted_certsr    r    r%   ÚverifyChainFromCAFile“  s    **zChain.verifyChainFromCAFilec           	   	   C   sò   z^g }t  |¡D ]J}tt j ||¡dƒ�"}| t| ¡ ƒ¡ W d  ƒ q1 sP0    Y  qW n tyx   tdƒ‚Y n0 d}|ræz6t|dƒ�}| ¡ }W d  ƒ n1 s¬0    Y  W n tyÒ   tdƒ‚Y n0 dd„ t	|ƒD ƒ}|  
||¡S )ae  
        Does the same job as .verifyChainFromCAFile() but using the list
        of anchors in capath directory. The directory should (only) contain
        certificates files in PEM format. As for .verifyChainFromCAFile(),
        a list of untrusted certificates can be passed as a file
        (concatenation of the certificates in PEM format).
        rP   Nz(capath provided is not a valid cert pathr)  c                 S   s   g | ]}t |ƒ‘qS r    r(  r#  r    r    r%   r&   Ã  r'   z/Chain.verifyChainFromCAPath.<locals>.<listcomp>)rT   ÚlistdirrX   rU   r.   r?   rÑ   rY   r:   rA   r'  )	rG   Úcapathr+  r  r*  Úfdr&  r^   r-  r    r    r%   ÚverifyChainFromCAPath¬  s     6*zChain.verifyChainFromCAPathc                 C   s–   t | ƒd }|dk rdS | d }d}| ¡ s<|d|j 7 }n|d|j 7 }d}||kr’| | }|dd| d	 |jf 7 }||krˆ|d
7 }|d7 }qN|S )Nr>   r   rS   z__ z%s [Not Self Signed]
z%s [Self Signed]
z%s_ %sú é   Ú
)r-   rö   rá   )rG   Zllenr¿   r@   Úidxr    r    r%   r  Ç  s     
zChain.__repr__)N)N)N)N)	rK   rL   rM   ru   rH   r'  r.  r2  r  r    r    r    r%   r   T  s   
$


r   )r   )Mru   Ú
__future__r   r   r*   rT   ré   Zscapy.configr   r   Zscapy.libs.sixZlibsÚsixZscapy.errorr   Zscapy.utilsr   Zscapy.asn1.asn1r   Zscapy.asn1.mibr	   Zscapy.layers.x509r
   r   r   r   r   r   r   r   r   Zscapy.layers.tls.crypto.pkcs1r   r   r   r   Zscapy.compatr   r   Zcrypto_validZcryptography.hazmat.backendsr   Zcryptography.hazmat.primitivesr   Z)cryptography.hazmat.primitives.asymmetricr   r   Z'cryptography.hazmat.backends.openssl.ecr   rl   rÐ   r  ÚcommandsÚregisterr3   r=   rA   ÚobjectrB   re   rN   rb   Úwith_metaclassrf   rg   rn   r¶   r»   r·   r¹   r¸   rÍ   rÑ   r  r  r!  r   r    r    r    r%   Ú<module>   sX   ,
7<6#?*=# .Z