def bytestr(self): """ Get byte string representation of TLV, depending on type. """ # BER, COMPREH: length as in ISO 8825-1 aka X.690 # COMPACT: length 00-FE or FF xx yy tags = int2s(self.tag) l = len(self.value) if self.typ == TLV.COMPACT: if l < 0xFF: lens = chr(l) else: lens = '\xFF' + pack(">H", l) else: lens = derLen(l) return tags + lens + self.value
def bytestr(self): """ Get byte string representation of TLV, depending on type. """ # BER, COMPREH: length as in ISO 8825-1 aka X.690 # COMPACT: length 00-FE or FF xx yy tags = int2s(self.tag) l = len(self.value) if self.typ == TLV.COMPACT: if l < 0xFF: lens = chr(l) else: lens = "\xFF" + pack(">H", l) else: lens = derLen(l) return tags + lens + self.value
def berlv(strval): """ Prepend length (coded as ASN1 DER) of the strval and return as LV.""" return derLen(strval) + strval
def putKey( oldKeyVersion, newKeyVersion, keyId, keyComponents, zMoreCmd = False, zMultiKey = False, keyDEK = None, lenMAC = 8 ): """Build APDU for PUT KEY command. oldKeyVersion - key version to be replaced. If zero, new key is created. newKeyVersion - key version of key being put keyId - id of the 1st key being put keyComponents - list of key components being put. Each componet is a tuple of key type (u8) and value (string). zMoreCmd - P1.b8, signals if there is more commands zMultiKey - P2.b8, signals if more than one component being put keyDEK - KIK or DEK key. keyDEK.encrypt( data ) called to encrypt (including padding) key component value if not None. If has attribute zAES and keyDEK.zAES evaluates as True, it is considered as AES key and [GP AmD] 7.2 formatting is used. lenMAC - length of CMAC for AES. Applicable if AES key with key id=0x02 (KID) and key version 0x01-0x0F or 0x11 is being put with AES keyDEK (see ETSI 102.226 rel 9+, 8.2.1.5 ) Returns APDU built (as list of u8). See [GP CS] 11.8 and [GP AmD] 7.2 for reference. See [GP CS] Tab 11.16 for coding of key type. Currently only Format1 supported. """ # sanity check assert 0 <= oldKeyVersion < 0x80 assert 0 < newKeyVersion < 0x80 assert 0 < keyId < 0x80 assert len( keyComponents ) > 0 assert lenMAC in ( 4, 8 ) P1 = ( zMoreCmd and 0x80 or 0 ) | oldKeyVersion P2 = ( zMultiKey and 0x80 or 0 ) | keyId data = chr( newKeyVersion ) for kc in keyComponents: keyType, keyVal = kc assert 0 <= keyType < 0xFF if keyDEK: encValue = keyDEK.encrypt( keyVal ) # for AES as keyDEK, prepend length of component if 'zAES' in dir( keyDEK ) and keyDEK.zAES: encValue = derLen( keyVal ) + encValue # see ETSI 102.226 rel 9+, 8.2.1.5 if keyType == KeyType.AES and keyId == 2 and \ newKeyVersion in range( 0x01, 0x10 ) + [ 0x11 ]: encValue += chr( lenMAC ) else: encValue = keyVal # calculate KCV if keyType in ( KeyType.DES_IMPLICIT, KeyType.TDES_CBC, KeyType.DES_ECB, KeyType.DES_CBC, KeyType.AES ): kcv = calcKCV( keyVal, keyType == KeyType.AES ) else: kcv = '' data += chr( keyType ) + derLen( encValue ) + encValue + derLen( kcv ) + kcv keyId += 1 apdu = [ 0x80, INS_PUTKEY, P1, P2, len( data ) ] + [ ord(x) for x in data ] return apdu
def berlv( strval ): """ Prepend length (coded as ASN1 DER) of the strval and return as LV.""" return derLen( strval ) + strval
def putKey(oldKeyVersion, newKeyVersion, keyId, keyComponents, zMoreCmd=False, zMultiKey=False, keyDEK=None, lenMAC=8): """Build APDU for PUT KEY command. oldKeyVersion - key version to be replaced. If zero, new key is created. newKeyVersion - key version of key being put keyId - id of the 1st key being put keyComponents - list of key components being put. Each componet is a tuple of key type (u8) and value (string). zMoreCmd - P1.b8, signals if there is more commands zMultiKey - P2.b8, signals if more than one component being put keyDEK - KIK or DEK key. keyDEK.encrypt( data ) called to encrypt (including padding) key component value if not None. If has attribute zAES and keyDEK.zAES evaluates as True, it is considered as AES key and [GP AmD] 7.2 formatting is used. lenMAC - length of CMAC for AES. Applicable if AES key with key id=0x02 (KID) and key version 0x01-0x0F or 0x11 is being put with AES keyDEK (see ETSI 102.226 rel 9+, 8.2.1.5 ) Returns APDU built (as list of u8). See [GP CS] 11.8 and [GP AmD] 7.2 for reference. See [GP CS] Tab 11.16 for coding of key type. Currently only Format1 supported. """ # sanity check assert 0 <= oldKeyVersion < 0x80 assert 0 < newKeyVersion < 0x80 assert 0 < keyId < 0x80 assert len(keyComponents) > 0 assert lenMAC in (4, 8) P1 = (zMoreCmd and 0x80 or 0) | oldKeyVersion P2 = (zMultiKey and 0x80 or 0) | keyId data = chr(newKeyVersion) for kc in keyComponents: keyType, keyVal = kc assert 0 <= keyType < 0xFF if keyDEK: encValue = keyDEK.encrypt(keyVal) # for AES as keyDEK, prepend length of component if 'zAES' in dir(keyDEK) and keyDEK.zAES: encValue = derLen(keyVal) + encValue # see ETSI 102.226 rel 9+, 8.2.1.5 if keyType == KeyType.AES and keyId == 2 and \ newKeyVersion in range( 0x01, 0x10 ) + [ 0x11 ]: encValue += chr(lenMAC) else: encValue = keyVal # calculate KCV if keyType in (KeyType.DES_IMPLICIT, KeyType.TDES_CBC, KeyType.DES_ECB, KeyType.DES_CBC, KeyType.AES): kcv = calcKCV(keyVal, keyType == KeyType.AES) else: kcv = '' data += chr(keyType) + derLen(encValue) + encValue + derLen(kcv) + kcv keyId += 1 apdu = [0x80, INS_PUTKEY, P1, P2, len(data)] + [ord(x) for x in data] return apdu