
    C                     >    d Z ddlZddlmZ ddlmZ  G d de      Zy)zThis module implements the low level device API.

This module exposes a low level SecurityKey class,
representing the physical security key device.
    N)apdu)errorsc                   D    e Zd ZdZd Zd Z	 ddZd Zd Zd Z	d Z
d	 Zy
)SecurityKeyzLow level api for talking to a security key.

  This class implements the low level api specified in FIDO
  U2F for talking to a security key.
  c                 T    || _         d| _        t        j                  d      | _        y )NFzpyu2f.hardware)	transportuse_legacy_formatlogging	getLoggerlogger)selfr   s     !lib/third_party/pyu2f/hardware.py__init__zSecurityKey.__init__!   s$    DN"D##$45DK    c           	      X   | j                   j                  d       t        |      dk7  st        |      dk7  rt        j                         t        ||z         }| j                  t        j                  dt        j                  dd|            }|j                          |j                  S )a2  Register security key.

    Ask the security key to register with a particular origin & client.

    Args:
      challenge_param: Arbitrary 32 byte challenge string.
      app_param: Arbitrary 32 byte applciation parameter.

    Returns:
      A binary structure containing the key handle, attestation, and a
      signature over that by the attestation key.  The precise format
      is dictated by the FIDO U2F specs.

    Raises:
      TUPRequiredError: A Test of User Precense is required to proceed.
      ApduError: Something went wrong on the device.
    CmdRegister    r      )r   debuglenr   InvalidRequestError	bytearrayInternalSendApdur   CommandApduCMD_REGISTERCheckSuccessOrRaisebody)r   challenge_param	app_paramr   responses        r   r   zSecurityKey.CmdRegister&   s    $ 	KKm$
?r!S^r%9&&((_y01D$$T%5%5	& H   "==r   c           	         | j                   j                  d       t        |      dk7  st        |      dk7  rt        j                         |rdnd}t        ||z   t        t        |      g      z   |z         }| j                  t        j                  dt        j                  |d|            }|j                          |j                  S )a  Attempt to obtain an authentication signature.

    Ask the security key to sign a challenge for a particular key handle
    in order to authenticate the user.

    Args:
      challenge_param: SHA-256 hash of client_data object as a bytes
          object.
      app_param: SHA-256 hash of the app id as a bytes object.
      key_handle: The key handle to use to issue the signature as a bytes
          object.
      check_only: If true, only check if key_handle is valid.

    Returns:
      A binary structure containing the key handle, attestation, and a
      signature over that by the attestation key.  The precise format
      is dictated by the FIDO U2F specs.

    Raises:
      TUPRequiredError: If check_only is False, a Test of User Precense
          is required to proceed.  If check_only is True, this means
          the key_handle is valid.
      InvalidKeyHandleError: The key_handle is not valid for this device.
      ApduError: Something else went wrong on the device.
    CmdAuthenticater      r   r   )r   r   r   r   r   r   r   r   r   CMD_AUTHr   r   )r   r   r   
key_handle
check_onlycontrolr   r    s           r   r"   zSecurityKey.CmdAuthenticateG   s    < 	KK'(
?r!S^r%9&&(( ddG_y0J0124>? @D$$T%5%5	4=='4&/ 0H  "==r   c                 .   | j                   j                  d       | j                  t        j                  dt        j
                  dd            }|j                         s*t        j                  |j                  |j                        |j                  S )a  Obtain the version of the device and test transport format.

    Obtains the version of the device and determines whether to use ISO
    7816-4 or the U2f variant.  This function should be called at least once
    before CmdAuthenticate or CmdRegister to make sure the object is using the
    proper transport for the device.

    Returns:
      The version of the U2F protocol in use.
    
CmdVersionr   )r   r   r   r   r   CMD_VERSION	IsSuccessr   	ApduErrorsw1sw2r   )r   r    s     r   r)   zSecurityKey.CmdVersionr   su     	KKl#$$T%5%5	4T4&) *H X\\8<<88==r   c                 p    | j                   j                  d       | j                  j                  |       y )NCmdBlink)r   r   r   	SendBlink)r   times     r   r0   zSecurityKey.CmdBlink   s&    KKj!NNT"r   c                 n    | j                   j                  d       | j                  j                          y )NCmdWink)r   r   r   SendWink)r   s    r   r4   zSecurityKey.CmdWink   s$    KKi NNr   c                 n    | j                   j                  d       | j                  j                  |      S )NCmdPing)r   r   r   SendPing)r   datas     r   r7   zSecurityKey.CmdPing   s)    KKi >>""4((r   c                    d}| j                   stt        j                  | j                  j	                  |j                                     }|j                  dk(  r'|j                  dk(  rd| _         | j                  |      S |S t        j                  | j                  j	                  |j                                     }|S )a,  Send an APDU to the device.

    Sends an APDU to the device, possibly falling back to the legacy
    encoding format that is not ISO7816-4 compatible.

    Args:
      apdu_to_send: The CommandApdu object to send

    Returns:
      The ResponseApdu object constructed out of the devices reply.
    Ng   r   T)
r	   r   ResponseApdur   SendMsgBytesToByteArrayr-   r.   r   ToLegacyU2FByteArray)r   apdu_to_sendr    s      r   r   zSecurityKey.InternalSendApdu   s     H!!""4>>#>#>

"
"
$$& 'h		(,,$"6 "&$$\22 O ""4>>#>#>

+
+
-$/ 0hOr   N)F)__name__
__module____qualname____doc__r   r   r"   r)   r0   r4   r7   r    r   r   r   r      s6    6
J "'	)V(#)r   r   )rD   r
   pyu2fr   r   objectr   rE   r   r   <module>rH      s#   
   P& Pr   