
    h                        d Z ddlZddlZddl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 ddlmZmZ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#        rEddl$m%Z% ddl&m'Z' ddl(m)Z) ddl*m+Z+m,Z,m-Z- 	  e+j.        dd           dZ/n# e0$ r dZ/ddl1m2Z2 Y nw xY wdZ3dZ4dZ5ej6        j7        d@d            Z8ej6        j7        d             Z9d Z: G d de;          Z< G d de=          Z> G d d e>          Z? G d! d"e?#          Z@ G d$ d%e@e          ZA G d& d'e@          ZB G d( d)e@          ZC G d* d+e>          ZD G d, d-e          ZE G d. d/eD#          ZF G d0 d1eFee          ZG G d2 d3eF          ZH G d4 d5eF          ZI G d6 d7e>          ZJ G d8 d9eJ#          ZK G d: d;e>          ZL G d< d=eL#          ZM G d> d?eN          ZOdS )Aa(  
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. :)
    N)confcrypto_validator)warning)binrepr)ASN1_BIT_STRING)hash_by_oid)ECDSAPrivateKey_OpenSSLECDSAPrivateKeyECDSAPublicKeyEdDSAPublicKeyEdDSAPrivateKeyRSAPrivateKey_OpenSSLRSAPrivateKeyRSAPublicKey	X509_CertX509_CRLX509_SubjectPublicKeyInfo)
pkcs_os2ip	_get_hash_EncryptAndVerifyRSA_DecryptAndSignRSA)rawbytes_encode)InvalidSignature)default_backend)serialization)rsaecx25519  i   public_exponentkey_sizeTF)rust_openssli   i   UNKNOWNc                    d|z                                   }t          j        |           fdt          dt	                    d          D             }|d                    |          z  }|d|z                                   z  }|S )z=Convert DER octet string to PEM format (with optional header)z-----BEGIN %s-----
c                 *    g | ]}||d z            S )@    ).0ibase64_strings     Y/mounts/lovelace/software/anaconda3/lib/python3.11/site-packages/scapy/layers/tls/cert.py
<listcomp>zder2pem.<locals>.<listcomp>^   s&    PPP!mAa"fH%PPP    r   r(      
z
-----END %s-----
)encodebase64	b64encoderangelenjoin)
der_stringobj
pem_stringchunksr,   s       @r-   der2pemr;   X   s     )3.6688J$Z00MPPPPuQM8J8JB/O/OPPPF%**V$$$J)C/77999Jr/   c                 p   |                      dd          } |                     d          dz   }|                     d|          dk    rt          d          |                     dd	|                     d                    }| ||         }|                     d
d           t	          j        |          }|S )z Convert PEM string to DER format   r/   s   -----
   
   -----BEGINz-pem2der() expects only one PEM-encoded objects   -----r   r0   )replacefind	Exceptionrfindr2   	b64decode)r9   	first_idxlast_idxr,   r7   s        r-   pem2derrH   d   s     ##E3//J
++a/I}i00B66GHHH!Z-=-=h-G-GHHHy12M%%%%!-00Jr/   c                 X   g }| dk    r|                      d          }|dk    rn|                      d          }|dk    rt          d          |                      d|          dz   }|dk    rt          |           }|                    | ||                    | |d	         } | dk    |S )
zI
    Split PEM objects. Useful to process concatenated certificates.
    r/   r?   r@   s   -----ENDz$Invalid PEM object (missing END tag)r0      r   N)rB   rC   r5   append)spem_strings	start_idxend_idxs       r-   	split_pemrP   s   s     K
s((FF=))	??&&%%b==BCCC&&((1,a<<!ffG1Yw./000ghhK s(( r/   c                       e Zd Zd Zd ZdS )_PKIObjc                 0    || _         || _        || _        d S N)frmtderpem)selfrU   rV   rW   s       r-   __init__z_PKIObj.__init__   s     	r/   c                     | j         S rT   )rV   rX   s    r-   __str__z_PKIObj.__str__   s	    xr/   N)__name__
__module____qualname__rY   r\   r)   r/   r-   rR   rR      s2              r/   rR   c                       e Zd ZddZdS )_PKIObjMakerNc                    d}|t          |          t          |          }d|vrt          j                            |          rt          j                            |          }||k    rt          |          	 t          |d          5 }|                                }d d d            n# 1 swxY w Y   n# t           $ r t          |          w xY w|}	 d|v r<d}|}	t          |          }
d	                    t          t          |
                    }nd}|}d}	|t          ||          }	n# t           $ r t          |          w xY wt          |||	          }|S )	NzUnable to import data    rbr?   PEMr/   DER )rC   r   ospathisfilegetsizeopenreadrP   r6   maprH   r;   rR   )clsobj_pathobj_max_size
pem_marker	error_msg_sizef_rawrU   rW   der_listrV   ps                r-   __call__z_PKIObjMaker.__call__   s    ,	I&&&))8##)A)A#GOOH--E|##	***+(D)) $Q6688D$ $ $ $ $ $ $ $ $ $ $ $ $ $ $ + + +	***+ D	'$$$T??hhs7H5566)!$
33C  	' 	' 	'I&&&	' D#s##s=   ;B8 B, B8 ,B00B8 3B04B8 8CAD1 1ErT   )r]   r^   r_   ry   r)   r/   r-   ra   ra      s(        + + + + + +r/   ra   c                       e Zd ZdZ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                 h   |Nt                               |           }| t          u rt          } | |_        d|_        |                                 |S t          |t                    rDt                               |           }t          |_        d|_        |	                    |           |S t                              | |t                    }	 t          |j                  }|j        }t          |t                    r"t          |_        |                    |           nyt          |t"                    r't$          |_        |                    |j                   n=t          |t(                    r't*          |_        |                    |j                   n d}ns# t,          $ rf 	 t          |j                  }t          |_        |                    |           d}n*# t,          $ r t.          j        r t-          d          w xY wY nw xY w|j        dk    rt3          |j        |          |_        |S )Noriginaltuples
   PUBLIC KEYs   RSA PUBLIC KEYzUnable to import public keyrf   )typery   PubKey	PubKeyRSA	__class__rU   fill_and_store
isinstancer~   import_from_tuplera   _MAX_KEY_SIZEr   rV   subjectPublicKeyr   import_from_asn1pktr   PubKeyECDSAimport_from_derr   PubKeyEdDSArC   r   debug_dissectorr;   rW   )ro   key_pathr8   spkipubkeymarkers         r-   ry   z_PubKeyFactory.__call__   s"   --$$Cf}}CM!CH   J h&& 	--$$C%CMCH!!(+++J ##C=AA	?,SW55D*F&,// 
 )''////FN33  +##CG,,,,FN33  +##CG,,,,"FF 
	? 
	? 
	?	?%cg.. )''///* ? ? ?'  =>>>	? 
	? 8ucgv..CG
s+   CF 
H
%7GH
'HH
	H
rT   r]   r^   r_   __doc__ry   r)   r/   r-   r{   r{      s2         
6 6 6 6 6 6r/   r{   c                       e Zd ZdZd ZdS )r   ze
    Parent class for both PubKeyRSA and PubKeyECDSA.
    Provides a common verifyCert() method.
    c                     |j         }|j        }t          |j        j                 }t          |j                  }|                     t          |          ||d          S z) Verifies either a Cert or an X509_Cert. pkcshttbsCertificate	signaturer   	algorithmvalr   signatureValueverifyrX   certtbsCertsigAlgr   sigVals         r-   
verifyCertzPubKey.verifyCert  R    %"(,-T()){{3w<<1{???r/   N)r]   r^   r_   r   r   r)   r/   r-   r   r     s2         
@ @ @ @ @r/   r   )	metaclassc                   V    e Zd ZdZed
d            Zed             Zd ZddZdd	Z	dS )r   z
    Wrapper for RSA keys based on _EncryptAndVerifyRSA from crypto/pkcs1.py
    Use the 'key' attribute to access original object.
    Nc                 @   |pd}|sp|pd}|dk     r)t           s"t          j                            ||          }n#t          j        ||t	                                }|                                | _        not          t          |                    }|r||k    rt          d           t          j
        ||          }|                    t	                                | _        | j                                        }|| _        |j        | _        |j        | _        d S )Nr          r!   r"   r#   backend$modulus and modulusLen do not match!ne)_RSA_512_SUPPORTEDr$   r   generate_private_keyr   
public_keyr   r5   r   r   RSAPublicNumberspublic_numbers_modulusLenr   _modulusr   _pubExp)rX   modulus
modulusLenpubExpreal_modulusLenprivate_keypubNums          r-   r   zPubKeyRSA.fill_and_store  s+   5 	?(0DO%%.@%*.CC$*, D  
 "6$*,+--  
 &0022DKK!''"2"233O @o;;>???)Gv>>>F ++O,=,=>>DK++--*xr/   c                    |\  }}}t          |t                    rt          |          }t          |t                    rt          |          }|                     ||           | j                            t          j        j        t          j	        j
                  | _        t          | j                  | _        d S )Nr   r   )encodingformat)r   bytesr   r   r   public_bytesr   Encodingre   PublicFormatSubjectPublicKeyInforW   rH   rV   )rX   tupr   mmLens        r-   r   zPubKeyRSA.import_from_tuple=  s     
1da 	1Aa 	1AAa000;++"+/ -B , D D 48$$r/   c                 d    |j         j        }|j        j        }|                     ||           d S )Nr   )r   r   publicExponentr   )rX   r   r   r   s       r-   r   zPubKeyRSA.import_from_asn1pktK  s6    .$&*GF;;;;;r/   r   sha256c                 6    t          j        | |||||          S N)r   r   mgfL)r   encryptrX   msgr   r   r   r   s         r-   r   zPubKeyRSA.encryptP  s     #+D#aSANNNNr/   c           	      8    t          j        | ||||||          S r   r   r   rX   r   sigr   r   r   r   s          r-   r   zPubKeyRSA.verifyT  s+    #*#sa1#4 4 4 	4r/   )NNNr   r   NN)
r]   r^   r_   r   r   r   r   r   r   r   r)   r/   r-   r   r     s                 : % % %< < <
O O O O4 4 4 4 4 4r/   r   c                   `    e Zd ZdZedd            Zed             Zd	dZed	d            ZdS )
r   zz
    Wrapper for ECDSA keys based on the cryptography library.
    Use the 'key' attribute to access original object.
    Nc                     |pt           j        }t          j         |            t                                }|                                | _        d S rT   )r   	SECP256R1r   r   r   r   rX   curver   s      r-   r   zPubKeyECDSA.fill_and_store^  sC    %-eegg7H7HII!,,..r/   c                 T    t          j        |t                                | _        d S N)r   r   load_der_public_keyr   r   rX   r   s     r-   r   zPubKeyECDSA.import_from_derd  s-     $7#%%
 
 
r/   r   c                      t          d          )NzNo ECDSA encryption supportrC   )rX   r   r   kwargss       r-   r   zPubKeyECDSA.encryptl      5666r/   c           	          	 | j                             ||t          j        t	          |                               dS # t
          $ r Y dS w xY wNTFr   r   r   ECDSAr   r   rX   r   r   r   r   s        r-   r   zPubKeyECDSA.verifyo  X    	KsC)A,,)?)?@@@4 	 	 	55	   ;? 
AArT   r   	r]   r^   r_   r   r   r   r   r   r   r)   r/   r-   r   r   Y  s          / / / /
 
 
 
7 7 7 7      r/   r   c                   \    e Zd ZdZedd            Zed             Zd Zed             ZdS )r   zz
    Wrapper for EdDSA keys based on the cryptography library.
    Use the 'key' attribute to access original object.
    Nc                 |    |pt           j        }|                                }|                                | _        d S rT   )r   X25519PrivateKeygenerater   r   r   s      r-   r   zPubKeyEdDSA.fill_and_store~  s5    00nn&&!,,..r/   c                 T    t          j        |t                                | _        d S r   r   r   s     r-   r   zPubKeyEdDSA.import_from_der  s+    #7#%%
 
 
r/   c                      t          d          )NzNo EdDSA encryption supportr   )rX   r   r   s      r-   r   zPubKeyEdDSA.encrypt  r   r/   c                 `    	 | j                             ||           dS # t          $ r Y dS w xY wr   r   r   r   rX   r   r   r   s       r-   r   zPubKeyEdDSA.verify  F    	KsC(((4 	 	 	55	    
--rT   r   r)   r/   r-   r   r   y  s          / / / /
 
 
 
7 7 7     r/   r   c                       e Zd ZdZ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                    |Nt                               |           }| t          u rt          } | |_        d|_        |                                 |S t                              | |t                    }d}	 t          |j
                  }|j        }t          |_        d}n# t          $ r 	 t          |j
                  }|j        }t          |_        d}d}n# t          $ r 	 t          |j
                  }t          |_        d}n# t          $ rx 	 t!          |j
                  }t          |_        d}nQ# t          $ rD 	 t#          |j
                  }t$          |_        d}n# t          $ r t          d          w xY wY nw xY wY nw xY wY nw xY wY nw xY w	 |                    |           n# t(          $ r Y nw xY w|j        d	k    r?|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.
        Nr}   Fs   PRIVATE KEYs   EC PRIVATE KEYTs   RSA PRIVATE KEYzUnable to import private keyrf   )r   ry   PrivKeyPrivKeyECDSAr   rU   r   ra   r   r   rV   
privateKey
PrivKeyRSArC   r	   r   r
   r   PrivKeyEdDSAr   ImportErrorr;   r   rW   )ro   r   r8   multiPEMprivkeyr   s         r-   ry   z_PrivKeyFactory.__call__  si    --$$Cg~~"CM!CH   J##C=AA	L+CG44G(G&CM#FF 	L 	L 	LL1#'::!, ,* L L LL+CG44G$.CM/FF  L L L
L"1#'":":(4!2$ L L LL&5cg&>&>G,8CM%3FF( L L L"+,J"K"KKL #F	LLL	L0	##G,,,, 	 	 	D	 8u 3!#g,,77!#'622
s   5)B 
F*+CF
F!"DF
F"D21F2
F 	="E F 	 E::F 	=F?F 	 FFFF	FFFFF, ,
F98F9rT   r   r)   r/   r-   r   r     s2         
; ; ; ; ; ;r/   r   c                       e Zd ZdZd ZeZdS )_Raw_ASN1_BIT_STRINGz+A ASN1_BIT_STRING that ignores BER encodingc                     | j         S rT   )val_readabler[   s    r-   	__bytes__z_Raw_ASN1_BIT_STRING.__bytes__  s      r/   N)r]   r^   r_   r   r  r\   r)   r/   r-   r
  r
    s(        55! ! !GGGr/   r
  c                   &    e Zd ZdZddZd Zd ZdS )r  zx
    Parent class for both PrivKeyRSA and PrivKeyECDSA.
    Provides common signTBSCert() and resignCert() methods.
    r   c                     |j         }|pt          |j        j                 }|                     t          |          |d          }t                      }||_        ||_        t          |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().
        r   r   T)readable)r   r   r   r   signr   r   r   signatureAlgorithmr
  r   )rX   r   r   r   r   cs         r-   signTBSCertzPrivKey.signTBSCert  sq     "2V-123w<<177KK"%/FFFr/   c                 :    |                      |j        d          S )z9 Rewrite the signature of either a Cert or an X509_Cert. N)r   )r  r   )rX   r   s     r-   
resignCertzPrivKey.resignCert  s     3t<<<r/   c                     |j         }|j        }t          |j        j                 }t          |j                  }|                     t          |          ||d          S r   r   r   s         r-   r   zPrivKey.verifyCert  r   r/   Nr   )r]   r^   r_   r   r  r  r   r)   r/   r-   r  r    sU         
   .= = =@ @ @ @ @r/   r  c                   F    e Zd ZdZe	 	 	 d	d            Zd Zd
dZ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
           	         |pd}d |||||	||fv r|pd}
|
dk     r.t           s't          j                            ||
          | _        n(t          j        ||
t                                | _        | j                                        | _        nt          t          |                    }
|r|
|k    rt          d           t          j        ||          }t          j        ||||||	|          }|                    t                                | _        | j                                        | _        | j                                        }|
| _        |j        | _        |j        | _        d S )	Nr    r   r   r!   r   r   r   )rx   qdmp1dmq1iqmpdr   )r   r$   r   r   keyr   r   r   r5   r   r   r   RSAPrivateNumbersr   r   r   r   r   r   r   )rX   r   r   r   prime1prime2coefficient	exponent1	exponent2privExpr   r   privNums                r-   r   zPrivKeyRSA.fill_and_store  s    5GVV['y* * *
 )0DO%%.@%'+@@$*, A  
 3$*,+--  
 (--//DKK!''"2"233O @o;;>???)Gv>>>F+f1:1<;AC C CG **?+<+<==DH(--//DK ++--*xr/   c           
          |j         j        }|j        j        }|j        j        }|j        j        }|j        j        }|j        j        }|j        j        }|j        j        }	| 	                    ||||||||	           d S )N)r   r   r&  r!  r"  r$  r%  r#  )
r   r   r   privateExponentr!  r"  r$  r%  r#  r   )
rX   r  r   r   r&  r!  r"  r$  r%  r#  s
             r-   r   zPrivKeyRSA.import_from_asn1pkt@  s    /%'+)-##%)	%)	)-GF$+F6&/9(3 	 	5 	5 	5 	5 	5r/   r   r   c           	      8    t          j        | ||||||          S r   r   r   s          r-   r   zPrivKeyRSA.verifyN  s+    #*#sa1#4 4 4 	4r/   c                 6    t          j        | |||||          S r   )r   r  )rX   datar   r   r   r   s         r-   r  zPrivKeyRSA.signS  s     !&tTQ!JJJJr/   )	NNNNNNNNNr   	r]   r^   r_   r   r   r   r   r   r  r)   r/   r-   r  r    s          CG=A?C'  '  '  ' R5 5 54 4 4 4
K K K K K Kr/   r  c                   p    e Zd ZdZedd            Zed             Zed	d            Ze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                     |pt           j        }t          j         |            t                                | _        | j                                        | _        d S rT   )r   r   r   r   r  r   r   rX   r   s     r-   r   zPrivKeyECDSA.fill_and_store\  sG    %*5577O4E4EFFh))++r/   c                     t          j        t          |          d t                                | _        | j                                        | _        d S r   r   load_der_private_keyr   r   r  r   r   rX   r  s     r-   r   z PrivKeyECDSA.import_from_asn1pktb  J     5c'llD>M>O>OQ Q Qh))++r/   r   c           	          	 | j                             ||t          j        t	          |                               dS # t
          $ r Y dS w xY wr   r   r   s        r-   r   zPrivKeyECDSA.verifyh  r   r   c                 v    | j                             |t          j        t	          |                              S rT   )r  r  r   r   r   )rX   r,  r   r   s       r-   r  zPrivKeyECDSA.signq  s(    x}}T28IaLL#9#9:::r/   rT   r   r-  r)   r/   r-   r  r  W  s          , , , ,
 , , ,
     ; ; ; ; ; ;r/   r  c                   l    e Zd ZdZedd            Zed             Zed             Zed             ZdS )r  zW
    Wrapper for EdDSA keys
    Use the 'key' attribute to access original object.
    Nc                     |pt           j        }|                                | _        | j                                        | _        d S rT   )r   r   r   r  r   r   r0  s     r-   r   zPrivKeyEdDSA.fill_and_store{  s9    00>>##h))++r/   c                     t          j        t          |          d t                                | _        | j                                        | _        d S r   r2  r4  s     r-   r   z PrivKeyEdDSA.import_from_asn1pkt  r5  r/   c                 `    	 | j                             ||           dS # t          $ r Y dS w xY wr   r   r   s       r-   r   zPrivKeyEdDSA.verify  r   r   c                 6    | j                             |          S rT   )r  r  )rX   r,  r   s      r-   r  zPrivKeyEdDSA.sign  s    x}}T"""r/   rT   r-  r)   r/   r-   r  r  v  s          , , , ,
 , , ,
    # # # # #r/   r  c                       e Zd ZdZ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                    t                               | |t          d          }t          |_        	 t          |j                  }n*# t          $ r t          j	        r t          d          w xY w|
                    |           |S )NCERTIFICATEUnable to import certificate)ra   ry   _MAX_CERT_SIZECertr   r   rV   rC   r   r   r   )ro   	cert_pathr8   r   s       r-   ry   z_CertMaker.__call__  s    ##C$2MC C	<SW%%DD 	< 	< 	<# :;;;	< 	%%%
s   A 'A,Nr   r)   r/   r-   r>  r>    s-             r/   r>  c                   V    e Zd ZdZd Zd Zd ZddZdd	Zdd
Z	d Z
ddZd Zd ZdS )rC  zt
    Wrapper for the X509_Cert from layers/x509.py.
    Use the 'x509Cert' attribute to access original object.
    c                 J   d}|| _         |j        }|| _        |j        r|j        j        dz   | _        nd| _        |j        j        | _        |j        j        j        | _	        |
                                | _        |                                | _        t          | j                  | _        |                                | _        |                                | _        t          | j                  | _        d | _        |j        j        j        | _        	 |j        j        j                                        | _        n# t:          $ r t=          |          w xY wt?          j         d| j                  | _!        |j        j"        j        | _#        	 |j        j"        j                                        | _$        n# t:          $ r t=          |          w xY wt?          j         d| j$                  | _%        tM          tO          |j(                            | _)        |j*        r|j*        D ]}|j+        j        dk    r/d| _,        |j-        j,        r|j-        j,        j        dk     | _,        A|j+        j        dk    r|j-        .                                | _/        p|j+        j        dk    r|j-        0                                | _1        |j+        j        d	k    r|j-        j2        j        | _        tO          |j3                  | _3        ti          | j3                  | _5        d S )
NrA  rJ   %xbasicConstraintsFr   keyUsageextKeyUsageauthorityKeyIdentifier)6x509Certr   versionr   serialNumberserialr   r   oidnamer   
get_issuerissuerget_issuer_str
issuer_strhashissuer_hashget_subjectsubjectget_subject_strsubject_strsubject_hashauthorityKeyIDvalidity
not_beforepretty_timenotBefore_strdatetime	timetuple	notBefore
ValueErrorrC   timestrftimenotBefore_str_simple	not_afternotAfter_strnotAfternotAfter_str_simpler   r   subjectPublicKeyInfopubKey
extensionsextnIDcA	extnValueget_keyUsagerI  get_extendedKeyUsagerJ  keyIdentifierr   r5   signatureLen)rX   r   rs   r   extns        r-   r   zCert.import_from_asn1pkt  s   2	%%? 	"?.2DLLDL*.'19((**!002200**,,"2244 !122"$-8D	'$-8AKKMMDNN 	' 	' 	'I&&&	'$(M$$G$G!#,6B	'#,6?IIKKDMM 	' 	' 	'I&&&	'#'=t}#E#E S!=>>?? 	K* 
K 
K;&*<<<#DG~( C'+~'8'<'A"B[(J66$(N$?$?$A$ADMM[(M99'+~'J'J'L'LD$$[(,DDD*..*F*JD'!$"566 344s   (D? ?E(F; ;Gc                 Z    | 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rV  r[  rm  r   rX   others     r-   isIssuerCertzCert.isIssuerCert  s0     u1115|&&t,,,r/   c                 P    | 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)rV  r[  r{  r[   s    r-   isSelfSignedzCert.isSelfSigned  s.     t000$$T***ur/   r   r   Nc                 @    | j                             |||||          S r   )rm  r   r   s         r-   r   zCert.encrypt  s#    {""3!qcQ"???r/   c                 B    | j                             ||||||          S r   )rm  r   r   s          r-   r   zCert.verify   s%    {!!#sa1#!CCCr/   c                    |t          j                    }nxt          |t                    rc	 d|v rt          j        |d          }nt          j        |d          }n2# t
          $ r% t          d           t          j                    }Y nw xY wt          j        |          }t          j        | j                  }||z
  dz  }|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     @)	re  	localtimer   strstrptimerC   r   mktimerj  )rX   nownftdiffs       r-   remainingDayszCert.remainingDays  s    ( ;.""CCS!! 	''#::-Z88CC--CDDC ' ' 'QRRRn&&' k#k$-((c	j)s   /A ,BBc                     |D ]d}| j         1|j         *| j         |j         k    r| j        d |j        D             v c S | j        |j        k    r| j        d |j        D             v c S ed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              3   &   K   | ]}|d          V  dS r   Nr)   r*   xs     r-   	<genexpr>z!Cert.isRevoked.<locals>.<genexpr><  &      &L&Lqt&L&L&L&L&L&Lr/   c              3   &   K   | ]}|d          V  dS r  r)   r  s     r-   r  z!Cert.isRevoked.<locals>.<genexpr>>  r  r/   F)r\  rO  revoked_cert_serialsrR  )rX   crl_listr  s      r-   	isRevokedzCert.isRevoked(  s       	M 	MA#/ ,'1+;;;{&L&LQ5K&L&L&LLLLL(({&L&LQ5K&L&L&LLLLL )ur/   rf   c                     t          |d          5 }|dk    r|                    | j                   n |dk    r|                    | j                   ddd           dS # 1 swxY w Y   dS )zT
        Export certificate in 'fmt' format (DER or PEM) to file 'filename'
        wbrf   re   N)rl   writerV   rW   )rX   filenamefmtru   s       r-   exportzCert.exportA  s     (D!! 	"Qe||!!!!!!!		" 	" 	" 	" 	" 	" 	" 	" 	" 	" 	" 	" 	" 	" 	" 	" 	" 	"s   AA  A$'A$c                     t          d| j        z             t          d| j        z              t          d| j        z              t          d| j        d| j                   d S )Nz
Serial: %sIssuer: z	Subject: z
Validity: z to )printrO  rT  rZ  r`  ri  r[   s    r-   showz	Cert.showK  sl    lT[()))j4?*+++kD,,---d&8&8&8$:K:KLMMMMMr/   c                 (    d| j         d| j        dS )Nz[X.509 Cert. Subject:z	, Issuer:])rZ  rT  r[   s    r-   __repr__zCert.__repr__Q  s     8<8H8H8H$///ZZr/   r   rT   )rf   )r]   r^   r_   r   r   r{  r}  r   r   r  r  r  r  r  r)   r/   r-   rC  rC    s         
45 45 45l- - -  @ @ @ @D D D D# # # #J  2" " " "N N N[ [ [ [ [r/   rC  c                       e Zd ZdZ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                     t                               | |t          d          }t          |_        	 t          |j                  }n# t          $ r t          d          w xY w|                    |           |S )NzX509 CRLUnable to import CRL)	ra   ry   _MAX_CRL_SIZECRLr   r   rV   rC   r   )ro   rD  r8   crls       r-   ry   z_CRLMaker.__call__^  s{    ##CM:NN	437##CC 	4 	4 	42333	4$$$
s   A ANr   r)   r/   r-   r  r  Y  s-             r/   r  c                   *    e Zd ZdZd Zd Zd Zd ZdS )r  zr
    Wrapper for the X509_CRL from layers/x509.py.
    Use the 'x509CRL' attribute to access original object.
    c                    d}|| _         |j        }t          |          | _        |j        r|j        j        dz   | _        nd| _        |j        j        j        | _        |	                                | _
        |                                | _        t          | j                  | _        |j        j        | _        |j        j        }|d         dk    r
|d d         }	 t%          j        |d          | _        n# t*          $ r t+          |          w xY wt%          j        d| j                  | _        d | _        d | _        |j        r|j        j        | _        |j        j        }|d         dk    r
|d d         }	 t%          j        |d          | _        n# t*          $ r t+          |          w xY wt%          j        d| j                  | _        |j        r0|j        D ](}|j        j        dk    r|j        j        j        | _         )g }|j!        r|j!        D ]{}|j"        j        }	|j#        j        }
|
d         dk    r
|
d d         }
	 t%          j        |
d           n# t*          $ r t+          |          w xY w|$                    |	|
f           ||| _%        t          |j&                  | _&        tO          | j&                  | _(        d S )Nr  rJ   r@   Zz%y%m%d%H%M%SrG  	cRLNumber))x509CRLtbsCertListr   rM  r   r   r   rP  r   rQ  rR  rS  rT  rU  rV  this_updater_  lastUpdate_strre  r  
lastUpdaterC   rf  lastUpdate_str_simple
nextUpdatenextUpdate_str_simplenext_updatenextUpdate_strcrlExtensionsro  rq  r  numberrevokedCertificatesrN  revocationDaterK   r  r   r5   ru  )rX   r  rs   r  r  r  	extensionrevokedr   rO  dates              r-   r   zCRL.import_from_asn1pkto  s   *	o{++ 	&.2Q6DLLDL!+5=!,,..%446600)5A ,0
b>S  #CRCJ	'"mJGGDOO 	' 	' 	'I&&&	'%)]4%I%I"%)"" 		N"-"9"ED$04J"~$$'_
+"&-
N"K"K + + +	***+)-tT_)M)MD&$ 	D(6 D D	#+{::"+"5"?"CDK* 
	/#7 	/ 	/*.*.8s??9D/M$7777  / / /#I.../~....$+!!#"455 344s$   C8 8D=F F2I""I<c                 Z    | j         |j        k    rdS |j                            |           S )NFrx  ry  s     r-   r{  zCRL.isIssuerCert  s.    u1115|&&t,,,r/   c                 :     t           fd|D                       S )Nc              3   B   K   | ]}                     |          V  d S rT   )r{  )r*   arX   s     r-   r  zCRL.verify.<locals>.<genexpr>  s1      99A4$$Q''999999r/   )any)rX   anchorss   ` r-   r   z
CRL.verify  s&    9999999999r/   c                     t          d| j        z             t          d| j        z              t          d| j        z              t          d| j        z             t          d| j        z             d S )NzVersion: %dzsigAlg: r  zlastUpdate: %sznextUpdate: %s)r  rM  r   rT  r  r  r[   s    r-   r  zCRL.show  su    mdl*+++j4;&'''j4?*+++!44555!4455555r/   N)r]   r^   r_   r   r   r{  r   r  r)   r/   r-   r  r  i  s[         
<5 <5 <5|- - -: : :6 6 6 6 6r/   r  c                   8    e Zd ZdZddZddZddZddZd ZdS )	Chainz/
    Basically, an enhanced array of Cert.
    Nc                    t                               | d           |r|                     |           nE|D ]B}|                                r,|                     |           |                    |            nCt          |           dk    rv|rvt          |           }|D ]I}|                    | d                   r,|                     |           |                    |            nJt          |           |k    rdS |rdS dS d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   r@   N)listrY   rK   r}  remover5   r{  )rX   certListcert0root_candidatetmp_lenr  s         r-   rY   zChain.__init__  s9    	dB 	KK"*  !..00 KK///OON333E
 t99q== 	d))!  A~~d2h// A *** t99''E  	 	 	 =	 	r/   c                     |pg }|D ]q}t          | |z   |          t                    dk    r)t          fd| D                       r-D ]}|                                dk     r n|d         u rc S rd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.
        rJ   c              3   0   K   | ]}|d d         v V  dS )rJ   Nr)   )r*   r  chains     r-   r  z$Chain.verifyChain.<locals>.<genexpr>  s/      00a1abb	>000000r/   r   r@   N)r  r5   r  r  )rX   r  	untrustedr  r  r  s        @r-   verifyChainzChain.verifyChain  s     O	 
	! 
	!A$*A..E5zzQ0000400000 !  A((1,, -b	>> LLLtr/   c                    	 t          |d          5 }|                                }ddd           n# 1 swxY w Y   n# t          $ r t          d          w xY wd t          |          D             }d}|rt	 t          |d          5 }|                                }ddd           n# 1 swxY w Y   n# t          $ r t          d          w xY w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).
        rd   NzCould not read from cafilec                 ,    g | ]}t          |          S r)   rC  r*   r  s     r-   r.   z/Chain.verifyChainFromCAFile.<locals>.<listcomp>  s    888q477888r/   "Could not read from untrusted_filec                 ,    g | ]}t          |          S r)   r  r  s     r-   r.   z/Chain.verifyChainFromCAFile.<locals>.<listcomp>      EEEQaEEEr/   )rl   rm   rC   rP   r  )rX   cafileuntrusted_fileru   ca_certsr  r  untrusted_certss           r-   verifyChainFromCAFilezChain.verifyChainFromCAFile  s   	:fd## $q6688$ $ $ $ $ $ $ $ $ $ $ $ $ $ $ 	: 	: 	:8999	: 98Ih$7$7888	 	FF.$// /1&'ffhhO/ / / / / / / / / / / / / / / F F F DEEEFEE)O*D*DEEEI333sQ   ? 3? 7? 7? A:B7 
B+B7 +B//B7 2B/3B7 7Cc                    	 g }t          j        |          D ]|}t          t           j                            ||          d          5 }|                    t          |                                                     ddd           n# 1 swxY w Y   }n# t          $ r t          d          w xY wd}|rt	 t          |d          5 }|                                }ddd           n# 1 swxY w Y   n# t          $ r t          d          w xY w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).
        rd   Nz(capath provided is not a valid cert pathr  c                 ,    g | ]}t          |          S r)   r  r  s     r-   r.   z/Chain.verifyChainFromCAPath.<locals>.<listcomp>2  r  r/   )rh   listdirrl   ri   r6   rK   rC  rm   rC   rP   r  )	rX   capathr  r  r  fdr  ru   r  s	            r-   verifyChainFromCAPathzChain.verifyChainFromCAPath  s   	HG*V,, 4 4"',,vv66== 4NN4		??3334 4 4 4 4 4 4 4 4 4 4 4 4 4 44  	H 	H 	HFGGG	H 	 	FF.$// /1&'ffhhO/ / / / / / / / / / / / / / / F F F DEEEFEE)O*D*DEEEI333s`   AB 5B	=B 	B	B B	B B08C5 C)C5 )C--C5 0C-1C5 5Dc                 "   t          |           dz
  }|dk     rdS | d         }d}|                                s|d|j        z  z  }n|d|j        z  z  }d}||k    r3| |         }|d|z  dz  d	|j        z  }||k    r|d
z  }|dz  }||k    3|S )NrJ   r   rg   z__ z%s [Not Self Signed]
z%s [Self Signed]
    z_ 
)r5   r}  rZ  )rX   llenr  rL   idxs        r-   r  zChain.__repr__6  s    4yy1}!882G~~ 	6)AM99AA%55ATkkS	AS3Y]]]AMM::Ad{{T	1HC Tkk r/   rT   )	r]   r^   r_   r   rY   r  r  r  r  r)   r/   r-   r  r    s~         " " " "H   ,4 4 4 424 4 4 46    r/   r  )r%   )Pr   r2   rh   re  scapy.configr   r   scapy.errorr   scapy.utilsr   scapy.asn1.asn1r   scapy.asn1.mibr   scapy.layers.x509r	   r
   r   r   r   r   r   r   r   r   r   scapy.layers.tls.crypto.pkcs1r   r   r   r   scapy.compatr   r   crypto_validcryptography.exceptionsr   cryptography.hazmat.backendsr   cryptography.hazmat.primitivesr   )cryptography.hazmat.primitives.asymmetricr   r   r   r   r   rd  -cryptography.hazmat.primitives.asymmetric.rsar$   r   rB  r  commandsregisterr;   rH   rP   objectrR   r   ra   r{   r   r   r   r   r   r
  r  r  r  r  r>  rC  r  r  r  r  r)   r/   r-   <module>r     s   ,  				  / / / / / / / /             + + + + + + & & & & & &                         - - - - - - - - - - - - * * * * * * * * O888888<<<<<<<<<<<<IIIIIIIIIIO  EEEE! O O O"NNNNNNNNO           *
 
 
 
 
f 
 
 
, , , , ,4 , , ,n< < < < <\ < < <~@ @ @ @ @~ @ @ @ @<4 <4 <4 <4 <4, <4 <4 <4~    &   @    &   FA A A A Al A A AH    ?   '@ '@ '@ '@ '@ '@ '@ '@ '@TCK CK CK CK CK.0B CK CK CKL; ; ; ; ;7 ; ; ;># # # # #7 # # #F       &f[ f[ f[ f[ f[Z f[ f[ f[ f[Z        S6 S6 S6 S6 S6I S6 S6 S6 S6tD D D D DD D D D D Ds   B B&%B&