
    hA                        d 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ZddlZddlmZmZmZ ddlmZ dZdZdZdZd	Zd
Zej2                  j4                  j7                  dddddd      Zej2                  j4                  j9                  d      Zej2                  j4                  j7                  dd      Z G d de      Z G d de       Z! G d de!      Z"y)ag
  
Parsing for `Tor Ed25519 certificates
<https://gitweb.torproject.org/torspec.git/tree/cert-spec.txt>`_, which are
used to for a variety of purposes...

  * validating the key used to sign server descriptors
  * validating the key used to sign hidden service v3 descriptors
  * signing and encrypting hidden service v3 indroductory points

.. versionadded:: 1.6.0

**Module Overview:**

::

  Ed25519Certificate - Ed25519 signing key certificate
    | +- Ed25519CertificateV1 - version 1 Ed25519 certificate
    |      |- is_expired - checks if certificate is presently expired
    |      |- signing_key - certificate signing key
    |      +- validate - validates a descriptor's signature
    |
    |- from_base64 - decodes a base64 encoded certificate
    |- to_base64 - base64 encoding of this certificate
    |
    |- unpack - decodes a byte encoded certificate
    +- pack - byte encoding of this certificate

  Ed25519Extension - extension included within an Ed25519Certificate

.. data:: CertType (enum)

  Purpose of Ed25519 certificate. For more information see...

    * `cert-spec.txt <https://gitweb.torproject.org/torspec.git/tree/cert-spec.txt>`_ section A.1
    * `rend-spec-v3.txt <https://gitweb.torproject.org/torspec.git/tree/rend-spec-v3.txt>`_ appendix E

  .. deprecated:: 1.8.0
     Replaced with :data:`stem.client.datatype.CertType`

  ========================  ===========
  CertType                  Description
  ========================  ===========
  **SIGNING**               signing key with an identity key
  **LINK_CERT**             TLS link certificate signed with ed25519 signing key
  **AUTH**                  authentication key signed with ed25519 signing key
  **HS_V3_DESC_SIGNING**    hidden service v3 short-term descriptor signing key
  **HS_V3_INTRO_AUTH**      hidden service v3 introductory point authentication key
  **HS_V3_INTRO_ENCRYPT**   hidden service v3 introductory point encryption key
  ========================  ===========

.. data:: ExtensionType (enum)

  Recognized exception types.

  ====================  ===========
  ExtensionType         Description
  ====================  ===========
  **HAS_SIGNING_KEY**   includes key used to sign the certificate
  ====================  ===========

.. data:: ExtensionFlag (enum)

  Flags that can be assigned to Ed25519 certificate extensions.

  ======================  ===========
  ExtensionFlag           Description
  ======================  ===========
  **AFFECTS_VALIDATION**  extension affects whether the certificate is valid
  **UNKNOWN**             extension includes flags not yet recognized by stem
  ======================  ===========
    N)FieldSizesplit)CertType    (   @   s"   Tor router descriptor signature v1s#   Tor onion service descriptor sig v36   SIGNING	LINK_CERTAUTHHS_V3_DESC_SIGNINGHS_V3_INTRO_AUTHHS_V3_INTRO_ENCRYPT)HAS_SIGNING_KEY   AFFECTS_VALIDATIONUNKNOWNc                   2    e Zd ZdZd Zd Zed        Zd Zy)Ed25519Extensiona  
  Extension within an Ed25519 certificate.

  :var stem.descriptor.certificate.ExtensionType type: extension type
  :var list flags: extension attribute flags
  :var int flag_int: integer encoding of the extension attribute flags
  :var bytes data: data the extension concerns
  c                 |   || _         g | _        |r|nd| _        || _        |r6|dz  dk(  r.| j                  j	                  t
        j                         |dz  }|r)| j                  j	                  t
        j                         |t        j                  k(  r&t        |      dk7  rt        dt        |      z        y y )Nr         r   z?Ed25519 HAS_SIGNING_KEY extension must be 32 bytes, but was %i.)typeflagsflag_intdataappendExtensionFlagr   r   ExtensionTyper   len
ValueError)selfext_typeflag_valr   s       e/var/www/betterdocs.net/sherlock_api/venv/lib/python3.12/site-packages/stem/descriptor/certificate.py__init__zEd25519Extension.__init__   s    DIDJ (HaDMDIHqLA%
jj889!mh
jj--.=000SY"_X[^_c[ddee 6E0    c                 d   t               }|t        j                  j                  t	        | j
                              z  }|t        j                  j                  | j                        z  }|t        j                  j                  | j                        z  }|| j
                  z  }t        |      S N)
	bytearrayr   SHORTpackr!   r   CHARr   r   bytes)r#   encodeds     r&   r-   zEd25519Extension.pack   sv    kGtzzs499~..Gtyy~~dii((Gtyy~~dmm,,GtyyG>r(   c                    t        |       dk  rt        d      t        j                  j	                  |       \  }} t        j
                  j	                  |       \  }} t        j
                  j	                  |       \  }} t        | |      \  }} t        |      |k7  rt        d|t        |      fz        t        |||      | fS )Nr   z*Ed25519 extension is missing header fieldszTEd25519 extension is truncated. It should have %i bytes of data but there's only %i.)r!   r"   r   r,   popr.   r   r   )content	data_sizer$   r   r   s        r&   r2   zEd25519Extension.pop   s    
7|aCDD0Iw		g.HgYY]]7+NE7'9-MD'
4yImqz|  AE  }F  qG  G  H  HHeT2G;;r(   c                 J    t         j                  j                  | dddd      S )Nr   r   r   T)cache)stemutil
_hash_attrr#   s    r&   __hash__zEd25519Extension.__hash__   s"    99fj&$OOr(   N)	__name__
__module____qualname____doc__r'   r-   staticmethodr2   r;    r(   r&   r   r   v   s,    f  < <Pr(   r   c                   j    e Zd ZdZd Zed        Zed        Zd ZddZ	ed        Z
d Zed	        Zy
)Ed25519Certificatez
  Base class for an Ed25519 certificate.

  :var int version: certificate format version
  :var unicode encoded: base64 encoded ed25519 certificate
  c                      || _         d | _        y r*   )versionr0   )r#   rE   s     r&   r'   zEd25519Certificate.__init__   s    DLDLr(   c                     t         j                  j                  |       d   }|dk(  rt        j	                  |       S t        d|z        )a  
    Parses a byte encoded ED25519 certificate.

    :param bytes content: encoded certificate

    :returns: :class:`~stem.descriptor.certificate.Ed25519Certificate` subclsss
      for the given certificate

    :raises: **ValueError** if certificate is malformed
    r   r   zLEd25519 certificate is version %i. Parser presently only supports version 1.)r   r.   r2   Ed25519CertificateV1unpackr"   )r3   rE   s     r&   rH   zEd25519Certificate.unpack   sE     iimmG$Q'G!|!((11ehooppr(   c                    t         j                  j                  j                  |       } | j	                  d      r| j                  d      r| dd } 	 t        j                  |       }|st        d      t        j                  |      }| |_        |S # t        t        j                  f$ r}t        d|d|       d}~ww xY w)	a  
    Parses a base64 encoded ED25519 certificate.

    :param str content: base64 encoded certificate

    :returns: :class:`~stem.descriptor.certificate.Ed25519Certificate` subclsss
      for the given certificate

    :raises: **ValueError** if content is malformed
    z-----BEGIN ED25519 CERT-----
z
-----END ED25519 CERT-----   iemptyz5Ed25519 certificate wasn't propoerly base64 encoded (z):
N)r7   r8   	str_tools_to_unicode
startswithendswithbase64	b64decode	TypeErrorrC   rH   r0   binasciiErrorr"   )r3   decodedinstanceexcs       r&   from_base64zEd25519Certificate.from_base64   s     ii!!--g6G:;@P@PQo@p3g
i  )g  #**73h hox~~& iZ]_fghhis   ?B C+B<<Cc                 D    t        dt        |       j                  z        )z}
    Encoded byte representation of our certificate.

    :returns: **bytes** for our encoded certificate representation
    z4Certificate encoding has not been implemented for %s)NotImplementedErrorr   r<   r:   s    r&   r-   zEd25519Certificate.pack   s"     TW[\`WaWjWjj
kkr(   c                    dj                  t        j                  j                  j	                  t        j                  | j                               d            }|rd|z  }t        j                  j                  j                  |      S )a1  
    Base64 encoded certificate data.

    :param bool pem: include `PEM header/footer
      <https://en.wikipedia.org/wiki/Privacy-Enhanced_Mail>`_, for more
      information see `RFC 7468 <https://tools.ietf.org/html/rfc7468>`_

    :returns: **unicode** for our encoded certificate representation
       
r	   s:   -----BEGIN ED25519 CERT-----
%s
-----END ED25519 CERT-----)	joinr7   r8   rL   _split_by_lengthrP   	b64encoder-   rM   )r#   pemr0   s      r&   	to_base64zEd25519Certificate.to_base64   sd     jj,,==f>N>Ntyy{>[]_`aG
ORYYg99**733r(   c                       fd}|S )Nc                     |   d   \  }}}|r|dk7  rt        dd|      t        | t        j                  |             y )Nr   zED25519 CERT'z8' should be followed by a ED25519 CERT block, but was a )r"   setattrrC   rX   )
descriptorentriesvalue
block_typeblock_contents	attributekeywords        r&   _parsez3Ed25519Certificate._from_descriptor.<locals>._parse  sM    *1'*:1*='eZz^;\ceopqqj)%7%C%CN%STr(   rA   )rl   rk   rm   s   `` r&   _from_descriptorz#Ed25519Certificate._from_descriptor  s    U Mr(   c                 &    | j                  d      S )NT)r`   )ra   r:   s    r&   __str__zEd25519Certificate.__str__  s    >>>%%r(   c                 ,    t         j                  |       S r*   )rC   rX   )r3   s    r&   parsezEd25519Certificate.parse  s    ))'22r(   N)F)r<   r=   r>   r?   r'   r@   rH   rX   r-   ra   rn   rp   rr   rA   r(   r&   rC   rC      sp     q q& i i:l4$ 	 	& 3 3r(   rC   c                   b     e Zd ZdZd
 fd	Zd Zed        Zd Zd Z	d Z
ed        Zd	 Z xZS )rG   a  
  Version 1 Ed25519 certificate, which are used for signing tor server
  descriptors.

  :var stem.client.datatype.CertType type: certificate purpose
  :var int type_int: integer value of the certificate purpose
  :var datetime expiration: expiration of the certificate
  :var int key_type: format of the key
  :var bytes key: key content
  :var list extensions: :class:`~stem.descriptor.certificate.Ed25519Extension` in this certificate
  :var bytes signature: certificate signature

  :param bytes signature: pre-calculated certificate signature
  :param cryptography.hazmat.primitives.asymmetric.ed25519.Ed25519PrivateKey signing_key: certificate signing key
  c                    t         t        |   d       |t        d      |t        d      t	        j
                  |      \  | _        | _        |r|n8t        j                  j                         t        j                  t              z   | _        |r|nd| _        t        j                  j!                  |      | _        |r|ng | _        || _        |r]|j)                  | j+                               }| j&                  r+| j&                  |k7  rt        d|d| j&                  d      || _        | j                  t        j,                  t        j.                  t        j0                  fv rt        d| j                  z        | j                  t        j2                  k(  rt        d	      | j                  t        j4                  k(  rt        d
| j                  z        y )Nr   zCertificate type is requiredzCertificate key is required)hoursz#Signature calculated from its key (z) mismatches 'rd   zOEd25519 certificate cannot have a type of %i. This is reserved for CERTS cells.zcEd25519 certificate cannot have a type of 7. This is reserved for RSA identity cross-certification.z+Ed25519 certificate type %i is unrecognized)superrG   r'   r"   ClientCertTypegetr   type_intdatetimeutcnow	timedeltaDEFAULT_EXPIRATION_HOURS
expirationkey_typer7   r8   _pubkey_byteskey
extensions	signaturesignr-   LINKIDENTITYAUTHENTICATEED25519_IDENTITYr   )
r#   	cert_typer~   r   r   r   r   signing_keycalculated_sig	__class__s
            r&   r'   zEd25519CertificateV1.__init__)  s   	
.q1566	455-11)<DIt}$.jH4E4E4L4L4NQYQcQc  mE  RF  5FDO (HaDMyy&&s+DH$.jBDODN"''		4n 
DNNn<Uceiesestuu%dnyy^((.*A*A>C^C^__hkokxkxxyy	n55	5|}}	n,,	,Dt}}TUU 
-r(   c                    t               }|t        j                  j                  | j                        z  }|t        j                  j                  | j
                        z  }|t        j                  j                  t        t        j                  j                  | j                        dz              z  }|t        j                  j                  | j                        z  }|| j                  z  }|t        j                  j                  t        | j                              z  }| j                  D ]  }||j                         z  } | j                   r|| j                   z  }t#        |      S )N  )r+   r   r.   r-   rE   ry   LONGintr7   r8   datetime_to_unixr~   r   r   r!   r   r   r/   )r#   r0   	extensions      r&   r-   zEd25519CertificateV1.packI  s   kGtyy~~dll++Gtyy~~dmm,,Gtyy~~c$))"<"<T__"MPT"TUVVGtyy~~dmm,,GtxxGtyy~~c$//233G__ "	!!g" ~~g>r(   c                 b   t        |       t        t        z   k  r$t        dt        |       t        t        z   fz        t	        | t        |       t        z
        \  }}t
        j                  j                  |      \  }}t
        j                  j                  |      \  }}t
        j                  j                  |      \  }}t
        j                  j                  |      \  }}t	        |t              \  }}t
        j                  j                  |      \  }}	|dk7  rt        d|z        g }
t        |      D ]+  }t        j                  |	      \  }}	|
j                  |       - |	rt        dt        |	      z        t        |t        j                  j                  |dz        |||
|      S )Nz;Ed25519 certificate was %i bytes, but should be at least %ir   z5Ed25519 v1 parser cannot read version %i certificatesz9Ed25519 certificate had %i bytes of unused extension datar   )r!   ED25519_HEADER_LENGTHED25519_SIGNATURE_LENGTHr"   r   r   r.   r2   r   ED25519_KEY_LENGTHranger   r   rG   rz   utcfromtimestamp)r3   headerr   rE   r   expiration_hoursr   r   extension_countextension_datar   ir   s                r&   rH   zEd25519CertificateV1.unpackZ  s   
7|+.FFFTX[\cXdf{  W  gW  XX  X  Y  Ygs7|6N'NOFIiimmF+OGV		f-Iv#yy}}V4fyy}}V,Hf 23KC&*iimmF&;#O^!|NQXXYYJ?# #"2"6"6~"Fi	"# RUXYgUhhii	8+<+<+M+MN^aeNe+fhpru  xB  DM  N  Nr(   c                 X    t         j                   j                         | j                  kD  S )z
    Checks if this certificate is presently expired or not.

    :returns: **True** if the certificate has expired, **False** otherwise
    )rz   nowr~   r:   s    r&   
is_expiredzEd25519CertificateV1.is_expiredv  s"       "T__44r(   c                 |    | j                   D ]-  }|j                  t        j                  k(  s!|j                  c S  y)z
    Provides this certificate's signing key.

    .. versionadded:: 1.8.0

    :returns: **bytes** with the first signing key on the certificate, None if
      not present
    N)r   r   r    r   r   )r#   r   s     r&   r   z Ed25519CertificateV1.signing_key  s8     __ 		=88	8~~ r(   c                 x   t         j                  j                  d      st        d      t	        |t         j
                  j                  j                        r{t        j                  t        j                  |            j                         }t         j                  j                  j                  |j                         }| j#                  |       nt	        |t         j
                  j$                  j&                        rIt        j                  |      }t         j                  j                  j                  |j(                        }n!t+        dt-        |      j.                  z        ddlm} ddlm} 	 |j9                  | j:                        }|j=                  ||       y	# |$ r t?        d      w xY w)
a)  
    Validate our descriptor content matches its ed25519 signature. Supported
    descriptor types include...

      * :class:`~stem.descriptor.server_descriptor.RelayDescriptor`
      * :class:`~stem.descriptor.hidden_service.HiddenServiceDescriptorV3`

    :param stem.descriptor.__init__.Descriptor descriptor: descriptor to validate

    :raises:
      * **ValueError** if signing key or descriptor are invalid
      * **TypeError** if descriptor type is unsupported
      * **ImportError** if cryptography module or ed25519 support unavailable
    T)ed25519zKCertificate validation requires the cryptography module and ed25519 supportzWCertificate validation only supported for server and hidden service descriptors, not %sr   Ed25519PublicKeyInvalidSignaturezNDescriptor Ed25519 certificate signature invalid (signature forged or corrupt)N) r7   prereqis_crypto_availableImportError
isinstancerf   server_descriptorRelayDescriptorhashlibsha256rG   _signed_contentdigestr8   rL   _decode_b64ed25519_signature!_validate_server_desc_signing_keyhidden_serviceHiddenServiceDescriptorV3r   rR   r   r<   1cryptography.hazmat.primitives.asymmetric.ed25519r   cryptography.exceptionsr   from_public_bytesr   verifyr"   )r#   rf   signed_contentr   r   r   r   s          r&   validatezEd25519CertificateV1.validate  s\     ;;**T*:eff*doo??OOP~~&:&J&J:&VW^^`n))%%11*2N2NOi
,,Z8	J > > X X	Y+;;JGn))%%11*2F2FGiorv  xB  sC  sL  sL  L  M  MR8i..txx8c	jjN+ ighhis   :-F( (F9c                    t        | t        j                  j                  j                        r	t
        }d}nXt        | t        j                  j                  j                        r	t        }d}n!t        dt        |       j                  z        t        j                  || j                         t        j                        }|st        d      ||j!                  d      z   S )zu
    Provides this descriptor's signing constant, appended with the portion of
    the descriptor that's signed.
    s   (.+router-sig-ed25519 )s   (.+)signature zBUG: %s type unexpectedz+Malformed descriptor missing signature liner   )r   r7   rf   r   r   SIG_PREFIX_SERVER_DESCr   r   SIG_PREFIX_HS_V3r"   r   r<   research	get_bytesDOTALLgroup)rf   prefixregexmatchs       r&   r   z$Ed25519CertificateV1._signed_content  s     *doo??OOP%f(e	J > > X X	Yfe04
3C3L3LLMMIIeZ113RYY?EDEEEKKN""r(   c                    ddl m} ddlm} |j                  rJt        j                  t        j                  j                  j                  |j                        dz         }n| j                         }|st        d      	 |j                  |      }|j                  | j                  t        j                  t        j                  j                  j                  | j                               d t"                 y # |$ r t        d      w xY w)Nr   r   r      =z0Server descriptor missing an ed25519 signing keyzJEd25519KeyCertificate signing key is invalid (signature forged or corrupt))r   r   r   r   ed25519_master_keyrP   rQ   r7   r8   rL   	_to_bytesr   r"   r   r   r   r0   r   )r#   rf   r   r   r   r   s         r&   r   z6Ed25519CertificateV1._validate_server_desc_signing_key  s    R8$$$$TYY%8%8%B%B:C`C`%adh%hik$$&kIJJe..{;c	jj!1!1$))2E2E2O2OPTP\P\2]!^_yay`y!z{ ecddes   A9C; ;D)NNNNNNN)r<   r=   r>   r?   r'   r-   r@   rH   r   r   r   r   r   __classcell__)r   s   @r&   rG   rG     sU     V@" N N65 %iN # #,er(   rG   )#r?   rP   rS   rz   r   r   stem.descriptor.hidden_servicer7   !stem.descriptor.server_descriptorstem.prereq	stem.utilstem.util.enumstem.util.str_toolsstem.client.datatyper   r   r   r   rw   r   r   r   r   r   r}   r8   enumUppercaseEnumEnumr    r   r   objectrC   rG   rA   r(   r&   <module>r      s   FP     	 % (     3 3
 <   > 9  99>>'' 		##$:<		,,-A9M2Pu 2Pjj3 j3ZEe- Eer(   