
    Dj5%                        d dl mZ d dlZd dlZd dlmZ d dl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mZ d	dlmZmZ d	dlmZ dZdZdZdZ ej        e          Z  G d de          Z!d Z"dS )    )annotationsN)Event)CallableIterator)System)CardConnection)CardConnectionDecorator)ListReadersException   )STATUS
CtapDevice	CtapError)
CAPABILITYCTAPHID)LOG_LEVEL_TRAFFICs     G/ )   r   )   r   a   c                     e Zd ZdZd5dZd Zd Zed6d            Zed7d            Z	ed8d            Z
ed9d            Zd:dZ	 d;d<dZd=d>dZd?dZ	 d=d@d$ZdAd%ZdBd&Z	 	 	 dCdDd+Z	 	 	 dCdEd-ZdFdGd1ZedHdId4            ZdS )JCtapPcscDevicezo
    CtapDevice implementation using pyscard (PCSC).

    This class is intended for use with NFC readers.
    
connection(CardConnection | CardConnectionDecoratornamestrc                R   || _         t          d          | _        d| _        d| _        || _        |                                  	 |                     t          j	        d           | xj        t          j	        z  c_        d S # t          $ r | j        st          d          Y d S w xY w)Nr   FT   zUnsupported device)_namer   _capabilitiesuse_ext_apduuse_nfcctap_getresponse_connconnectcallr   CBORr   
ValueError)selfr   r   s      E/home/thesage/.hermes/venv/lib/python3.11/site-packages/fido2/pcsc.py__init__zCtapPcscDevice.__init__=   s    
']]!'+$
	7IIglG,,,*/1 	7 	7 	7% 7 !56667 7 7	7s   :B  B&%B&c                `    | j                                          |                                  d S N)r!   r"   _selectr&   s    r'   r"   zCtapPcscDevice.connectL   s'    
    c                    d| j          dS )NzCtapPcscDevice())r   r,   s    r'   __repr__zCtapPcscDevice.__repr__P   s    .....r-   returnintc                0    t           j        | j        v rdndS )zCTAPHID protocol version.   r   )r   r$   r   r,   s    r'   versionzCtapPcscDevice.versionS   s     Ot'999qqq@r-   r   c                    | j         S )z%Capabilities supported by the device.)r   r,   s    r'   capabilitieszCtapPcscDevice.capabilitiesX   s     !!r-   
str | Nonec                    dS )zProduct name of device.N r,   s    r'   product_namezCtapPcscDevice.product_name]   	     tr-   
int | Nonec                    dS )zSerial number of device.Nr:   r,   s    r'   serial_numberzCtapPcscDevice.serial_numberb   r<   r-   bytesc                R    t          | j                                        pd          S )z&Get the ATR/ATS of the connected card.r-   )r@   r!   getATRr,   s    r'   get_atrzCtapPcscDevice.get_atrg   s#    TZ&&((/C000r-   Napduprotocoltuple[bytes, int, int]c                R   t                               t          d|                                           | j                            t          |          |          \  }}}t          |          }t                               t          d|                                ||           |||fS )zExchange data with smart card.

        :param apdu: byte string. data to exchange with card
        :return: byte string. response from card
        zSEND: %szRECV: %s SW=%02X%02X)loggerlogr   hexr!   transmitlistr@   )r&   rD   rE   respsw1sw2responses          r'   apdu_exchangezCtapPcscDevice.apdu_exchangek   s     	

$j$((**===,,T$ZZBBc3;;

$&<hllnncSVWWWc!!r-   r-   control_codecontrol_datac                @   t                               t          d|                                           | j                            |t          |                    }t          |          }t                               t          d|                                           |S )zSends control sequence to reader's driver.

        :param control_code: int. code to send to reader driver.
        :param control_data: byte string. data to send to driver
        :return: byte string. response
        zSend control: %szControl response: %s)rH   rI   r   rJ   r!   controlrL   r@   )r&   rR   rS   rP   s       r'   control_exchangezCtapPcscDevice.control_exchange{   sw     	

$&8,:J:J:L:LMMM:%%lD4F4FGG??

$&<hllnnMMMr-   Nonec                   dt          j        dt          t                              z   t          z   }|                     |          \  }}}||ft
          k    rt          d          |dk    r| xj        t          j	        z  c_        d S d S )Ns     !BzFIDO applet selection failure.s   U2F_V2)
structpacklenAID_FIDO_chained_apdu_exchange
SW_SUCCESSr%   r   r   NMSGr&   rD   rM   rN   rO   s        r'   r+   zCtapPcscDevice._select   s    "V[s8}}%E%EEP44T::c3:##=>>>9*/1 r-   clainsp1p2datac                    | j         rHt          j        d||||dt          |                    }|                     ||z             \  }}}	|||	fS t          |          dk    r~|d d         |dd          }}
t          j        dd|z  |||t          |
                    }|                     ||
z             \  }}}	||	ft
          k    r|||	fS t          |          dk    ~t          j        d||||          }|r(|t          j        dt          |                    |z   z  }|                     |dz             \  }}}	|t          k    rAd	t          j        d|	          z   }|                     |          \  }}}	||z  }|t          k    A|||	fS )
Nz!BBBBBHr      z!BBBBB   z!BBBBrY       s      )r   rZ   r[   r\   rQ   r_   SW1_MORE_DATA)r&   rb   rc   rd   re   rf   headerrM   rN   rO   to_sendrD   lress                r'   _chain_apduszCtapPcscDevice._chain_apdus   s     	"[Cb"dCIINNF!//>>ND#sc>!d))c// $TcT
DJXtcz3BGUU!%!3!3FW4D!E!Ec3:++c>) d))c// ;wS"b99D <D#d))44t;;!//w??ND#s&&*V[s-C-CC!%!3!3D!9!9c3 && c>!r-   c                H   t          |          dk    r=|d         dk    r1t          j        d|dd                   d         }|dd|z            }n+t          |          dk    rd}n|d         }|dd|z            }|d d         \  }}}}|                     |||||          S )N      r   z!H   r-   )r\   rZ   unpackro   )r&   rD   data_lenrf   rb   rc   rd   re   s           r'   r^   z%CtapPcscDevice._chained_apdu_exchange   s    t99>>d1gll}T4!955a8HAL()DDYY!^^DD AwHAL()D!"1"Xc2r  c2r4888r-   c                f    |                      |          \  }}}|t          j        d||          z   S )Nz!BB)r^   rZ   r[   ra   s        r'   
_call_apduzCtapPcscDevice._call_apdu   s4    44T::c3fk%c2222r-   eventEvent | Noneon_keepaliveCallable[[STATUS], None] | Nonec                H   |pt                      }| j        rdnd}|                     dd|d|          \  }}}d }d}	 ||ft          k    rjt	          |d                   }	|r||	k    r|	} ||	           |                    d          rd}|                     dd|d          \  }}}||ft          k    jnA# t          $ r4 t                              d           |                     dddd            w xY w||ft          k    rt          t          j        j                  |S )N   r   ri   g?   z!Keyboard interrupt, cancelling...)r   r    ro   	SW_UPDATEr   waitKeyboardInterruptrH   debugr_   r   ERROTHER)
r&   rf   rx   rz   rd   rM   rN   rO   last_ka	ka_statuss
             r'   
_call_cborzCtapPcscDevice._call_cbor   sZ      1;TTt**4r4FFc3 	*	))"47OO	 ,Gy$8$8'G L+++::c?? B!%!2!24r4!H!Hc3 *	)) ! 	 	 	LL<===dD$555		 :##IM/000s   A7B6 6>C4cmdc                    |t           j        k    r|                     |||          S |t           j        k    r|                     |          S t          t
          j        j                  r*   )r   r$   r   MSGrw   r   r   INVALID_COMMAND)r&   r   rf   rx   rz   s        r'   r#   zCtapPcscDevice.call   sY     ',??4===GK??4(((IM9:::r-   Freleaseboolc                    | j                                          |r0t          | j         d          r| j                                          d S d S d S )Nr   )r!   
disconnecthasattrr   )r&   r   s     r'   closezCtapPcscDevice.close   s_    
 	!wtz955 	!J     	! 	! 	! 	!r-    Iterator[CtapPcscDevice]c              #     K   t                      D ]d}||j        v rY	  | |                                |j                  V  2# t          $ r%}t                              d|           Y d }~\d }~ww xY wed S )NzError %r)_list_readersr   createConnection	ExceptionrH   r   )clsr   readeres       r'   list_deviceszCtapPcscDevice.list_devices   s      #oo 	0 	0Fv{""0#f5577EEEEEE  0 0 0LLQ////////0 #	0 	0s   %A
A2A--A2)r   r   r   r   )r1   r2   )r1   r   )r1   r8   )r1   r=   )r1   r@   r*   )rD   r@   rE   r=   r1   rF   )r-   )rR   r2   rS   r@   r1   r@   )r1   rW   )rb   r2   rc   r2   rd   r2   re   r2   rf   r@   r1   rF   )rD   r@   r1   rF   )rD   r@   r1   r@   )r-   NN)rf   r@   rx   ry   rz   r{   r1   r@   )
r   r2   rf   r@   rx   ry   rz   r{   r1   r@   )F)r   r   r1   rW   )r   )r   r   r1   r   )__name__
__module____qualname____doc__r(   r"   r0   propertyr5   r7   r;   r?   rC   rQ   rV   r+   ro   r^   rw   r   r#   r   classmethodr   r:   r-   r'   r   r   6   s        7 7 7 7  / / / A A A XA " " " X"    X    X1 1 1 1
 37" " " " "     2 2 2 2 CF" " " " "09 9 9 93 3 3 3 "8<	" " " " "N "8<; ; ; ; ;! ! ! ! !
 0 0 0 0 [0 0 0r-   r   c                     	 t          j                    S # t          $ r;} 	 ddlm} d |_        t          j                    cY d } ~ S # t          $ r | w xY wd } ~ ww xY w)Nr   )PCSCContext)r   readersr
   smartcard.pcsc.PCSCContextr   instanceImportError)r   r   s     r'   r   r      s    ~   	>>>>>>#'K >######## 	 	 	G	s%    
AAAAAA)#
__future__r   loggingrZ   	threadingr   typingr   r   	smartcardr   smartcard.CardConnectionr   !smartcard.CardConnectionDecoratorr	   smartcard.pcsc.PCSCExceptionsr
   ctapr   r   r   hidr   r   utilsr   r]   r_   r   rk   	getLoggerr   rH   r   r   r:   r-   r'   <module>r      sY  : # " " " " "         % % % % % % % %       3 3 3 3 3 3 E E E E E E > > > > > > / / / / / / / / / / $ $ $ $ $ $ $ $ $ $ $ $ $ $.
	 
	8	$	$E0 E0 E0 E0 E0Z E0 E0 E0P    r-   