3
[_ð]x@  ã               @   sÔ  d Z ddlmZ ddlZddlZddlZddlZddlZddl	Zddl
ZddlZddlZddlmZ G dd„ dejjƒZG dd	„ d	ejjƒZdZd
ZdZdZdZdZdZdZdZdZdZdZdZdZ eeeeeeeeeeeeee dœZ!dd„ e!j"ƒ D ƒZ#dd„ Z$dd„ Z%dd„ Z&dHd d!„Z'dId"d#„Z(d$d%„ Z)d&d'„ Z*d(d)„ Z+d*d+„ Z,d,d-„ Z-d.d/„ Z.d0d1„ Z/d2d3„ Z0d4d5„ Z1d6d7„ Z2d8d9„ Z3dJd:d;„Z4dKd<d=„Z5d>d?„ Z6y°yLdd@l7m8Z8m9Z9m:Z:m;Z;m<Z< ddAl=m>Z?mZ@ ddBlAmBZBmCZC ddClDmEZE W n^ eFk
�rD   dd@lGm8Z8m9Z9m:Z:m;Z;m<Z< ddAlHm>Z?mZ@ ddBlImBZBmCZC ddClJmEZE Y nX W n& eFk
�rn   e6ZKe6ZLdDZMdDZNY nbX e5ZKe4ZLdEZMy$ddlOZOddlPZOddlQZOddlRZOW n eFk
�rº   dDZNY nX dEZNG dFdG„ dGeSƒZTdS )Lz.Common DNSSEC-related functions and constants.é    )ÚBytesIONé   )Ústring_typesc               @   s   e Zd ZdZdS )ÚUnsupportedAlgorithmz&The DNSSEC algorithm is not supported.N)Ú__name__Ú
__module__Ú__qualname__Ú__doc__© r
   r
   ú//tmp/pip-build-yz_zf6az/dnspython/dns/dnssec.pyr   "   s   r   c               @   s   e Zd ZdZdS )ÚValidationFailurez The DNSSEC signature is invalid.N)r   r   r   r	   r
   r
   r
   r   r   &   s   r   é   é   é   é   é   é   é   é
   é   é   éü   éý   éþ   )ÚRSAMD5ÚDHÚDSAÚECCÚRSASHA1ÚDSANSEC3SHA1ÚRSASHA1NSEC3SHA1Ú	RSASHA256Ú	RSASHA512ÚINDIRECTÚECDSAP256SHA256ÚECDSAP384SHA384Ú
PRIVATEDNSÚ
PRIVATEOIDc             C   s   i | ]\}}||“qS r
   r
   )Ú.0ÚxÚyr
   r
   r   ú
<dictcomp>\   s    r+   c             C   s"   t j| jƒ ƒ}|dkrt| ƒ}|S )zIConvert text into a DNSSEC algorithm value.

    Returns an ``int``.
    N)Ú_algorithm_by_textÚgetÚupperÚint)ÚtextÚvaluer
   r
   r   Úalgorithm_from_text_   s    r2   c             C   s   t j| ƒ}|dkrt| ƒ}|S )zEConvert a DNSSEC algorithm value to text

    Returns a ``str``.
    N)Ú_algorithm_by_valuer-   Ústr)r1   r0   r
   r
   r   Úalgorithm_to_textk   s    
r5   c             C   s   t ƒ }| j||d� |jƒ S )N)Úorigin)r   Úto_wireÚgetvalue)Úrecordr6   Úsr
   r
   r   Ú	_to_rdataw   s    r;   c             C   s¶   t | |ƒ}t|ƒ}| jtkr0|d	 d> |d
  S d}x<tt|ƒd ƒD ](}||d|  d> |d| d   7 }qFW t|ƒd dkrš||t|ƒd  d> 7 }||d? d@ 7 }|d@ S dS )zÃReturn the key id (a 16-bit number) for the specified key.

    Note the *origin* parameter of this function is historical and
    is not needed.

    Returns an ``int`` between 0 and 65535.
    r   r   r   r   r   é   iÿÿ  Néýÿÿÿéþÿÿÿ)r;   Ú	bytearrayÚ	algorithmr   ÚrangeÚlen)Úkeyr6   ÚrdataÚtotalÚir
   r
   r   Úkey_id}   s    	

rG   c             C   s¼   |j ƒ dkrd}tjƒ }n&|j ƒ dkr4d}tjƒ }ntd| ƒ‚t| tƒrXtjj	| |ƒ} |j
| jƒ jƒ ƒ |j
t||ƒƒ |jƒ }tjdt|ƒ|j|ƒ| }tjjtjjtjj|dt|ƒƒS )aÀ  Create a DS record for a DNSSEC key.

    *name* is the owner name of the DS record.

    *key* is a ``dns.rdtypes.ANY.DNSKEY``.

    *algorithm* is a string describing which hash algorithm to use.  The
    currently supported hashes are "SHA1" and "SHA256".  Case does not
    matter for these strings.

    *origin* is a ``dns.name.Name`` and will be used as the origin
    if *key* is a relative name.

    Returns a ``dns.rdtypes.ANY.DS``.
    ÚSHA1r   ÚSHA256r   zunsupported algorithm "%s"z!HBBr   )r.   rH   ÚnewrI   r   Ú
isinstancer   ÚdnsÚnameÚ	from_textÚupdateZcanonicalizer7   r;   ÚdigestÚstructÚpackrG   r@   rD   Z	from_wireÚ
rdataclassÚINÚ	rdatatypeZDSrB   )rM   rC   r@   r6   ZdsalgÚhashrP   Zdsrdatar
   r
   r   Úmake_ds•   s    


rW   c             C   s”   g }| j |jƒ}|d krd S t|tjjƒrZy|jtjjtj	j
ƒ}W q^ tk
rV   d S X n|}x0|D ](}|j|jkrdt|ƒ|jkrd|j|ƒ qdW |S )N)r-   ÚsignerrK   rL   ÚnodeÚNodeZfind_rdatasetrS   rT   rU   ZDNSKEYÚKeyErrorr@   rG   Zkey_tagÚappend)ÚkeysÚrrsigÚcandidate_keysr1   ÚrdatasetrD   r
   r
   r   Ú_find_candidate_keysº   s     

ra   c             C   s   | t ttttfkS )N)r   r   r    r!   r"   )r@   r
   r
   r   Ú_is_rsaÎ   s    rb   c             C   s   | t tfkS )N)r   r   )r@   r
   r
   r   Ú_is_dsaÔ   s    rc   c             C   s   t o| ttfkS )N)Ú_have_ecdsar$   r%   )r@   r
   r
   r   Ú	_is_ecdsaØ   s    re   c             C   s   | t kS )N)r   )r@   r
   r
   r   Ú_is_md5Ü   s    rf   c             C   s   | t tttfkS )N)r   r   r   r    )r@   r
   r
   r   Ú_is_sha1à   s    rg   c             C   s   | t tfkS )N)r!   r$   )r@   r
   r
   r   Ú
_is_sha256å   s    rh   c             C   s   | t kS )N)r%   )r@   r
   r
   r   Ú
_is_sha384é   s    ri   c             C   s   | t kS )N)r"   )r@   r
   r
   r   Ú
_is_sha512í   s    rj   c             C   s`   t | ƒrtjƒ S t| ƒr tjƒ S t| ƒr0tjƒ S t| ƒr@tjƒ S t	| ƒrPt
jƒ S td|  ƒ‚d S )Nzunknown hash for algorithm %u)rf   ÚMD5rJ   rg   rH   rh   rI   ri   ÚSHA384rj   ÚSHA512r   )r@   r
   r
   r   Ú
_make_hashñ   s    rn   c          	   C   sè   t | ƒrddddddddg}ndt| ƒr6dd	d
ddg}nLt| ƒrVdddddd
dddg	}n,t| ƒrvdddddd
ddd
g	}ntd|  ƒ‚t|ƒ}t| ƒj}dgd| | g d|d g d|g | ddg d|g }tj	dt|ƒ f|žŽ S )Né*   é†   éH   é÷   r   r   r   é+   r   r   é   é`   r   ée   r   zunknown algorithm %ué0   r   r   r   z!%dB)
rf   rg   rh   rj   r   rB   rn   Údigest_sizerQ   rR   )r@   ÚoidZolenÚdlenZidbytesr
   r
   r   Ú_make_algorithm_idÿ   s    
<r{   c       '      C   s¾  t |tƒrtjj|tjjƒ}t||ƒ}|dkr6tdƒ‚�xx|D �]n}t | tƒr`| d }| d }n
| j}| }|dkrzt	j	ƒ }|j
|k rŒtdƒ‚|j|kržtdƒ‚t|jƒ}	t|jƒ�rh|j}
tjd|
dd… ƒ\}|
dd… }
|dk�rtjd|
dd	… ƒ\}|
d	d… }
|
d|… }|
|d… }ytjtj|ƒtj|ƒfƒ}W n tk
�r\   td
ƒ‚Y nX |j}�nÎt|jƒ�r8|j}
tjd|
dd… ƒ\}|
dd… }
d|d  }|
dd… }|
dd… }
|
d|… }|
|d… }
|
d|… }|
|d… }
|
d|… }tjtj|ƒtj|ƒtj|ƒtj|ƒfƒ}|jdd… }� nþt|jƒ�r(|j}
|jtk�rdtjj}d}n|jtk�r|tjj }d}tj|
d|… ƒ}tj|
||d	 … ƒ}tjj!|j"||ƒ�sÀtdƒ‚tj#j$|j%|||j&ƒ}tj'j(j)||ƒ}t*||ƒ}|jd|… }|j|d… }tjj+tj|ƒtj|ƒƒ}ntd|j ƒ‚|	j,t-||ƒdd… ƒ |	j,|j.j/|ƒƒ |j0t1|ƒd k �r–|j2|j0d ƒd }tjjd|ƒ}|j/|ƒ}tj3d|j4|j5|j6ƒ} t7|ƒ}!xP|!D ]H}"|	j,|ƒ |	j,| ƒ |"j/|ƒ}#tj3dt1|#ƒƒ}$|	j,|$ƒ |	j,|#ƒ �qÄW y„t|jƒ�r6t8j9|ƒ}%|%j:|	|ƒ n\t|jƒ�r\t;j9|dƒ}%|%j:|	|ƒ n6t|jƒ�r„|	j<ƒ }&|j:|&|ƒ�s’t‚ntd|j ƒ‚dS  tk
�r¬   w>Y q>X q>W tdƒ‚dS )a  Validate an RRset against a single signature rdata

    The owner name of *rrsig* is assumed to be the same as the owner name
    of *rrset*.

    *rrset* is the RRset to validate.  It can be a ``dns.rrset.RRset`` or
    a ``(dns.name.Name, dns.rdataset.Rdataset)`` tuple.

    *rrsig* is a ``dns.rdata.Rdata``, the signature to validate.

    *keys* is the key dictionary, used to find the DNSKEY associated with
    a given name.  The dictionary is keyed by a ``dns.name.Name``, and has
    ``dns.node.Node`` or ``dns.rdataset.Rdataset`` values.

    *origin* is a ``dns.name.Name``, the origin to use for relative names.

    *now* is an ``int``, the time to use when validating the signatures,
    in seconds since the UNIX epoch.  The default is the current time.
    Nzunknown keyr   r   Zexpiredznot yet validz!Bz!Hr   zinvalid public keyé@   r   é   é    rw   zinvalid ECDSA keyzunknown algorithm %ué   Ú*z!HHIz
fips-186-3zverify failure)=rK   r   rL   rM   rN   Úrootra   r   ÚtupleÚtimeZ
expirationZ	inceptionrn   r@   rb   rC   rQ   ÚunpackÚ	CryptoRSAZ	constructÚnumberÚbytes_to_longÚ
ValueErrorÚ	signaturerc   Ú	CryptoDSAre   r$   ÚecdsaZcurvesZNIST256pr%   ZNIST384pZpoint_is_validÚ	generatorZellipticcurveZPointÚcurveÚorderr]   ZVerifyingKeyZfrom_public_pointÚECKeyWrapperÚ	SignaturerO   r;   rX   Zto_digestableÚlabelsrB   ÚsplitrR   ZrdtypeZrdclassZoriginal_ttlÚsortedÚpkcs1_15rJ   ÚverifyÚDSSrP   )'Úrrsetr^   r]   r6   Únowr_   Zcandidate_keyÚrrnamer`   rV   ZkeyptrÚbytes_Zrsa_eZrsa_nÚpubkeyÚsigÚtÚoctetsZdsa_qZdsa_pZdsa_gZdsa_yr�   Úkey_lenr)   r*   ZpointZverifying_keyÚrr:   ÚsuffixZ	rrnamebufZrrfixedZrrlistZrrZrrdataZrrlenZverifierrP   r
   r
   r   Ú_validate_rrsig  sÒ    

















r¢   c       	      C   sÄ   t |tƒrtjj|tjjƒ}t | tƒr0| d }n| j}t |tƒrR|d }|d }n
|j}|}|j|ƒ}|j|ƒ}||kr€tdƒ‚x6|D ].}yt	| ||||ƒ dS  tk
r²   Y q†X q†W tdƒ‚dS )aÜ  Validate an RRset.

    *rrset* is the RRset to validate.  It can be a ``dns.rrset.RRset`` or
    a ``(dns.name.Name, dns.rdataset.Rdataset)`` tuple.

    *rrsigset* is the signature RRset to be validated.  It can be a
    ``dns.rrset.RRset`` or a ``(dns.name.Name, dns.rdataset.Rdataset)`` tuple.

    *keys* is the key dictionary, used to find the DNSKEY associated with
    a given name.  The dictionary is keyed by a ``dns.name.Name``, and has
    ``dns.node.Node`` or ``dns.rdataset.Rdataset`` values.

    *origin* is a ``dns.name.Name``, the origin to use for relative names.

    *now* is an ``int``, the time to use when validating the signatures,
    in seconds since the UNIX epoch.  The default is the current time.
    r   r   zowner names do not matchNzno RRSIGs validated)
rK   r   rL   rM   rN   r�   r‚   Zchoose_relativityr   r¢   )	r—   Zrrsigsetr]   r6   r˜   r™   Z	rrsignameZrrsigrdatasetr^   r
   r
   r   Ú	_validate«  s*    








r£   c              O   s   t dƒ‚d S )Nz5DNSSEC validation requires pycryptodome/pycryptodomex)ÚNotImplementedError)ÚargsÚkwargsr
   r
   r   Ú_need_pycryptoÛ  s    r§   )rk   rH   rI   rl   rm   )ÚRSAr   )r”   r–   )r†   FTc               @   s   e Zd Zdd„ Zdd„ ZdS )r�   c             C   s   || _ || _d S )N)rC   rŸ   )ÚselfrC   rŸ   r
   r
   r   Ú__init__  s    zECKeyWrapper.__init__c             C   s   t j|ƒ}| jjj||ƒS )N)r†   r‡   rC   r›   Zverifies)r©   rP   rœ   Zdiglongr
   r
   r   r•     s    
zECKeyWrapper.verifyN)r   r   r   rª   r•   r
   r
   r
   r   r�   ÿ  s   r�   )N)N)NN)NN)Ur	   Úior   rQ   rƒ   Zdns.exceptionrL   Zdns.nameZdns.nodeZdns.rdatasetZ	dns.rdataZdns.rdatatypeZdns.rdataclassÚ_compatr   Ú	exceptionZDNSExceptionr   r   r   r   r   r   r   r   r    r!   r"   r$   r%   r#   r&   r'   r,   Úitemsr3   r2   r5   r;   rG   rW   ra   rb   rc   re   rf   rg   rh   ri   rj   rn   r{   r¢   r£   r§   ZCrypto.Hashrk   rH   rI   rl   rm   ZCrypto.PublicKeyr¨   r…   rŠ   ZCrypto.Signaturer”   r–   ZCrypto.Utilr†   ÚImportErrorZCryptodome.HashZCryptodome.PublicKeyZCryptodome.SignatureZCryptodome.UtilÚvalidateZvalidate_rrsigZ_have_pycryptord   r‹   Zecdsa.ecdsaZecdsa.ellipticcurveZ
ecdsa.keysÚobjectr�   r
   r
   r
   r   Ú<module>   s´   

%
 
0

