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:
@@ -22,7 +22,7 @@ from virtualsmartcard.SWutils import SwError, SW
|
|||||||
from virtualsmartcard.ConstantDefinitions import CRT_TEMPLATE, SM_Class
|
from virtualsmartcard.ConstantDefinitions import CRT_TEMPLATE, SM_Class
|
||||||
from virtualsmartcard.TLVutils import unpack, bertlv_pack
|
from virtualsmartcard.TLVutils import unpack, bertlv_pack
|
||||||
from virtualsmartcard.SmartcardFilesystem import make_property
|
from virtualsmartcard.SmartcardFilesystem import make_property
|
||||||
from virtualsmartcard.utils import inttostring
|
from virtualsmartcard.utils import inttostring, hexdump
|
||||||
import virtualsmartcard.CryptoUtils as vsCrypto
|
import virtualsmartcard.CryptoUtils as vsCrypto
|
||||||
from chat import CHAT
|
from chat import CHAT
|
||||||
import pace
|
import pace
|
||||||
@@ -74,6 +74,7 @@ class nPA_AT_CRT(ControlReferenceTemplate):
|
|||||||
# handled by ControlReferenceTemplate.parse_SE_config
|
# handled by ControlReferenceTemplate.parse_SE_config
|
||||||
pass
|
pass
|
||||||
elif tag == 0x91:
|
elif tag == 0x91:
|
||||||
|
#print "saving eph_pub_key"
|
||||||
self.eph_pub_key = value
|
self.eph_pub_key = value
|
||||||
else:
|
else:
|
||||||
raise SwError(SW["ERR_REFNOTUSABLE"])
|
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 = self.mf.select('fid', 0x011c)
|
||||||
ef_card_access_data = ef_card_access.getenc('data')
|
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_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))
|
nonce = pace.buf2string(pace.PACE_STEP1_enc_nonce(self.eac_ctx, self.sec))
|
||||||
resp = nPA_SE.__pack_general_authenticate([[0x80, len(nonce), nonce]])
|
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):
|
def __eac_pace_step3(self, data):
|
||||||
tlv_data = nPA_SE.__unpack_general_authenticate(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:
|
for tag, length, value in tlv_data:
|
||||||
if tag == 0x83:
|
if tag == 0x83:
|
||||||
@@ -235,7 +241,7 @@ class nPA_SE(Security_Environment):
|
|||||||
|
|
||||||
self.eac_step += 1
|
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):
|
def __eac_pace_step4(self, data):
|
||||||
tlv_data = nPA_SE.__unpack_general_authenticate(data)
|
tlv_data = nPA_SE.__unpack_general_authenticate(data)
|
||||||
@@ -265,10 +271,12 @@ class nPA_SE(Security_Environment):
|
|||||||
print "PIN unblocked"
|
print "PIN unblocked"
|
||||||
|
|
||||||
self.eac_step += 1
|
self.eac_step += 1
|
||||||
|
self.at.algorithm = "TA"
|
||||||
|
|
||||||
self.ssc = 0
|
self.ssc = 0
|
||||||
|
|
||||||
pace.EAC_CTX_set_encryption_ctx(self.eac_ctx, pace.EAC_ID_PACE)
|
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],
|
return 0x9000, nPA_SE.__pack_general_authenticate([[0x86, len(my_token), my_token],
|
||||||
[0x87, len(self.ca), self.ca]])
|
[0x87, len(self.ca), self.ca]])
|
||||||
@@ -298,26 +306,46 @@ class nPA_SE(Security_Environment):
|
|||||||
if (p1, p2) != (0x00, 0xbe):
|
if (p1, p2) != (0x00, 0xbe):
|
||||||
raise SwError(SW["ERR_INCORRECTPARAMETERS"])
|
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):
|
if 1 != pace.TA_STEP2_import_certificate(self.eac_ctx, cert):
|
||||||
pace.print_ossl_err()
|
pace.print_ossl_err()
|
||||||
raise SwError(SW["ERR_NOINFO69"])
|
raise SwError(SW["ERR_NOINFO69"])
|
||||||
|
|
||||||
|
return 0x9000, ""
|
||||||
|
|
||||||
def external_authenticate(self, p1, p2, data):
|
def external_authenticate(self, p1, p2, data):
|
||||||
"""
|
"""
|
||||||
Authenticate the terminal to the card. Check whether Terminal correctly
|
Authenticate the terminal to the card. Check whether Terminal correctly
|
||||||
encrypted the given challenge or not
|
encrypted the given challenge or not
|
||||||
"""
|
"""
|
||||||
if self.at.algorithm == "TA":
|
if self.dst.keyref: # TODO check if this is the correct CAR
|
||||||
if self.last_challenge is None:
|
if self.sam.last_challenge is None:
|
||||||
raise SwError(SW["ERR_CONDITIONNOTSATISFIED"])
|
raise SwError(SW["ERR_CONDITIONNOTSATISFIED"])
|
||||||
|
|
||||||
pace.EAC_CTX_init_ta(self.eac_ctx, "", 0, self.dst.keyref,
|
id_picc = pace.EAC_Comp(self.eac_ctx, pace.EAC_ID_PACE, self.my_pace_eph_pubkey)
|
||||||
len(self.dst.keyref), "", 0)
|
|
||||||
|
# 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,
|
if 1 != pace.TA_STEP6_verify(self.eac_ctx,
|
||||||
pace.get_buf(self.at.eph_pub_key), id_picc,
|
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()
|
pace.print_ossl_err()
|
||||||
raise SwError(SW["ERR_CONDITIONNOTSATISFIED"])
|
raise SwError(SW["ERR_CONDITIONNOTSATISFIED"])
|
||||||
|
|
||||||
@@ -336,7 +364,8 @@ class nPA_SE(Security_Environment):
|
|||||||
return 0x9000, checksum
|
return 0x9000, checksum
|
||||||
|
|
||||||
def encipher(self, p1, p2, data):
|
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:
|
if not cipher:
|
||||||
pace.print_ossl_err()
|
pace.print_ossl_err()
|
||||||
raise SwError(SW["ERR_NOINFO69"])
|
raise SwError(SW["ERR_NOINFO69"])
|
||||||
@@ -453,6 +482,24 @@ class nPA_SAM(SAM):
|
|||||||
|
|
||||||
return 0x9000, ""
|
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):
|
def parse_SM_CAPDU(self, CAPDU, header_authentication):
|
||||||
self.current_SE.ssc += 1
|
self.current_SE.ssc += 1
|
||||||
return SAM.parse_SM_CAPDU(self, CAPDU, header_authentication)
|
return SAM.parse_SM_CAPDU(self, CAPDU, header_authentication)
|
||||||
|
|||||||
Reference in New Issue
Block a user