Skip to content
This repository was archived by the owner on Mar 27, 2026. It is now read-only.

Commit 8f2a8ff

Browse files
committed
Use default VISA IPB (with warning) if IPB is not present on card
1 parent 6e1c9d9 commit 8f2a8ff

2 files changed

Lines changed: 43 additions & 16 deletions

File tree

emv/cap.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,30 @@
2424
]
2525
)
2626

27+
# A static Issuer Proprietary Bitmap which is apparently the default for VISA cards.
28+
# Retrieved from the EMVCAP code:
29+
# https://github.com/zoobab/EMVCAP/blob/0e4877c30972475249e6a2b0253068bfda9e5cf3/EMV-CAP#L519
30+
VISA_STATIC_IPB = [
31+
0x00,
32+
0x00,
33+
0xFF,
34+
0xFF,
35+
0xFF,
36+
0x00,
37+
0x00,
38+
0x00,
39+
0x00,
40+
0x00,
41+
0x00,
42+
0x00,
43+
0x00,
44+
0x00,
45+
0x00,
46+
0x20,
47+
0xB9,
48+
0x38,
49+
]
50+
2751

2852
def get_arqc_req(app_data, value=None, challenge=None):
2953
"""Generate the data to send with the generate application cryptogram request.

emv/card.py

Lines changed: 19 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from __future__ import division, absolute_import, print_function, unicode_literals
1+
import logging
22
from .transmission import TransmissionProtocol
33
from .protocol.structures import TLV
44
from .protocol.data import Tag
@@ -10,9 +10,11 @@
1010
GetProcessingOptions,
1111
VerifyCommand,
1212
)
13-
from .exc import InvalidPINException, MissingAppException, EMVProtocolError
13+
from .exc import InvalidPINException, MissingAppException
1414
from .util import decode_int
15-
from .cap import get_arqc_req, get_cap_value
15+
from .cap import get_arqc_req, get_cap_value, VISA_STATIC_IPB
16+
17+
log = logging.getLogger(__name__)
1618

1719

1820
class Card(object):
@@ -174,18 +176,6 @@ def generate_cap_value(self, pin, challenge=None, value=None):
174176
# of the data passed to the Get Application Cryptogram function.
175177
app_data = self.get_application_data(opts["AFL"])
176178

177-
# In some cases the IPB may not be present. EMVCAP uses the IPB:
178-
# 0000FFFFFF0000000000000000000020B938
179-
# for VISA cards which don't provide their own, but relies on a hard-coded
180-
# list of app names to work out which cards are VISA.
181-
#
182-
# It appears that Belgian cards use their own silliness.
183-
# https://github.com/zoobab/EMVCAP/blob/master/EMV-CAP#L512
184-
if Tag.IPB not in app_data:
185-
raise EMVProtocolError(
186-
"Issuer Proprietary Bitmap not found in application file"
187-
)
188-
189179
self.verify_pin(pin)
190180

191181
resp = self.tp.exchange(
@@ -199,4 +189,17 @@ def generate_cap_value(self, pin, challenge=None, value=None):
199189
if Tag.IAF in app_data and app_data[Tag.IAF][0] & 0x40:
200190
psn = app_data[Tag.PAN_SN]
201191

202-
return get_cap_value(resp, app_data[Tag.IPB], psn)
192+
# Fetch the Issuer Proprietary Bitmap. In most UK cards this is provided in the application data file.
193+
#
194+
# In some cases the IPB may not be present. This static IPB is from the EMVCAP code.
195+
#
196+
# It appears that Belgian cards use their own silliness.
197+
# https://github.com/zoobab/EMVCAP/blob/master/EMV-CAP#L512
198+
if Tag.IPB in app_data:
199+
ipb = app_data[Tag.IPB]
200+
else:
201+
log.warn("Issuer Proprietary Bitmap not found on card - using static VISA IPB. "
202+
"The resulting code may not work!")
203+
ipb = VISA_STATIC_IPB
204+
205+
return get_cap_value(resp, ipb, psn)

0 commit comments

Comments
 (0)