
    <[j=                    f   d dl mZ d dlZd dlZd dlmZmZmZmZ d dl	m
Z d dlmZ ddlmZ ddlmZ dd	lmZ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 m!Z!m"Z"m#Z#m$Z$m%Z%m&Z&m'Z'm(Z(m)Z)  ej*        e+          Z,eee-gdf         Z.ee/ge0f         Z1d#dZ2d$dZ3	 d%d&dZ4d'dZ5d(d Z6 G d! d"          Z7dS ))    )annotationsN)AnyCallableMappingSequence)InvalidSignature)constant_time   )CoseKeyverify_rp_id)websafe_decodewebsafe_encode)AttestationConveyancePreferenceAttestationObjectAttestedCredentialDataAuthenticationResponseAuthenticatorAttachmentAuthenticatorDataAuthenticatorSelectionCriteriaCollectedClientDataCredentialCreationOptionsCredentialRequestOptions"PublicKeyCredentialCreationOptionsPublicKeyCredentialDescriptorPublicKeyCredentialParameters!PublicKeyCredentialRequestOptionsPublicKeyCredentialRpEntityPublicKeyCredentialTypePublicKeyCredentialUserEntityRegistrationResponseResidentKeyRequirementUserVerificationRequirementrp_idstrreturnVerifyOriginc                      fdS )Nc                $    t          |           S Nr   )or$   s    T/home/thesage/.hermes/hermes-agent/venv/lib/python3.11/site-packages/fido2/server.py<lambda>z'_verify_origin_for_rp.<locals>.<lambda>G   s    \%++      )r$   s   `r,   _verify_origin_for_rpr0   F   s    +++++r.   	challengebytes | Nonebytesc                    | t          j        d          } nFt          | t                    st	          d          t          |           dk     rt          d          | S )N    z)Custom challenge must be of type 'bytes'.   z&Custom challenge length must be >= 16.)osurandom
isinstancer3   	TypeErrorlen
ValueError)r1   s    r,   _validata_challenger=   J   s_    JrNN		)U++ 	IGHHHy>>BEFFFr.   
credentialr   r   c                D    t          t          j        | j        |          S )a  Converts an AttestedCredentialData to a PublicKeyCredentialDescriptor.

    :param credential: AttestedCredentialData containing the credential ID to use.
    :param transports: Optional list of AuthenticatorTransport strings to add to the
        descriptor.
    :return: A descriptor of the credential, for use with register_begin or
        authenticate_begin.
    :rtype: PublicKeyCredentialDescriptor
    )typeid
transports)r   r   
PUBLIC_KEYcredential_id)r>   rB   s     r,   to_descriptorrE   U   s*     )$/#   r.   credsGSequence[AttestedCredentialData | PublicKeyCredentialDescriptor] | None.Sequence[PublicKeyCredentialDescriptor] | Nonec                "    | d S d | D             S )Nc                ~    g | ]:}t          |t                    rt          |          nt          j        |          ;S r/   )r9   r   rE   r   	from_dict).0cs     r,   
<listcomp>z%_wrap_credentials.<locals>.<listcomp>m   sU         !344<M!.8;;	  r.   r/   )rF   s    r,   _wrap_credentialsrO   h   s1     }t     r.   attestation_objectr   client_data_hashNonec                    dS )zIgnore attestation.Nr/   )rP   rQ   s     r,   _ignore_attestationrT   w   s      r.   c                  r    e Zd ZdZ	 	 	 d'd(dZ	 	 	 	 	 	 d)d*dZd+dZ	 	 	 	 d,d-d Zd.d$Ze	d/d&            Z
dS )0Fido2Servera@  FIDO2 server.

    :param rp: Relying party data as `PublicKeyCredentialRpEntity` instance.
    :param attestation: (optional) Requirement on authenticator attestation.
    :param verify_origin: (optional) Alternative function to validate an origin.
    :param verify_attestation: (optional) function to validate attestation, which is
        invoked with attestation_object and client_data_hash. It should return nothing
        and raise an exception on failure. By default, attestation is ignored.
        Attestation is also ignored if `attestation` is set to `none`.
    Nrpr   attestation&AttestationConveyancePreference | Noneverify_originVerifyOrigin | Noneverify_attestationVerifyAttestation | Nonec                n   t          j        |          | _        | j        j        J |pt	          | j        j                  | _        d | _        t          |          | _        d t          j
                    D             | _        |pt          | _        t                              d| j                    d S )Nc                D    g | ]}t          t          j        |           S ))r@   alg)r   r   rC   )rL   r`   s     r,   rN   z(Fido2Server.__init__.<locals>.<listcomp>   sA     #
 #
 #
  *,7S  #
 #
 #
r.   z Fido2Server initialized for RP: )r   rK   rW   rA   r0   _verifytimeoutr   rX   r   supported_algorithmsallowed_algorithmsrT   _verify_attestationloggerdebug)selfrW   rX   rZ   r\   s        r,   __init__zFido2Server.__init__   s     .7;;wz%%%$I(=dgj(I(I:;GG#
 #
 355	#
 #
 #
 $6#L9L AAABBBBBr.   userr    credentialsrG   resident_key_requirementResidentKeyRequirement | Noneuser_verification"UserVerificationRequirement | Noneauthenticator_attachmentAuthenticatorAttachment | Noner1   r2   r&   %tuple[CredentialCreationOptions, Any]c                   | j         st          d          t          |          }t          |          }|                     ||          }	t
                              dd                    d |pg D                       z              t          t          | j
        t          j        |          || j         | j        |t          |||f          rt          |||          nd| j        |	  	                  |	fS )	av  Return a PublicKeyCredentialCreationOptions registration object and
        the internal state dictionary that needs to be passed as is to the
        corresponding `register_complete` call.

        :param user: The dict containing the user data.
        :param credentials: The list of previously registered credentials, these can be
            of type AttestedCredentialData, or PublicKeyCredentialDescriptor.
        :param resident_key_requirement: The desired RESIDENT_KEY_REQUIREMENT level.
        :param user_verification: The desired USER_VERIFICATION level.
        :param authenticator_attachment: The desired AUTHENTICATOR_ATTACHMENT
            or None to not provide a preference (and get both types).
        :param challenge: A custom challenge to sign and verify or None to use
            OS-specific random bytes.
        :return: Registration data, internal state.z!Server has no allowed algorithms.z1Starting new registration, existing credentials: , c              3  H   K   | ]}|j                                         V  d S r*   rA   hexrL   ds     r,   	<genexpr>z-Fido2Server.register_begin.<locals>.<genexpr>   s,      >>q

>>>>>>r.   )rp   resident_keyrn   N)	rW   rj   r1   pub_key_cred_paramsrb   exclude_credentialsauthenticator_selectionrX   
extensions
public_key)rd   r<   r=   rO   _make_internal_staterf   rg   joinr   r   rW   r    rK   rb   anyr   rX   )
rh   rj   rk   rl   rn   rp   r1   r   descriptorsstates
             r,   register_beginzFido2Server.register_begin   s9   4 & 	B@AAA'	22	'44)))5FGG?ii>>K,=2>>>>>?	
 	
 	
 &=w6@FF'(,(? L(3  8 8 1 "65M)A.?    " $ 0)/    6 9
 	
r.   response(RegistrationResponse | Mapping[str, Any]r   c                   t          j        |          }|j        j        }|j        j        }|j        t          j        j        k    rt          d          | 
                    |j                  st          d          t          j        t          |d                   |j                  st          d          t          j        | j        j        pd|j        j                  st          d          |j                                        st          d          |d         t*          j        k    r(|j                                        st          d	          | j        d
t2          j        fvr=t6                              d|j                    |                     ||j                   |j        }|j         J t6          !                    d|j         j"        #                                z              |S )a(  Verify the correctness of the registration data received from
        the client.

        :param state: The state data returned by the corresponding
            `register_begin`.
        :param response: The registration response from the client.
        :return: The authenticator data
        &Incorrect type in CollectedClientData.&Invalid origin in CollectedClientData.r1   Wrong challenge in response.r.   Wrong RP ID hash in response.User Present flag not set.rn   z;User verification required, but User Verified flag not set.NzVerifying attestation of type zNew credential registered: )$r!   rK   r   client_datarP   r@   r   TYPECREATEr<   ra   originr	   bytes_eqr   r1   rW   id_hash	auth_data
rp_id_hashis_user_presentr#   REQUIREDis_user_verifiedrX   r   NONErf   rg   fmtre   hashcredential_datainforD   rw   )rh   r   r   registrationr   rP   r   s          r,   register_completezFido2Server.register_complete   s    ,5h??"+7)2E27>>>EFFF||K.// 	GEFFF%5-..0E
 
 	= ;<<<%GO"s$6$@$K
 
 	> <===!+;;== 	;9::: %&*E*NNN&0AACC O M   D*I*N#OOOLLR:L:PRRSSS$$%79IJJJ '0	(444)'599;;<	
 	
 	
 r.   $tuple[CredentialRequestOptions, Any]c           
        t          |          }t          |          }|                     ||          }|t                              d           n:t                              dd                    d |D                       z              t          t          || j        | j	        j
        |||                    |fS )aR  Return a PublicKeyCredentialRequestOptions assertion object and the internal
        state dictionary that needs to be passed as is to the corresponding
        `authenticate_complete` call.

        :param credentials: The list of previously registered credentials, these can be
            of type AttestedCredentialData, or PublicKeyCredentialDescriptor.
        :param user_verification: The desired USER_VERIFICATION level.
        :param challenge: A custom challenge to sign and verify or None to use
            OS-specific random bytes.
        :return: Assertion data, internal state.Nz/Starting new authentication without credentialsz.Starting new authentication, for credentials: rt   c              3  H   K   | ]}|j                                         V  d S r*   rv   rx   s     r,   rz   z1Fido2Server.authenticate_begin.<locals>.<genexpr>3  s,      <<1ADHHJJ<<<<<<r.   )r1   rb   r$   allow_credentialsrn   r   r   )r=   rO   r   rf   rg   r   r   r   rb   rW   rA   )rh   rk   rn   r1   r   r   r   s          r,   authenticate_beginzFido2Server.authenticate_begin  s    & (	22	'44)))5FGGLLJKKKKLL@))<<<<<<<=   %<' L'*&1&7)  	 	 	 
 	
r.    Sequence[AttestedCredentialData]*AuthenticationResponse | Mapping[str, Any]r   c                   t          j        |          }|j        }|j        j        }|j        j        }|j        j        }|j        t          j	        j
        k    rt          d          |                     |j                  st          d          t          j        t!          |d                   |j                  st          d          t          j        | j        j        pd|j                  st          d          |                                st          d          |d         t,          j        k    r#|                                st          d	          |D ]}	|	j        |k    ru	 |	j                            ||j        z   |           n# t:          $ r t          d
          w xY wt<                              d|                                             |	c S t          d          )a  Verify the correctness of the assertion data received from
        the client.

        :param state: The state data returned by the corresponding
            `register_begin`.
        :param credentials: The list of previously registered credentials.
        :param credential_id: The credential id from the client response.
        :param client_data: The client data.
        :param auth_data: The authenticator data.
        :param signature: The signature provided by the client.r   r   r1   r   r.   r   r   rn   z;User verification required, but user verified flag not set.zInvalid signature.zCredential authenticated: zUnknown credential ID.)!r   rK   raw_idr   r   authenticator_data	signaturer@   r   r   GETr<   ra   r   r	   r   r   r1   rW   r   r   r   r#   r   r   rD   r   verifyr   _InvalidSignaturerf   r   rw   )
rh   r   rk   r   authenticationrD   r   r   r   creds
             r,   authenticate_completez!Fido2Server.authenticate_completeD  s   " 09(CC&-$-9"+>	"+5	27;;;EFFF||K.// 	GEFFF%5-..0E
 
 	= ;<<<%dgo&<i>RSS 	><===((** 	;9::: %&*E*NNN..00 O M     	 	D!]22;O**9{7G+GSSSS( ; ; ;$%9:::;N9J9J9L9LNNOOO 3 1222s   /#FF-r3   c                &    t          |           |dS )Nr1   rn   )r   r   s     r,   r   z Fido2Server._make_internal_statez  s!    
 (	22!2
 
 	
r.   )NNN)rW   r   rX   rY   rZ   r[   r\   r]   )NNNNNN)rj   r    rk   rG   rl   rm   rn   ro   rp   rq   r1   r2   r&   rr   )r   r   r&   r   )NNNN)rk   rG   rn   ro   r1   r2   r&   r   )rk   r   r   r   r&   r   )r1   r3   rn   ro   )__name__
__module____qualname____doc__ri   r   r   r   r   staticmethodr   r/   r.   r,   rV   rV   }   s        	 	 ?C-17;C C C C C4 BF@DCG"&B
 B
 B
 B
 B
H4 4 4 4t @D"&*
 *
 *
 *
 *
X43 43 43 43l 
 
 
 \
 
 
r.   rV   )r$   r%   r&   r'   )r1   r2   r&   r3   r*   )r>   r   r&   r   )rF   rG   r&   rH   )rP   r   rQ   r3   r&   rR   )8
__future__r   loggingr7   typingr   r   r   r   cryptography.exceptionsr   r   cryptography.hazmat.primitivesr	   coser   rpidr   utilsr   r   webauthnr   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r    r!   r"   r#   	getLoggerr   rf   r3   VerifyAttestationr%   boolr'   r0   r=   rE   rO   rT   rV   r/   r.   r,   <module>r      sq  8 # " " " " "  				 3 3 3 3 3 3 3 3 3 3 3 3 I I I I I I 8 8 8 8 8 8             1 1 1 1 1 1 1 1                                           . 
	8	$	$ /7=> t$, , , ,    48    &      D
 D
 D
 D
 D
 D
 D
 D
 D
 D
r.   