def __init__(self, PIN, cardNumber, mf=None, cardSecret=None, default_se=Security_Environment): self.PIN = PIN self.mf = mf self.cardNumber = cardNumber self.last_challenge = None #Will contain non-readable binary string self.counter = 3 #Number of tries for PIN validation self.cipher = 0x01 self.asym_key = None keylen = vsCrypto.get_cipher_keylen(get_referenced_cipher(self.cipher)) if cardSecret is None: #Generate a random card secret self.cardSecret = urandom(keylen) else: if len(cardSecret) != keylen: raise ValueError("cardSecret has the wrong key length for: " +\ get_referenced_cipher(self.cipher)) else: self.cardSecret = cardSecret #Security Environments may be saved to/retrieved from this dictionary self.saved_SEs = {} self.default_se = default_se self.current_SE = default_se(self.mf, self)
def _get_referenced_key(self, p1, p2): """ This method returns the key specified by the p2 parameter. The key may be stored on the cards filesystem. :param p1: Specifies the algorithm to use. Needed to know the keylength. :param p2: Specifies a reference to the key to be used for encryption == == == == == == == == ============================================= b8 b7 b6 b5 b4 b3 b2 b1 Meaning == == == == == == == == ============================================= 0 0 0 0 0 0 0 0 No information is given 0 - - - - - - - Global reference data(e.g. MF specific key) 1 - - - - - - - Specific reference data(e.g. DF specific key) - - - x x x x x Number of the secret == == == == == == == == ============================================= Any other value RFU """ key = None qualifier = p2 & 0x1F algo = get_referenced_cipher(p1) keylength = vsCrypto.get_cipher_keylen(algo) if (p2 == 0x00): #No information given, use the global card key key = self.cardSecret #We treat global and specific reference data alike #elif ((p2 >> 7) == 0x01 or (p2 >> 7) == 0x00): else: #Interpret qualifier as an short fid (try to read the key from FS) if self.mf == None: raise SwError(SW["ERR_REFNOTUSABLE"]) df = self.mf.currentDF() fid = df.select("fid", stringtoint(qualifier)) key = fid.readbinary(keylength) if key != None: return key else: raise SwError(SW["ERR_REFNOTUSABLE"])