U
    j*                  
   @   s  d Z ddlmZmZmZmZ ddlmZmZ ddl	m	Z	 ddlm
Z
 erTddlmZ z8dd	lmZ dd
lmZmZ ddlmZ ddlmZ W n. ek
r Z zedeW 5 dZ[X Y nX zddlmZ dZW n ek
r   dZY nX dZG dd deZG dd de
Z dS )zWebAuthn Authentication Plugin.    )TYPE_CHECKINGAnyCallableOptional   )errorsutils)logger   )MySQLAuthPlugin)MySQLSocket)
dump_bytes)Fido2ClientUserInteraction)CtapHidDevice)!PublicKeyCredentialRequestOptionszxModule fido2 is required for WebAuthn authentication mechanism but was not found. Unable to authenticate with the serverN)CtapPcscDeviceTFMySQLWebAuthnAuthPluginc                   @   s2   e Zd ZdZd	ee dddZddddZdS )
ClientInteractionz(Provides user interaction to the Client.N)callbackc                 C   s   || _ d| _d S )NzTPlease insert FIDO device and perform gesture action for authentication to complete.)r   msg)selfr    r   Z/tmp/pip-unpacked-wheel-d6bt0v6z/mysql/connector/plugins/authentication_webauthn_client.py__init__B   s    zClientInteraction.__init__returnc                 C   s&   | j dkrt| j n|  | j dS )z=Prompt message for the user interaction with the FIDO device.N)r   printr   r   r   r   r   	prompt_upI   s    
zClientInteraction.prompt_up)N)__name__
__module____qualname____doc__r   r   r   r   r   r   r   r   r   ?   s   r   c                   @   s   e Zd ZU dZdZee ed< dZee	 ed< ddg dZ
eed< eeddd	Zeedd
dZdee edddZeeee dddZdeeedddZdeeedddZdS )r   z<Class implementing the MySQL WebAuthn authentication plugin.Nclientr   )rpId	challengeallowCredentialsoptionsr   c                 C   s   dS )zPlugin official name.Zauthentication_webauthn_clientr   r   r   r   r   nameX   s    zMySQLWebAuthnAuthPlugin.namec                 C   s   dS )z'Signals whether or not SSL is required.Fr   r   r   r   r   requires_ssl]   s    z$MySQLWebAuthnAuthPlugin.requires_ssl)credential_idr   c           
      C   s   | j dkrtd|dk	r.|ddg| jd< | j t| j}t| }d}t	
d}|t	
|7 }t|D ]X}||}t|j}|j}	|t	
t|7 }||7 }|t	
t|	7 }||	7 }|j}qr|t	
t|7 }||7 }td| |S )	zGet assertion from authenticator and return the response.

        Args:
            credential_id (Optional[bytearray]): The credential ID.

        Returns:
            bytearray: The response packet with the data from the assertion.
        NzNo WebAuthn client foundz
public-key)idtyper'       r   z&WebAuthn - payload response packet: %s)r$   r   InterfaceErrorr(   Zget_assertionr   	from_dictlenZget_assertionsr   lc_intrangeZget_responsecbor_dump_bytesauthenticator_data	signatureZclient_datar	   debug)
r   r+   Z	assertionZnumber_of_assertionsZclient_data_jsonpacketiZassertion_responser5   r6   r   r   r   get_assertion_responseb   s6    






z.MySQLWebAuthnAuthPlugin.get_assertion_response)	auth_datakwargsr   c           	   
   K   s0  zjt |d\}}t |\}}|| jd< | | jd< td| td| jd  td| jd  W n. tk
r } zt	d|W 5 d}~X Y nX t
t d}|dk	rtd	 ntrt
t d}|dkrt	d
t|d| jd  t| jd| _| jjjds"td dS td dS )aE  Find authenticator device and check if supports resident keys.

        It also creates a Fido2Client using the relying party ID from the server.

        Raises:
            InterfaceError: When the FIDO device is not found.

        Returns:
            bytes: 2 if the authenticator supports resident keys else 1.
        r
   r&   r%   zWebAuthn - capability: %dzWebAuthn - challenge: %szWebAuthn - relying party id: %sz2Unable to parse MySQL WebAuthn authentication dataNzWebAuthn - Use USB HID channelzNo FIDO device foundzhttps://)Zuser_interactionZrkz6WebAuthn - Authenticator doesn't support resident keys   1z<WebAuthn - Authenticator with support for resident key found   2)r   Zread_intZread_lc_string_listr(   decoder	   r7   
ValueErrorr   r/   nextr   Zlist_devicesCTAP_PCSC_DEVICE_AVAILABLEr   r   r   r   r$   infoget)	r   r;   r<   ZpacketsZ
capabilityr&   Zrp_iderrZdevicer   r   r   auth_response   s>    



z%MySQLWebAuthnAuthPlugin.auth_responser   )sockr;   r<   r   c                 K   sP   t |\}}| |}td|t| || t| }td| |S )aE  Handles server's `auth more data` response.

        Args:
            sock: Pointer to the socket connection.
            auth_data: Authentication method data (from a packet representing
                       an `auth more data` response).
            kwargs: Custom configuration to be passed to the auth plugin
                    when invoked. The parameters defined here will override the ones
                    defined in the auth plugin itself.

        Returns:
            packet: Last server's response after back-and-forth
                    communication.
        WebAuthn - request: %s size: %s%WebAuthn - server response packet: %s)	r   Zread_lc_stringr:   r	   r7   r1   sendbytesrecv)r   rG   r;   r<   _r+   responsepktr   r   r   auth_more_response   s    

z*MySQLWebAuthnAuthPlugin.auth_more_responsec                 K   s   | dp| d}t|tr(t|n|| _| |}d}|dkrntd |	t
t| t| S | |}td|t| |	| t| }td| |S )aS  Handles server's `auth switch request` response.

        Args:
            sock: Pointer to the socket connection.
            auth_data: Plugin provided data (extracted from a packet
                       representing an `auth switch request` response).
            kwargs: Custom configuration to be passed to the auth plugin
                    when invoked. The parameters defined here will override the ones
                    defined in the auth plugin itself.

        Returns:
            packet: Last server's response after back-and-forth
                    communication.
        Zwebauthn_callbackZfido_callbackNr=   z WebAuthn - request credential_idrH   rI   )rD   
isinstancestrr   Zimport_objectr   rF   r	   r7   rJ   r2   intrK   rL   r:   r1   )r   rG   r;   r<   Zwebauth_callbackrN   r+   rO   r   r   r   auth_switch_response   s&    



z,MySQLWebAuthnAuthPlugin.auth_switch_response)N)r    r!   r"   r#   r$   r   r   __annotations__r   r   r(   dictpropertyrR   r)   boolr*   	bytearrayrK   r:   r   rF   rP   rT   r   r   r   r   r   Q   s0   
 F1    )!r#   typingr   r   r   r    r   r   r	   r   networkr   Z
fido2.cborr   r4   Zfido2.clientr   r   Z	fido2.hidr   Zfido2.webauthnr   ImportErrorZ
import_errZProgrammingErrorZ
fido2.pcscr   rB   ModuleNotFoundErrorZAUTHENTICATION_PLUGIN_CLASSr   r   r   r   r   r   <module>   s2   
