
    gX                         S r SSKJr  SSKJr  SSKrSSKJr  SSK	J
r
JrJrJrJrJrJrJrJrJrJrJrJrJrJr  S r SS	 jrS
 rSS jrS rg)z
This module contains functions that verify signatures and thereby authenticate
data.

Function Manifest for this Module
    verify_signature
    verify_gpg_signature
    verify_signable
    verify_root
    verify_delegation
    )	unhexlify)packN)ed25519   )MetadataVerificationError	PublicKeySignatureErrorUnknownRoleErrorcanonserializecheckformat_byteslikecheckformat_delegating_metadatacheckformat_gpg_signaturecheckformat_hex_keycheckformat_signableis_gpg_signature
is_hex_keyis_hex_signatureis_signableis_signaturec                 |   [        U 5        [        U5        U S   S   S:w  d  US   S   S:w  a  [        S5      eU S   S   S   nUS   nUS   nUS   S   S   nUS   nUS   nU S   S   nUS   S   n	US	-   U	:w  a)  [        S
[        U5      -   S-   [        U	5      -   S-   5      e[	        XUSS9  [	        UUUSS9  g)uM  
Given currently trusted root metadata, verify that new root metadata is
trustworthy per the currently trusted root metadata.

This requires a root chaining process as specified in The Update Framework
specification.  (Version N must be used in order to verify version N+1.
Versions cannot be skipped.)

# TODO✅: Proper docstring.
signedtyperootzxExpected two instances of root metadata.  Listed metadata type in one or both pieces of metadata provided is not "root".delegations	thresholdpubkeysversionr   zYRoot chaining failure: we currently trust a version of root that marks itself as version zG, and the provided new root metadata to verify marks itself as version z; the new version must be 1 more than the old version: root updates MUST be processed one at a time for security reasons: no root version may be skipped.TgpgN)r   
ValueErrorr   strverify_signable)
trusted_current_root_metadatauntrusted_new_root_metadataroot_expectationsexpected_thresholdauthorized_pub_keysnew_root_expectationsnew_expected_thresholdnew_authorized_pub_keystrusted_root_versionuntrusted_root_versions
             Blib/python3.13/site-packages/conda_content_trust/authentication.pyverify_rootr.   (   sD    $$AB#$?@ 	&h/76A&x08FB
 	
 6h?NvV*;7+I6 8A-PQWX2;?3I>8B9M8B9Ma#99',&'(   67	8;+	+	
 		
 #:LRV #	    c                    [        U [        5      (       d   [        S[        [        U 5      5      -   5      eUS;  a  [        S5      e[	        U5        [        U5         [	        U5        XS   S   :w  a  [        SU -   S-   US   S   -   S-   5      e US   S	   nX;  a  [        S
U -   S-   5      eX@   S   nX@   S   n[        UUUUS9  g!    N== f)aS  
Verify that the given untrusted, delegated-to metadata is trustworthy,
based on the given trusted metadata's expectations (expected keys and
threshold).  This function returns if verification succeeds.


In other words, check trusted_delegating_metadata's delegation
to delegation_name to find the expected signing keys and threshold for
delegation_name, and then check untrusted_delegated_metadata to see if it
is signed by enough of the right keys to be trustworthy.

For example, using root metadata to verify key_mgr metadata looks like
this:
    verify_delegation(
            'key_mgr', <full root metadata>, <full key_mgr metadata>)

Arguments:
    (string) delegation_name is the name of the role delegated.
    (dict)   trusted_delegating_metadata is a signable JSON-serializable
             object representing the full metadata that delegates to role
             delegation_name.
    (dict)   untrusted_delegated_metadata is a signable JSON-serializable
             object
    (bool)   gpg should be true if the signatures to be verified in the
             delegated metadata are expected to be OpenPGP signatures
             rather than the usual raw ed25519 signatures.

Exceptions:
    - raises UnknownRoleError if there's no matching delegation
    - raises SignatureError if a signature is bad or signatures
      don't match expectations (threshold, wrong keys, etc.)
        # TODO: Consider exception handling to raise MetadataVerificationError instead?
    - raises MetadataVerificationError if the metadata type is unexpected
    - raises TypeError or ValueError if the arguments are invalid
z(delegation_name must be a string, not a )TFz!Argument "gpg" must be a boolean.r   r   z<Instructed to verify provided metadata as if it is of type "z ", but it claims to be of type "z"!r   zRole z, not found in the given delegating metadata.r   r   r   N)	
isinstancer!   	TypeErrorr   r   r   r   r
   r"   )delegation_nameuntrusted_delegated_metadatatrusted_delegating_metadatar   r   expected_keysr   s          r-   verify_delegationr7      s9   X os++6T/=R9SS
 	
 -/
 	
 $$?@ 56'(DE 8DVLL+*+.7A&IJLPQ  M .h7FK)o% )# #
 	

  0;M,[9I$	9
 	s   C Cc                    [        U[        R                  5      (       d   [        S[	        [        U5      5      -   5      e[        U 5      (       d   [        S[	        [        U 5      5      -   5      e[        U[        5      (       d   [        S[	        [        U5      5      -   5      eUR                  [        U 5      U5        g)u  
Raises ❌cryptography.exceptions.InvalidSignature if signature is not a
correct signature by the given key over the given data.

Raises ❌TypeError if public_key, signature, or data are not correctly
formatted.

Otherwise, returns (nothing), indicating the signature was verified.

Note that this does not use the generalized signature format (which would
be compatible with OpenPGP/GPG signatures as well as pyca/cryptography's
simple ed25519 sigs).

Args:
    - public_key must be an ed25519.Ed25519PublicKeyObject
    - signature must be a hex string, length 128, representing a 64-byte
      raw ed25519 signature
    - data must be bytes
zverify_signature expects a cryptography.hazmat.primitives.asymmetric.ed25519ed25519.Ed25519PublicKeyobject as the "public_key" argument.  Instead, received zverify_signature expects a hex string representing an ed25519 signature as the "signature" argument. Instead, received object of type zXverify_signature expects a bytes object as the "signature" argument.  Instead, received N)
r1   r   Ed25519PublicKeyr2   r!   r   r   bytesverifyr   )	signature
public_keydatas      r-   verify_signaturer?      s    ( j'":":;;G $z"#$
 	
 I&&'),T)_)=>
 	
 dE"",.1$t*o>
 	

 i	*D1 r/   c           	         [        U 5      (       d  [        S5      e[        U[        5      (       a)  [	        U Vs/ sH  n[        U5      PM     sn5      (       d  [        S5      e[        U[        5      (       a  US::  a  [        S5      e[        U S   5      n0 nU S   R                  5        H  u  px[        U5      (       d  [        S[        U5      -   5        M.  U(       a)  [        U5      (       d  [        S[        U5      -   5        M^  Xq;  a  [        S	[        U5      -   S
-   5        M  U(       dU  [        U5      (       d  [        S[        U5      -   5        M  [        R                  " U5      n	 [        US   X5        XU'   M  U(       d   e ['        XU5        XU'   M     [)        U5      U:  ae  [+        S[        U5      -   S-   [        [)        U5      5      -   S-   [        [)        U S   5      5      -   S-   [        [)        U5      5      -   S-   5      egs  snf ! [         R"                  R$                   a     GM  f = f! [         R"                  R$                   a     GM  f = f)u{  
Raises a ❌SignatureError if signable does not include at least threshold
good signatures from (unique) keys with public keys listed in
authorized_pub_keys, over the data contained in signable['signed'].

Raises ❌TypeError if the arguments are invalid.

Else returns (nothing).

Args:
    - signable
        common.is_a_signable(signable) must return true.
        wrap_as_signable() produces output of this type.  See those
        functions.

    - authorized_pub_keys
        a list of ed25519 public keys (32 bytes) expressed as 64-character
        hex strings.  This is the form in which they appear in authority
        metadata (root.json, etc.)  Only good signatures from keys listed
        in authorized_pub_keys count against the threshold of signatures
        required to verify the signable.

    - threshold
        the number of good signatures from unique authorized keys required
        in order to verify the signable.

    - gpg (boolean, default False)
        If True, expects OpenPGP ed25519 signatures (see RFC 4880 bis-08)
        instead of raw ed25519 signatures.
        If False, expects raw ed25519 signatures.
zOverify_signable expects a signable dictionary.  Given argument failed the test.z2authorized_pub_keys must be a list of hex strings r   z%threshold must be a positive integer.r   
signatureszYIgnoring signature from "key" with public key value that does not look like a key value: zDIgnoring "signature" that does not look like a gpg signature value: z Ignoring signature from a key ("z0") that is not authorized to sign this metadata.zDIgnoring "signature" that does not look like a hex signature value: r<   z'Expected good signatures from at least z unique keys from a set of z keys.  Saw z signatures, only zJ of which were good signatures over the given data from the expected keys.N)r   r2   r1   listallr   intr   itemsprintr!   r   r   r   from_hexr?   cryptography
exceptionsInvalidSignatureverify_gpg_signaturelenr	   )
signabler'   r   r   ksigned_datagood_sigs_from_trusted_keys
pubkey_hexr<   publics
             r-   r"   r"   ,  s   Z x  .
 	

 	&--(;<(;1A(;<==LMM i%%a?@@" !(!34K #%!),!7!=!=!?
*%%358_E '	22$&))n5 02j/"DE
 	**(*-i.9 ''
3FD ;!7M ;DJ7 J3D$YKH ;DJ7w "@| &')35)n+, #)*+, 	
 #h|,-./ ## #1234	
 	
 _ =V  **;;   **;; s)   H4H!I!III*)I*c                    [        U 5        [        U5        [        U5        [        R                  " U5      n[        U S   5      n[        R                  R                  R                  R                  [        R                  R                  R                  R                  5       [        R                  R                  R                  5       5      nUR                  U5        UR                  U5        UR                  S5        UR                  [        S[!        U5      5      5        UR#                  5       nUR%                  [        U S   5      U5        g)u  
Verifies a raw ed25519 signature that happens to have been produced by an
OpenPGP signing process (RFC4880).

NOTE that this code DISREGARDS most OpenPGP semantics: is interested solely
in the verification of a signature over the given data, with the raw
ed25519 public key given (in the form of a hex string).  This code does not
care about the GPG public key infrastructure, including key
self-revocation, expiry, or the relationship of any key with any other key
through OpenPGP (subkeys, key-to-key signoff, etc.).

This codebase uses OpenPGP signatures solely as a means of facilitating a
TUF-style public key infrastructure, where the public key values are
trusted with specific privileges directly.


⚠️💣 ABSOLUTELY DO NOT use this for general purpose verification of GPG
     signatures!!  It is for our root signatures only, where OpenPGP
     signing is just a proxy for a simple ed25519 signature through a
     hardware signing mechanism.


# TODO: ✅ Proper docstring modeled on verify_signature.
other_headerss   z>Ir<   N)r   r   r   r   rG   r   rH   hazmat
primitiveshashesHashSHA256backendsdefault_backendupdater   rL   finalizer;   )r<   	key_valuer>   r=   additional_header_datahasherdigests          r-   rK   rK     s   4 i(	"$ ##I.J$ 'y'AB   ++2277&&--446$$446F MM$
MM()
MM+
MM$tS!789:__F i	+ 67@ r/   )F)__doc__binasciir   structr   cryptography.exceptionsrH   )cryptography.hazmat.primitives.asymmetricr   commonr   r   r	   r
   r   r   r   r   r   r   r   r   r   r   r   r.   r7   r?   r"   rK    r/   r-   <module>ri      sW   
    =    (GT 		f^,^cLIr/   