def test_get_clear_pin_improper_length(self): with self.assertRaisesRegex(ValueError, 'Incorrect PIN length: 223'): get_clear_pin(b'DF1267EEDCBA9876', b'881123456789')
def test_get_clear_pin_pin_length_9(self): with self.assertRaisesRegex(ValueError, 'Incorrect PIN length: 9'): get_clear_pin(b'091267EEDCBA9876', b'881123456789')
def test_get_clear_pin_1234(self): self.assertEqual(get_clear_pin(b'0412BCEEDCBA9876', b'881123456789'), b'1234')
def test_get_clear_pin_non_numeric(self): with self.assertRaisesRegex(ValueError, 'PIN contains non-numeric characters'): get_clear_pin(b'041267EEDCBA9876', b'881123456789')
def verify_pin(self, request): """ Get response to DC or EC command """ response = OutgoingMessage(data=None, header=self.header) command_code = request.get_command_code() if command_code == b'DC': response.set_response_code('DD') key_type = 'TPK' elif command_code == b'EC': response.set_response_code('ED') key_type = 'ZPK' if not self.check_key_parity(request.get(key_type)): self._debug_trace(key_type + ' parity error') if self.approve_all: self._debug_trace( 'Forced approval as --approve-all option set') response.set_error_code('00') else: response.set_error_code('10') return response if not self.check_key_parity(request.get('PVK Pair')): self._debug_trace('PVK parity error') if self.approve_all: self._debug_trace( 'Forced approval as --approve-all option set') response.set_error_code('00') else: response.set_error_code('11') return response if len(request.get('PVK Pair')) != 32: self._debug_trace('PVK not double length') if self.approve_all: self._debug_trace( 'Forced approval as --approve-all option set') response.set_error_code('00') else: response.set_error_code('27') return response decrypted_pinblock = self._decrypt_pinblock(request.get('PIN block'), request.get(key_type)) self._debug_trace('Decrypted pinblock: {}'.format( decrypted_pinblock.decode('utf-8'))) try: pin = get_clear_pin(decrypted_pinblock, request.get('Account Number')) pvv = get_visa_pvv(request.get('Account Number'), request.get('PVKI'), pin[:4], request.get('PVK Pair')) if pvv == request.get('PVV'): response.set_error_code('00') else: self._debug_trace('PVV mismatch: {} != {}'.format( pvv.decode('utf-8'), request.get('PVV').decode('utf-8'))) if self.approve_all: self._debug_trace( 'Forced approval as --approve-all option set') response.set_error_code('00') else: response.set_error_code('01') return response except ValueError as err: self._debug_trace(err) if self.approve_all: self._debug_trace( 'Forced approval as --approve-all option set') response.set_error_code('00') else: response.set_error_code('01') return response