
    0f%"                     l    d 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 Zd Zd Zd	 Zy
)a+  
This module contains functions that sign data using ed25519 keys, via the
pyca/cryptography library.  Functions that perform OpenPGP-compliant (e.g. GPG)
signing are provided instead in root_signing.

Function Manifest for this Module:
    serialize_and_sign
    wrap_as_signable
    sign_signable
    )hexlify)deepcopy   )SUPPORTED_SERIALIZABLE_TYPES
PrivateKey	PublicKeycanonserializecheckformat_hex_keycheckformat_keycheckformat_signablecheckformat_signaturecheckformat_stringload_metadata_from_filewrite_metadata_to_filec                 r    t        |       }|j                  |      }t        |      j                  d      }|S )uF  
    Given a JSON-compatible object, does the following:
     - serializes the dictionary as utf-8-encoded JSON, lazy-canonicalized
       such that any dictionary keys in any dictionaries inside <dictionary>
       are sorted and indentation is used and set to 2 spaces (using json lib)
     - creates a signature over that serialized result using private_key
     - returns that signature as a hex string

    See comments in common.canonserialize()

    Arguments:
      obj: a JSON-compatible object -- see common.canonserialize()
      private_key: a conda_content_trust.common.PrivateKey object

    # TODO ✅: Consider taking the private key data as a hex string instead?
    #          On the other hand, it's useful to support an object that could
    #          obscure the key (or provide an interface to a hardware key).
    zutf-8)r	   signr   decode)objprivate_key
serializedsignature_as_bytessignature_as_hexstrs        ;lib/python3.12/site-packages/conda_content_trust/signing.pyserialize_and_signr      s<    *  $J$))*5!"45<<WE    c                     t        |       t        vr#t        dt        t        |             z   dz         i t	        |       dS )u'  
    Given a JSON-serializable object (dictionary, list, string, numeric, etc.),
    returns a wrapped copy of that object:

        {'signatures': {},
         'signed': <deep copy of the given object>}

    Expects strict typing matches (not duck typing), for no good reason.
    (Trying JSON serialization repeatedly could be too time consuming.)

    TODO: ✅ Consider whether or not the copy can be shallow instead, for speed.

    Raises ❌TypeError if the given object is not a JSON-serializable type per
    SUPPORTED_SERIALIZABLE_TYPES
    z]wrap_dict_as_signable requires a JSON-serializable object, but the given argument is of type z7, which is not supported by the json library functions.)
signaturessigned)typer   	TypeErrorstrr   )r   s    r   wrap_as_signabler"   =   sR      944136tCy>BEDD
 	
 66r   c                     t        |       t        |        t        | d   |      }t        j                  |j                               }d|i}t        |       || d   |<   y)u  
    Given a JSON-compatible signable dictionary (as produced by calling
    wrap_dict_as_signable with a JSON-compatible dictionary), calls
    serialize_and_sign on the enclosed dictionary at signable['signed'],
    producing a signature, and places the signature in
    signable['signatures'], in an entry indexed by the public key
    corresponding to the given private_key.

    Updates the given signable in place, returning nothing.
    Overwrites if there is already an existing signature by the given key.

    # TODO ✅: Take hex string keys for sign_signable and serialize_and_sign
    #          instead of constructed PrivateKey objects?  Add the comment
    #          below if so:
    # # Unlike with lower-level functions, both signatures and public keys are
    # # always written as hex strings.

    Raises ❌TypeError if the given object is not a JSON-serializable type per
    SUPPORTED_SERIALIZABLE_TYPES
    r   	signaturer   N)r   r   r   r   to_hex
public_keyr   )signabler   r   public_key_as_hexstrsignature_dicts        r   sign_signabler*   ^   sj    , K " -Xh-?M$++K,B,B,DE "#67N.) 4BH\/0r   c                    t        |       t        |        t        j                  |      }t	        j
                  |j                               }t        |       }d|vrt        d      i |d<   |d   j                         D ]*  \  }}t        ||      }d|i}t        |       ||i|d   |<   , |j                  di       j                         D ]  \  }}t        ||      }|d|ii|d   |<    t        ||        y)a  
    Given a repodata.json filename, reads the "packages" entries in that file,
    and produces a signature over each artifact, with the given key.  The
    signatures are then placed in a "signatures" entry parallel to the
    "packages" entry in the json file.  The file is overwritten.

    Arguments:
        fname: filename of a repodata.json file
        private_key_hex:
            a private ed25519 key value represented as a 64-char hex string
    packagesz3Expected a "packages" entry in given repodata file.r   r$   zpackages.condaN)r
   r   r   from_hexr   r%   r&   r   
ValueErroritemsr   r   getr   )	fnameprivate_key_hexprivate
public_hexrepodataartifact_namemetadatasignature_hexr)   s	            r   sign_all_in_repodatar9      s%    (u !!/2G!!'"4"4"67J 'u-H !NOO  H\#+J#7#=#=#? Mx +8W= &}5n-1;^0L}-#M( $,<<0@"#E#K#K#M 
x*8W=m41
}-
 8U+r   N)__doc__binasciir   copyr   commonr   r   r   r	   r
   r   r   r   r   r   r   r   r"   r*   r9    r   r   <module>r?      s>   	     <7B3BlA,r   