fixed import of CV certificates. Terminal's signature is currently wrongly checked (as 'invalid').

git-svn-id: https://vsmartcard.svn.sourceforge.net/svnroot/vsmartcard@692 96b47cad-a561-4643-ad3b-153ac7d7599c
This commit is contained in:
frankmorgner
2012-01-23 14:53:28 +00:00
parent 18036bb4de
commit 97c51d320d

View File

@@ -22,7 +22,7 @@ from virtualsmartcard.SWutils import SwError, SW
from virtualsmartcard.ConstantDefinitions import CRT_TEMPLATE, SM_Class
from virtualsmartcard.TLVutils import unpack, bertlv_pack
from virtualsmartcard.SmartcardFilesystem import make_property
from virtualsmartcard.utils import inttostring
from virtualsmartcard.utils import inttostring, hexdump
import virtualsmartcard.CryptoUtils as vsCrypto
from chat import CHAT
import pace
@@ -74,6 +74,7 @@ class nPA_AT_CRT(ControlReferenceTemplate):
# handled by ControlReferenceTemplate.parse_SE_config
pass
elif tag == 0x91:
#print "saving eph_pub_key"
self.eph_pub_key = value
else:
raise SwError(SW["ERR_REFNOTUSABLE"])
@@ -198,6 +199,7 @@ class nPA_SE(Security_Environment):
ef_card_access = self.mf.select('fid', 0x011c)
ef_card_access_data = ef_card_access.getenc('data')
pace.EAC_CTX_init_ef_cardaccess(ef_card_access_data, self.eac_ctx)
pace.EAC_CTX_init_ca(self.eac_ctx, pace.id_CA_DH_AES_CBC_CMAC_128, 13, None, None)
nonce = pace.buf2string(pace.PACE_STEP1_enc_nonce(self.eac_ctx, self.sec))
resp = nPA_SE.__pack_general_authenticate([[0x80, len(nonce), nonce]])
@@ -224,7 +226,11 @@ class nPA_SE(Security_Environment):
def __eac_pace_step3(self, data):
tlv_data = nPA_SE.__unpack_general_authenticate(data)
my_epp_pubkey = pace.buf2string(pace.PACE_STEP3B_generate_ephemeral_key(self.eac_ctx))
self.my_pace_eph_pubkey = pace.PACE_STEP3B_generate_ephemeral_key(self.eac_ctx)
if not self.my_pace_eph_pubkey:
pace.print_ossl_err()
raise SwError(SW["WARN_NOINFO63"])
eph_pubkey = pace.buf2string(self.my_pace_eph_pubkey)
for tag, length, value in tlv_data:
if tag == 0x83:
@@ -235,7 +241,7 @@ class nPA_SE(Security_Environment):
self.eac_step += 1
return 0x9000, nPA_SE.__pack_general_authenticate([[0x84, len(my_epp_pubkey), my_epp_pubkey]])
return 0x9000, nPA_SE.__pack_general_authenticate([[0x84, len(eph_pubkey), eph_pubkey]])
def __eac_pace_step4(self, data):
tlv_data = nPA_SE.__unpack_general_authenticate(data)
@@ -265,10 +271,12 @@ class nPA_SE(Security_Environment):
print "PIN unblocked"
self.eac_step += 1
self.at.algorithm = "TA"
self.ssc = 0
pace.EAC_CTX_set_encryption_ctx(self.eac_ctx, pace.EAC_ID_PACE)
pace.EAC_CTX_init_ta(self.eac_ctx, None, None, self.ca)
return 0x9000, nPA_SE.__pack_general_authenticate([[0x86, len(my_token), my_token],
[0x87, len(self.ca), self.ca]])
@@ -298,26 +306,46 @@ class nPA_SE(Security_Environment):
if (p1, p2) != (0x00, 0xbe):
raise SwError(SW["ERR_INCORRECTPARAMETERS"])
cert = bertlv_pack([[0x7f, len(data), data]])
cert = bertlv_pack([[0x7f21, len(data), data]])
if 1 != pace.TA_STEP2_import_certificate(self.eac_ctx, cert):
pace.print_ossl_err()
raise SwError(SW["ERR_NOINFO69"])
return 0x9000, ""
def external_authenticate(self, p1, p2, data):
"""
Authenticate the terminal to the card. Check whether Terminal correctly
encrypted the given challenge or not
"""
if self.at.algorithm == "TA":
if self.last_challenge is None:
if self.dst.keyref: # TODO check if this is the correct CAR
if self.sam.last_challenge is None:
raise SwError(SW["ERR_CONDITIONNOTSATISFIED"])
pace.EAC_CTX_init_ta(self.eac_ctx, "", 0, self.dst.keyref,
len(self.dst.keyref), "", 0)
id_picc = pace.EAC_Comp(self.eac_ctx, pace.EAC_ID_PACE, self.my_pace_eph_pubkey)
# FIXME auxiliary_data might be from an older run of PACE
if hasattr(self, "auxiliary_data"):
auxiliary_data = pace.get_buf(self.auxiliary_data)
else:
auxiliary_data = None
#print "at.eph_pub_key"
#print hexdump(self.at.eph_pub_key)
#print "my_pace_eph_pubkey"
#print hexdump(pace.buf2string(self.my_pace_eph_pubkey))
#print "data"
#print hexdump(data)
#if self.auxiliary_data:
#print "auxiliary_data"
#print hexdump(self.auxiliary_data)
#else:
#print "auxiliary_data"
#print "None"
if 1 != pace.TA_STEP6_verify(self.eac_ctx,
pace.get_buf(self.at.eph_pub_key), id_picc,
pace.get_buf(self.auxiliary_data), pace.get_buf(data)):
auxiliary_data, pace.get_buf(data)):
pace.print_ossl_err()
raise SwError(SW["ERR_CONDITIONNOTSATISFIED"])
@@ -336,7 +364,8 @@ class nPA_SE(Security_Environment):
return 0x9000, checksum
def encipher(self, p1, p2, data):
cipher = pace.EAC_encrypt(self.eac_ctx, self.ssc, data)
padded = vsCrypto.append_padding(self.cct.blocklength, data)
cipher = pace.EAC_encrypt(self.eac_ctx, self.ssc, padded)
if not cipher:
pace.print_ossl_err()
raise SwError(SW["ERR_NOINFO69"])
@@ -453,6 +482,24 @@ class nPA_SAM(SAM):
return 0x9000, ""
def external_authenticate(self, p1, p2, data):
return self.current_SE.external_authenticate(p1, p2, data)
def get_challenge(self, p1, p2, data):
if self.current_SE.eac_step == 4:
# TA
if (p1 != 0x00 or p2 != 0x00):
raise SwError(SW["ERR_INCORRECTP1P2"])
self.last_challenge = pace.buf2string(pace.TA_STEP4_get_nonce(self.current_SE.eac_ctx))
if not self.last_challenge:
pace.print_ossl_err()
raise SwError(SW["ERR_NOINFO69"])
else:
SAM.get_challenge(self, p1, p2, data)
return SW["NORMAL"], self.last_challenge
def parse_SM_CAPDU(self, CAPDU, header_authentication):
self.current_SE.ssc += 1
return SAM.parse_SM_CAPDU(self, CAPDU, header_authentication)