44from  hashlib  import  sha256 
55from  threading  import  Event 
66from  types  import  FunctionType 
7- from  typing  import  List , Optional 
7+ from  typing  import  List , Optional ,  Mapping ,  Any 
88
99import  keyring 
1010from  cryptography .hazmat .primitives  import  serialization 
1515from  fido2  import  webauthn 
1616from  fido2 .attestation  import  PackedAttestation 
1717from  fido2 .ctap  import  CtapError 
18- from  fido2 .ctap2  import  (
18+ from  fido2 .ctap2  import  AssertionResponse , AttestationResponse , Info 
19+ from  fido2 .webauthn  import  (
20+     Aaguid ,
1921    AttestedCredentialData ,
2022    AuthenticatorData ,
21-     AttestationObject ,
22-     AssertionResponse ,
23- )
24- from  fido2 .webauthn  import  (
2523    PublicKeyCredentialDescriptor ,
2624    PublicKeyCredentialType ,
2725    PublicKeyCredentialUserEntity ,
@@ -71,27 +69,28 @@ class CtapKeyringDevice(ctap.CtapDevice):
7169
7270    SUPPORTED_CTAP_VERSIONS  =  ['FIDO_2_0' ]
7371    MAX_MSG_SIZE  =  1  <<  20 
74-     AAGUID  =  b'pasten-ctap-1337' 
72+     AAGUID  =  Aaguid ( b'pasten-ctap-1337' ) 
7573
7674    def  __init__ (self ):
77-         self .capabilities  =  hid .CAPABILITY .CBOR 
78- 
7975        self ._ctap2_cmd_to_handler  =  {
8076            ctap2 .Ctap2 .CMD .MAKE_CREDENTIAL : self .make_credential ,
8177            ctap2 .Ctap2 .CMD .GET_ASSERTION : self .get_assertion ,
8278            ctap2 .Ctap2 .CMD .GET_NEXT_ASSERTION : self .get_next_assertion ,
8379            ctap2 .Ctap2 .CMD .GET_INFO : self .get_info ,
8480        }
8581
86-         self ._info  =  ctap2 .Info .create (
87-             self .SUPPORTED_CTAP_VERSIONS ,
82+         self ._info  =  Info (
83+             versions = self .SUPPORTED_CTAP_VERSIONS ,
84+             extensions = [],
8885            aaguid = self .AAGUID ,
8986            options = {
9087                CtapOptions .PLATFORM_DEVICE : True ,
9188                CtapOptions .RESIDENT_KEY : True ,
9289                CtapOptions .USER_PRESENCE : True ,
9390                CtapOptions .USER_VERIFICATION : True ,
91+                 CtapOptions .CLIENT_PIN : True ,
9492            },
93+             pin_uv_protocols = [ctap2 .PinProtocolV2 .VERSION ],
9594            max_msg_size = self .MAX_MSG_SIZE ,
9695            transports = [webauthn .AuthenticatorTransport .INTERNAL ],
9796            algorithms = cose .CoseKey .supported_algorithms (),
@@ -100,6 +99,10 @@ def __init__(self):
10099        self ._next_assertions_ctx : Optional [CtapGetNextAssertionContext ] =  None 
101100        self ._user_verifier  =  CtapUserVerifierFactory .create ()
102101
102+     @property  
103+     def  capabilities (self ) ->  int :
104+         return  hid .CAPABILITY .CBOR 
105+ 
103106    @classmethod  
104107    def  list_devices (cls ):
105108        if  isinstance (keyring .get_keyring (), FailKeyring ):
@@ -117,7 +120,7 @@ def call(
117120        # noinspection PyBroadException 
118121        try :
119122            res  =  self ._call (cmd , data , event , on_keepalive )
120-             return  self ._wrap_err_code (CtapError .ERR .SUCCESS ) +  res 
123+             return  self ._wrap_err_code (CtapError .ERR .SUCCESS ) +  cbor . encode ( res ) 
121124        except  CtapError  as  e :
122125            return  self ._wrap_err_code (e .code )
123126        except  Exception :
@@ -147,7 +150,7 @@ def _call(
147150
148151        # noinspection PyBroadException 
149152        try :
150-             ctap2_req : dict  =  cbor .decode (data [1 :])
153+             ctap2_req : Mapping [ Any ,  Any ]  =  cbor .decode (data [1 :])
151154        except  Exception :
152155            raise  CtapError (CtapError .ERR .INVALID_CBOR )
153156
@@ -161,10 +164,10 @@ def _call(
161164    def  _wrap_err_code (err : CtapError .ERR ) ->  bytes :
162165        return  err .to_bytes (1 , 'big' )
163166
164-     def  get_info (self ) ->  ctap2 . Info :
167+     def  get_info (self ) ->  Info :
165168        return  self ._info 
166169
167-     def  make_credential (self , make_credential_request : dict ) ->  AttestationObject :
170+     def  make_credential (self , make_credential_request : dict ) ->  AttestationResponse :
168171        # noinspection PyBroadException 
169172        request  =  CtapMakeCredentialRequest .create (make_credential_request )
170173        if  (
@@ -189,10 +192,10 @@ def make_credential(self, make_credential_request: dict) -> AttestationObject:
189192        )
190193
191194        attestation_statement  =  {'alg' : cred .algorithm , 'sig' : signature }
192-         attestation_object  =  AttestationObject . create (
195+         attestation_response  =  AttestationResponse (
193196            PackedAttestation .FORMAT , authenticator_data , attestation_statement 
194197        )
195-         return  attestation_object 
198+         return  attestation_response 
196199
197200    @classmethod  
198201    def  _create_credential (cls , request : CtapMakeCredentialRequest ) ->  Credential :
@@ -343,12 +346,18 @@ def _get_assertion(
343346        signature  =  self ._generate_signature (
344347            authenticator_data , request .client_data_hash , cred .private_key 
345348        )
346-         response  =  AssertionResponse .create (
347-             PublicKeyCredentialDescriptor (PublicKeyCredentialType .PUBLIC_KEY , cred .id ),
349+         response  =  AssertionResponse (
350+             PublicKeyCredentialDescriptor (
351+                 PublicKeyCredentialType .PUBLIC_KEY ,
352+                 cred .id ,
353+                 transports = [webauthn .AuthenticatorTransport .INTERNAL ],
354+             ).__dict__ ,
348355            authenticator_data ,
349356            signature ,
350-             user = PublicKeyCredentialUserEntity (cred .user_id , name = '' ),
351-             n_creds = len (ctx .creds ),
357+             user = PublicKeyCredentialUserEntity (
358+                 name = '' , id = cred .user_id .encode ('utf-8' ), display_name = '' 
359+             ).__dict__ ,
360+             number_of_credentials = len (ctx .creds ),
352361        )
353362        return  response 
354363
0 commit comments