o
    sh"                     @  s   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 dl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mZ d dlZd dlZdZdZdZdZe e!Z"G dd deZ#dd Z$dS )    )annotations   )
CtapDevice	CtapErrorSTATUS)
CAPABILITYCTAPHID)LOG_LEVEL_TRAFFIC)System)CardConnection)ListReadersException)PCSCContext)Event)TupleOptionalCallableIteratorNs     G/ )   r   )   r   a   c                   @  s   e Zd ZdZdDddZdd	 Zd
d ZedEddZedFddZ	edGddZ
edHddZdIddZ	dJdKd d!ZdLdMd%d&ZdNd(d)Z	"dLdOd/d0ZdPd1d2ZdQd3d4Z	"		dRdSd9d:Z	"		dRdTd<d=ZdNd>d?ZedUdVdBdCZdS )WCtapPcscDevicezo
    CtapDevice implementation using pyscard (PCSC).

    This class is intended for use with NFC readers.
    
connectionr   namestrc                 C  sl   || _ td| _d| _|| _|   z| tjd |  jtjO  _W d S  t	y5   | js2t
dY d S w )Nr   F   zUnsupported device)_namer   _capabilitiesuse_ext_apdu_connconnectcallr   CBORr   
ValueError)selfr   r    r$   E/var/www/html/env_mimamsha/lib/python3.10/site-packages/fido2/pcsc.py__init__=   s   
zCtapPcscDevice.__init__c                 C  s   | j   |   d S N)r   r   _selectr#   r$   r$   r%   r   K   s   
zCtapPcscDevice.connectc                 C  s   d| j  dS )NzCtapPcscDevice())r   r)   r$   r$   r%   __repr__O      zCtapPcscDevice.__repr__returnintc                 C  s   t j| jv rdS dS )zCTAPHID protocol version.   r   )r   r!   r   r)   r$   r$   r%   versionR   s   zCtapPcscDevice.versionr   c                 C  s   | j S )z%Capabilities supported by the device.)r   r)   r$   r$   r%   capabilitiesW   s   zCtapPcscDevice.capabilitiesOptional[str]c                 C     dS )zProduct name of device.Nr$   r)   r$   r$   r%   product_name\      zCtapPcscDevice.product_nameOptional[int]c                 C  r3   )zSerial number of device.Nr$   r)   r$   r$   r%   serial_numbera   r5   zCtapPcscDevice.serial_numberbytesc                 C  s   t | j S )z&Get the ATR/ATS of the connected card.)r8   r   getATRr)   r$   r$   r%   get_atrf   s   zCtapPcscDevice.get_atrNapduprotocolTuple[bytes, int, int]c                 C  sR   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listr8   )r#   r;   r<   respsw1sw2responser$   r$   r%   apdu_exchangej   s
   	
zCtapPcscDevice.apdu_exchange    control_codecontrol_datac                 C  sB   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)r>   r?   r	   r@   r   controlrB   r8   )r#   rI   rJ   rF   r$   r$   r%   control_exchangez   s
   zCtapPcscDevice.control_exchangeNonec                 C  s\   dt dtt t }| |\}}}||ftkrtd|dkr,|  jtj	O  _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#   r;   rC   rD   rE   r$   r$   r%   r(      s   zCtapPcscDevice._selectclainsp1p2datac              
   C  s:  | j rtd||||dt|}| || \}}}	|||	fS t|dkr[|d d |dd  }
}tdd|B |||t|
}| ||
 \}}}	||	ftkrU|||	fS t|dks%td||||}|rr|tdt|| 7 }| |d \}}}	|tkrd	td|	 }| |\}}}	||7 }|tks|||	fS )
Nz!BBBBBHr      z!BBBBB   z!BBBBrN       s      )r   rO   rP   rQ   rG   rT   SW1_MORE_DATA)r#   rW   rX   rY   rZ   r[   headerrC   rD   rE   to_sendr;   lresr$   r$   r%   _chain_apdus   s*   


zCtapPcscDevice._chain_apdusc                 C  s   t |dkr!|d dkr!td|dd d }|dd|  }nt |dkr*d}n|d }|dd|  }|d d \}}}}| |||||S )N      r   z!H   rH   )rQ   rO   unpackrc   )r#   r;   data_lenr[   rW   rX   rY   rZ   r$   r$   r%   rS      s   z%CtapPcscDevice._chained_apdu_exchangec                 C  s"   |  |\}}}|td|| S )Nz!BB)rS   rO   rP   rV   r$   r$   r%   
_call_apdu   s   zCtapPcscDevice._call_apdueventOptional[Event]on_keepalive"Optional[Callable[[STATUS], None]]c           	      C  s   |pt  }| dddd|\}}}d }| sN||ftkr@t|d }|r/||kr/|}|| | dddd\}}}||ftks||ftkrLttjj|S ttjj	)N   r]   r      )
r   rc   is_set	SW_UPDATEr   rT   r   ERROTHERKEEPALIVE_CANCEL)	r#   r[   rj   rl   rC   rD   rE   last_ka	ka_statusr$   r$   r%   
_call_cbor   s   
	zCtapPcscDevice._call_cborcmdc                 C  s8   |t jkr| |||S |t jkr| |S ttjjr'   )r   r!   rw   MSGri   r   rr   INVALID_COMMAND)r#   rx   r[   rj   rl   r$   r$   r%   r       s
   


zCtapPcscDevice.callc                 C  s   | j   d S r'   )r   
disconnectr)   r$   r$   r%   close   r,   zCtapPcscDevice.close Iterator[CtapPcscDevice]c                 c  sd    t  D ]+}||jv r/z| | |jV  W q ty. } ztd| W Y d }~qd }~ww qd S )NzError %r)_list_readersr   createConnection	Exceptionr>   debug)clsr   readerer$   r$   r%   list_devices   s   

zCtapPcscDevice.list_devices)r   r   r   r   )r-   r.   )r-   r   )r-   r2   )r-   r6   )r-   r8   r'   )r;   r8   r<   r6   r-   r=   )rH   )rI   r.   rJ   r8   r-   r8   )r-   rM   )rW   r.   rX   r.   rY   r.   rZ   r.   r[   r8   r-   r=   )r;   r8   r-   r=   )r;   r8   r-   r8   )rH   NN)r[   r8   rj   rk   rl   rm   r-   r8   )
rx   r.   r[   r8   rj   rk   rl   rm   r-   r8   )r}   )r   r   r-   r~   )__name__
__module____qualname____doc__r&   r   r+   propertyr0   r1   r4   r7   r:   rG   rL   r(   rc   rS   ri   rw   r    r|   classmethodr   r$   r$   r$   r%   r   6   sB    


	


r   c                   C  s,   zt  W S  ty   d t_t   Y S w r'   )r
   readersr   r   instancer$   r$   r$   r%   r      s   
r   )%
__future__r   ctapr   r   r   hidr   r   utilsr	   	smartcardr
   smartcard.CardConnectionr   smartcard.pcsc.PCSCExceptionsr   smartcard.pcsc.PCSCContextr   	threadingr   typingr   r   r   r   rO   loggingrR   rT   rq   r_   	getLoggerr   r>   r   r   r$   r$   r$   r%   <module>   s(   
 >