
    x@                     >   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ej                  j                         Z G 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!e!jE                         D  ci c]  \  } }|| 
 c}} Z#d Z$d Z%d Z&d3dZ'd3dZ(d Z)d Z*d Z+d  Z,d! Z-d" Z.d# Z/d$ Z0d% Z1d& Z2d' Z3d4d(Z4d4d)Z5d* Z6	 	 dd+l7m8Z8m9Z9m:Z:m;Z;m<Z< dd,l=m>Z?mZ@ dd-lAmBZBmCZC dd.lDmEZE e5ZKe4ZLd/ZM	 ddlNZNddlOZNddlPZNddlQZNd/ZR G d0 d1eS      ZTyc c}} w # eF$ r' dd+lGm8Z8m9Z9m:Z:m;Z;m<Z< dd,lHm>Z?mZ@ dd-lImBZBmCZC dd.lJmEZE Y Vw xY w# eF$ r d2ZRY yw xY w# eF$ r e6ZKe6ZLd2ZMd2ZRY yw xY w)5z.Common DNSSEC-related functions and constants.    )BytesION   )string_typesc                       e Zd ZdZy)UnsupportedAlgorithmz&The DNSSEC algorithm is not supported.N__name__
__module____qualname____doc__     lib/third_party/dns/dnssec.pyr   r   "   s    0r   r   c                       e Zd ZdZy)ValidationFailurez The DNSSEC signature is invalid.Nr   r   r   r   r   r   &   s    *r   r                        
                  )RSAMD5DHDSAECCRSASHA1DSANSEC3SHA1RSASHA1NSEC3SHA1	RSASHA256	RSASHA512INDIRECTECDSAP256SHA256ECDSAP384SHA384
PRIVATEDNS
PRIVATEOIDc                 f    t         j                  | j                               }|t        |       }|S )zIConvert text into a DNSSEC algorithm value.

    Returns an ``int``.
    )_algorithm_by_textgetupperint)textvalues     r   algorithm_from_textr4   _   s-     ""4::<0E}D	Lr   c                 J    t         j                  |       }|t        |       }|S )zEConvert a DNSSEC algorithm value to text

    Returns a ``str``.
    )_algorithm_by_valuer/   str)r3   r2   s     r   algorithm_to_textr8   k   s'     ""5)D|5zKr   c                 \    t               }| j                  ||       |j                         S )N)origin)r   to_wiregetvalue)recordr:   ss      r   	_to_rdatar?   w   s%    	A
NN1VN$::<r   c                 R   t        | |      }t        |      }| j                  t        k(  r|d   dz  |d   z   S d}t	        t        |      dz        D ]  }||d|z     dz  |d|z  dz      z   z  } t        |      dz  dk7  r||t        |      dz
     dz  z  }||dz	  dz  z  }|dz  S )	zReturn 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      i  )r?   	bytearray	algorithmr   rangelen)keyr:   rdatatotalis        r   key_idrL   }   s     c6"EeE
}}b	Q%)++s5zQ'AeAEla'a!eai ! !E ( u:>QU3u:>*a//E5B;&()v~r   c           	         |j                         dk(  rd}t        j                         }n8|j                         dk(  rd}t        j                         }nt	        d|z        t        | t              r t        j                  j                  | |      } |j                  | j                         j                                |j                  t        ||             |j                         }t        j                   dt#        |      |j$                  |      |z   }t        j&                  j)                  t        j*                  j,                  t        j.                  j0                  |dt3        |            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   )r0   rN   newrO   r   
isinstancer   dnsname	from_textupdatecanonicalizer;   r?   digeststructpackrL   rE   rI   	from_wire
rdataclassIN	rdatatypeDSrG   )rS   rH   rE   r:   dsalghashrW   dsrdatas           r   make_dsrb      s
   " F"xxz		h	&zz|"#?)#KLL$%xx!!$/KK!!#++-.KK	#v&'[[]Fkk&&+s}}eDvMG99s~~00#--2B2BGQ"7|- -r   c                    g }| j                  |j                        }|y t        |t        j                  j
                        rD	 |j                  t        j                  j                  t        j                  j                        }n|}|D ]F  }|j                  |j                  k(  st        |      |j                  k(  s6|j                  |       H |S # t        $ r Y y w xY wN)r/   signerrQ   rR   nodeNodefind_rdatasetr[   r\   r]   DNSKEYKeyErrorrE   rL   key_tagappend)keysrrsigcandidate_keysr3   rdatasetrI   s         r   _find_candidate_keysrq      s    NHHU\\"E}%'	**3>>+<+<+.==+?+?AH
 ??eoo-u.!!%(    		s   AC 	C$#C$c                 <    | t         t        t        t        t        fv S rd   )r   r#   r%   r&   r'   rE   s    r   _is_rsart      s     )9"$ $ $r   c                     | t         t        fv S rd   )r!   r$   rs   s    r   _is_dsarv      s    l+++r   c                 .    t         xr | t        t        fv S rd   )_have_ecdsar)   r*   rs   s    r   	_is_ecdsary      s    LI/?)KKLr   c                     | t         k(  S rd   )r   rs   s    r   _is_md5r{      s    r   c                 2    | t         t        t        t        fv S rd   )r!   r#   r$   r%   rs   s    r   _is_sha1r}      s    g%'79 9 9r   c                     | t         t        fv S rd   )r&   r)   rs   s    r   
_is_sha256r      s    O444r   c                     | t         k(  S rd   )r*   rs   s    r   
_is_sha384r      s    ''r   c                     | t         k(  S rd   )r'   rs   s    r   
_is_sha512r      s    	!!r   c                 T   t        |       rt        j                         S t        |       rt	        j                         S t        |       rt        j                         S t        |       rt        j                         S t        |       rt        j                         S t        d| z        )Nzunknown hash for algorithm %u)r{   MD5rP   r}   rN   r   rO   r   SHA384r   SHA512r   rs   s    r   
_make_hashr      sw    ywwy	xxz)zz|)zz|)zz|
;iG
HHr   c                 p   t        |       rg d}n>t        |       rg d}n.t        |       rg d}nt        |       rg d}nt	        d| z        t        |      }t        |       j                  }dgd|z   |z   gz   d|dz   gz   d	|gz   |z   d
dgz   d|gz   }t        j                  dt        |      z  g| S )N)*      H   r      r   r   r   )+   r   r   r      )	`   r   r   r   e   r   r   r   r   )	r   r   r   r   r   r   r   r   r   unknown algorithm %u0   r   r   r   r   r   z!%dB)
r{   r}   r   r   r   rG   r   digest_sizerX   rY   )rE   oidolendlenidbytess        r   _make_algorithm_idr      s    y>	)	,	I	D	I	D 6 BCCs8Di ,,DfD4((TAX"&.034Tl"D\*G ;;vG,7w77r   c           	         t        |t              r8t        j                  j	                  |t        j                  j
                        }t        ||      }|t        d      |D ]@  }t        | t              r| d   }| d   }n| j                  }| }|t        j                         }|j                  |k  rt        d      |j                  |kD  rt        d      t        |j                        }	t        |j                        r|j                  }
t!        j"                  d|
dd       \  }|
dd }
|dk(  r t!        j"                  d|
dd	       \  }|
d	d }
|
d| }|
|d }	 t%        j&                  t)        j*                  |      t)        j*                  |      f      }|j.                  }nt1        |j                        r|j                  }
t!        j"                  d|
dd       \  }|
dd }
d|dz  z   }|
dd }|
dd }
|
d| }|
|d }
|
d| }|
|d }
|
d| }t3        j&                  t)        j*                  |      t)        j*                  |      t)        j*                  |      t)        j*                  |      f      }|j.                  dd }nt5        |j                        r|j                  }
|j                  t6        k(  rt8        j:                  j<                  }d}n/|j                  t>        k(  rt8        j:                  j@                  }d}t)        j*                  |
d       }t)        j*                  |
||d	z         }t8        j8                  jC                  jD                  ||      st        d      t8        jF                  jI                  |jJ                  |||jL                        }t8        jN                  jP                  jS                  ||      }tU        ||      }|j.                  d| }|j.                  |d }t8        j8                  jW                  t)        j*                  |      t)        j*                  |            }nt        d|j                  z        |	jY                  t[        ||      dd        |	jY                  |j\                  j_                  |             |j`                  tc        |      dz
  k  rA|je                  |j`                  dz         d   }t        j                  j	                  d|      }|j_                  |      }t!        jf                  d|jh                  |jj                  |jl                        } to        |      }!|!D ]v  }"|	jY                  |       |	jY                  |        |"j_                  |      }#t!        jf                  dtc        |#            }$|	jY                  |$       |	jY                  |#       x 	 t        |j                        r)tq        jr                  |      }%|%ju                  |	|        yt1        |j                        r*tw        jr                  |d      }%|%ju                  |	|        yt5        |j                        r(|	jy                         }&|ju                  |&|      st,        t        d|j                  z         y t        d      # t,        $ r t        d
      w xY w# t,        $ r Y sw xY w)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   expiredznot yet validz!Bz!Hr   zinvalid public key@   r          r   zinvalid ECDSA keyr      *z!HHIz
fips-186-3zverify failure)=rQ   r   rR   rS   rT   rootrq   r   tupletime
expiration	inceptionr   rE   rt   rH   rX   unpack	CryptoRSA	constructnumberbytes_to_long
ValueError	signaturerv   	CryptoDSAry   r)   ecdsacurvesNIST256pr*   NIST384ppoint_is_valid	generatorellipticcurvePointcurveorderrm   VerifyingKeyfrom_public_pointECKeyWrapper	SignaturerU   r?   re   to_digestablelabelsrG   splitrY   rdtyperdclassoriginal_ttlsortedpkcs1_15rP   verifyDSSrW   )'rrsetrn   rm   r:   nowro   candidate_keyrrnamerp   r`   keyptrbytes_rsa_ersa_npubkeysigtoctetsdsa_qdsa_pdsa_gdsa_yr   key_lenxypointverifying_keyrr>   suffix	rrnamebufrrfixedrrlistrrrrdatarrlenverifierrW   s'                                          r   _validate_rrsigr     s   * &,'##FCHHMM:)$6N..' eU#1XFQxHZZFH;))+Cc!#I..??S #O44%//*5??#"&&FdF1QK8IVABZF{"MM$q<	1V$E67OE>",,))%0))%023
 //CU__%"&&F==va{3DQABZF!a%ZF1RLEBC[F1V$EFG_F1V$EFG_F1V$E((%%e,%%e,%%e,%%e,./F
 //!"%Cu' #&&F/1--O3--$$VAg%67A$$VGGaK%@AA;;--eooq!D'(;<<''--ekk1aME!JJ33EEeFKMM!-9F)A)A++''(<(<Q(?(.(<(<Q(?AC $$:U__$LMMIeV,Sb12ELL..v67<<#f+/)\\%,,"23A6FXX''V4F((0	++fhoox7G7G#002!BKK	"KK %%f-FKKc&k2EKKKK 	u'#<</c*  )776<8c*  5??+}}VS1$$
 ((>(PQQk (t ,
--u  >'(<==>l  		s+   !=Z3<[=[A[3[	[[c                    t        |t              r8t        j                  j	                  |t        j                  j
                        }t        | t              r| d   }n| j                  }t        |t              r|d   }|d   }n|j                  }|}|j                  |      }|j                  |      }||k7  rt        d      |D ]  }	 t        | ||||        y t        d      # t        $ r Y ,w xY w)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)
rQ   r   rR   rS   rT   r   r   choose_relativityr   r   )	r   rrsigsetrm   r:   r   r   	rrsignamerrsigrdatasetrn   s	            r   	_validater     s    & &,'##FCHHMM:%q(E"QK	 MM	 %%f-F++F3I :;;	E5$<  1
22 ! 		s   C))	C54C5c                      t        d      )Nz5DNSSEC validation requires pycryptodome/pycryptodomex)NotImplementedError)argskwargss     r   _need_pycryptor     s    
U
VVr   )r   rN   rO   r   r   )RSAr!   )r   r   )r   Tc                       e Zd Zd Zd Zy)r   c                      || _         || _        y rd   )rH   r   )selfrH   r   s      r   __init__zECKeyWrapper.__init__  s    &r   c                 x    t        j                  |      }| j                  j                  j	                  ||      S rd   )r   r   rH   r   verifies)r   rW   r   diglongs       r   r   zECKeyWrapper.verify  s-     ..v6xx//==r   N)r	   r
   r   r   r   r   r   r   r   r     s    '>r   r   Frd   )NN)Ur   ior   rX   r   dns.exceptionrR   dns.namedns.nodedns.rdataset	dns.rdatadns.rdatatypedns.rdataclass_compatr   	exceptionDNSExceptionr   r   r   r    r!   r"   r#   r$   r%   r&   r'   r)   r*   r(   r+   r,   r.   itemsr6   r4   r8   r?   rL   rb   rq   rt   rv   ry   r{   r}   r   r   r   r   r   r   r   r   Crypto.Hashr   rN   rO   r   r   Crypto.PublicKeyr   r   r   Crypto.Signaturer   r   Crypto.Utilr   ImportErrorCryptodome.HashCryptodome.PublicKeyCryptodome.SignatureCryptodome.Utilvalidatevalidate_rrsig_have_pycryptor   ecdsa.ecdsaecdsa.ellipticcurve
ecdsa.keysrx   objectr   )r   r   s   00r   <module>r     s  $ 5           !13==55 1+22 +
 

 		

 
 (&& * );(@(@(BC(B1q!t(BC 		0"-J($,M9
5("I8&V.r-3`W(>
+AAG2& H$NN>" 	>6 	>G DT  +EEK6*	+(    H#NNK	sB   1E
$E ,E? )E<9F ;E<<F ?F	F	FF