<s> from u2flib_server . jsapi import ( RegisterRequest , RegisterResponse , <EOL> SignRequest , SignResponse , DeviceRegistration ) <EOL> from u2flib_server . utils import ( certificate_from_der , pub_key_from_der , <EOL> subject_from_certificate , websafe_decode , <EOL> websafe_encode , rand_bytes , <EOL> verify_ecdsa_signature ) <EOL> from u2flib_server . yubicommon . compat import byte2int <EOL> import codecs <EOL> import struct <EOL> from cryptography . hazmat . primitives . serialization import Encoding <EOL> __all__ = [ <EOL> '<STR_LIT>' , <EOL> '<STR_LIT>' , <EOL> '<STR_LIT>' , <EOL> '<STR_LIT>' <EOL> ] <EOL> VERSION = '<STR_LIT>' <EOL> FIXSIG = [ <EOL> '<STR_LIT>' , <EOL> '<STR_LIT>' , <EOL> '<STR_LIT>' , <EOL> '<STR_LIT>' , <EOL> '<STR_LIT>' , <EOL> '<STR_LIT>' <EOL> ] <EOL> class RawRegistrationResponse ( object ) : <EOL> """<STR_LIT>""" <EOL> PUBKEY_LEN = <NUM_LIT> <EOL> def __init__ ( self , app_param , chal_param , data ) : <EOL> self . app_param = app_param <EOL> self . chal_param = chal_param <EOL> self . data = data <EOL> if byte2int ( data [ <NUM_LIT:0> ] ) != <NUM_LIT> : <EOL> raise ValueError ( "<STR_LIT>" % ( data , ) ) <EOL> data = data [ <NUM_LIT:1> : ] <EOL> self . pub_key = data [ : self . PUBKEY_LEN ] <EOL> data = data [ self . PUBKEY_LEN : ] <EOL> kh_len = byte2int ( data [ <NUM_LIT:0> ] ) <EOL> data = data [ <NUM_LIT:1> : ] <EOL> self . key_handle = data [ : kh_len ] <EOL> data = data [ kh_len : ] <EOL> self . certificate = self . _fixsig ( certificate_from_der ( data ) ) <EOL> self . signature = data [ len ( self . certificate . public_bytes ( Encoding . DER ) ) : ] <EOL> def __str__ ( self ) : <EOL> hex_bytes = codecs . encode ( self . data , '<STR_LIT>' ) <EOL> hex_text = codecs . decode ( hex_bytes , '<STR_LIT:ascii>' ) <EOL> return str ( hex_text ) <EOL> def verify_csr_signature ( self ) : <EOL> data = ( b'<STR_LIT:\x00>' + self . app_param + self . chal_param + <EOL> self . key_handle + self . pub_key ) <EOL> pub_key = self . certificate . public_key ( ) <EOL> verify_ecdsa_signature ( data , pub_key , self . signature ) <EOL> def _fixsig ( self , cert ) : <EOL> subject = '<STR_LIT>' + subject_from_certificate ( cert ) <EOL> if subject in FIXSIG : <EOL> der = cert . public_bytes ( Encoding . DER ) <EOL> der = der [ : - <NUM_LIT> ] + b'<STR_LIT:\x00>' + der [ - <NUM_LIT> : ] <EOL> cert = certificate_from_der ( der ) <EOL> return cert <EOL> def serialize ( self ) : <EOL> return websafe_encode ( self . app_param + self . chal_param + self . data ) <EOL> @ classmethod <EOL> def deserialize ( cls , serialized ) : <EOL> data = websafe_decode ( serialized ) <EOL> return cls ( data [ : <NUM_LIT:32> ] , data [ <NUM_LIT:32> : <NUM_LIT:64> ] , data [ <NUM_LIT:64> : ] ) <EOL> class RawAuthenticationResponse ( object ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , app_param , chal_param , data ) : <EOL> self . app_param = app_param <EOL> self . chal_param = chal_param <EOL> self . data = data <EOL> self . user_presence = data [ <NUM_LIT:0> : <NUM_LIT:1> ] <EOL> self . counter = data [ <NUM_LIT:1> : <NUM_LIT:5> ] <EOL> self . counter_int = struct . unpack ( '<STR_LIT>' , self . counter ) [ <NUM_LIT:0> ] <EOL> self . signature = data [ <NUM_LIT:5> : ] <EOL> def __str__ ( self ) : <EOL> hex_bytes = codecs . encode ( self . data , '<STR_LIT>' ) <EOL> hex_text = codecs . decode ( hex_bytes , '<STR_LIT:ascii>' ) <EOL> return str ( hex_text ) <EOL> def verify_signature ( self , pubkey ) : <EOL> data = ( self . app_param + self . user_presence + self . counter + <EOL> self . chal_param ) <EOL> pub_key = pub_key_from_der ( pubkey ) <EOL> verify_ecdsa_signature ( data , pub_key , self . signature ) <EOL> def serialize ( self ) : <EOL> return websafe_encode ( self . app_param + self . chal_param + self . data ) <EOL> @ classmethod <EOL> def deserialize ( cls , serialized ) : <EOL> data = websafe_decode ( serialized ) <EOL> return cls ( data [ : <NUM_LIT:32> ] , data [ <NUM_LIT:32> : <NUM_LIT:64> ] , data [ <NUM_LIT:64> : ] ) <EOL> def _validate_client_data ( client_data , challenge , typ , valid_facets ) : <EOL> """<STR_LIT>""" <EOL> if client_data . typ != typ : <EOL> raise ValueError ( "<STR_LIT>" % ( <EOL> client_data . typ , typ ) ) <EOL> if challenge != client_data . challenge : <EOL> raise ValueError ( "<STR_LIT>" % ( <EOL> client_data . challenge , challenge ) ) <EOL> if valid_facets is not None and client_data . origin not in valid_facets : <EOL> raise ValueError ( "<STR_LIT>" % ( <EOL> client_data . origin , valid_facets ) ) <EOL> def start_register ( app_id , challenge = None ) : <EOL> if challenge is None : <EOL> challenge = rand_bytes ( <NUM_LIT:32> ) <EOL> return RegisterRequest ( <EOL> version = VERSION , <EOL> appId = app_id , <EOL> challenge = websafe_encode ( challenge ) <EOL> ) <EOL> def complete_register ( request , response , valid_facets = None ) : <EOL> request = RegisterRequest . wrap ( request ) <EOL> response = RegisterResponse . wrap ( response ) <EOL> _validate_client_data ( response . clientData , request . challenge , <EOL> "<STR_LIT>" , valid_facets ) <EOL> raw_response = RawRegistrationResponse ( <EOL> request . appParam , <EOL> response . clientParam , <EOL> response . registrationData <EOL> ) <EOL> raw_response . verify_csr_signature ( ) <EOL> return DeviceRegistration ( <EOL> appId = request . appId , <EOL> keyHandle = websafe_encode ( raw_response . key_handle ) , <EOL> publicKey = websafe_encode ( raw_response . pub_key ) <EOL> ) , raw_response . certificate <EOL> def start_authenticate ( device , challenge = None ) : <EOL> device = DeviceRegistration . wrap ( device ) <EOL> if challenge is None : <EOL> challenge = rand_bytes ( <NUM_LIT:32> ) <EOL> return SignRequest ( <EOL> version = VERSION , <EOL> appId = device . appId , <EOL> keyHandle = device . keyHandle , <EOL> challenge = websafe_encode ( challenge ) <EOL> ) <EOL> def verify_authenticate ( device , request , response , valid_facets = None ) : <EOL> device = DeviceRegistration . wrap ( device ) <EOL> request = SignRequest . wrap ( request ) <EOL> response = SignResponse . wrap ( response ) <EOL> _validate_client_data ( response . clientData , request . challenge , <EOL> "<STR_LIT>" , valid_facets ) <EOL> raw_response = RawAuthenticationResponse ( <EOL> device . appParam , <EOL> response . clientParam , <EOL> response . signatureData <EOL> ) <EOL> raw_response . verify_signature ( websafe_decode ( device . publicKey ) ) <EOL> return raw_response . counter_int , raw_response . user_presence </s>
