smartpgp-cli: add getm-sm-key command

This commit is contained in:
Arnaud Fontaine 2020-05-15 10:36:47 +02:00
parent c23c620a1e
commit 01e05ed5ae
3 changed files with 49 additions and 0 deletions

View File

@ -38,6 +38,7 @@ VALID_COMMANDS={
'switch-p384': CardConnectionContext.cmd_switch_p384,
'switch-p521': CardConnectionContext.cmd_switch_p521,
'generate-sm-key': CardConnectionContext.cmd_generate_sm_key,
'get-sm-key': CardConnectionContext.cmd_get_sm_key,
'set-resetting-code': CardConnectionContext.cmd_set_resetting_code,
'unblock-pin': CardConnectionContext.cmd_unblock_pin,
'put-sm-key': CardConnectionContext.cmd_put_sm_key,

View File

@ -40,6 +40,7 @@ ACTIVATE = [0x00, 0x44, 0x00, 0x00]
ACTIVATE_FULL = [0x00, 0x44, 0x00, 0x01]
GET_SM_CURVE_OID = [0x00, 0xca, 0x00, 0xd4]
GENERATE_ASYMETRIC_KEYPAIR = [0x00, 0x47, 0x80, 0x00]
GET_ASYMETRIC_KEYPAIR = [0x00, 0x47, 0x81, 0x00]
ALGS_ALIASES = {
'ansix9p256r1': 'ansix9p256r1',
@ -232,6 +233,11 @@ def generate_sm_key(connection):
apdu = apdu + [0x00]
return _raw_send_apdu(connection,"Generate SM key",apdu)
def get_sm_key(connection):
apdu = assemble_with_len(GET_ASYMETRIC_KEYPAIR, [0xA6, 0x00])
apdu = apdu + [0x00]
return _raw_send_apdu(connection,"Get SM key",apdu)
def set_resetting_code(connection, resetting_code):
apdu = assemble_with_len([0x00, 0xDA, 0x00, 0xD3], ascii_encode_pin(resetting_code))
_raw_send_apdu(connection,"Define the resetting code (PUK)",apdu)

View File

@ -189,6 +189,48 @@ class CardConnectionContext:
f.write(pubkey_der)
f.close()
def cmd_get_sm_key(self):
if not self.output:
print "Missing output file name"
return
self.connect()
(data,sw1,sw2) = get_sm_key(self.connection)
if sw1!=0x90 or sw2!=0x00:
print "get_sm_key failed"
return
if len(data) < 4 or data[0]!=0x7f or data[1]!=0x49:
print "Strange reply for get_sm_key"
return
blob_len = data[2]
blob = data[3:]
assert(blob_len == len(blob))
if blob[0]!=0x86:
print "get_sm_key something not a public key"
return
assert(blob[1]==len(blob[2:]))
pubkey = blob[2:]
# get curve OID
curve_oid_der = get_sm_curve_oid(self.connection)
if not curve_oid_der:
print "Error getting SM curve OID"
return
(curve_oid,_) = der_decoder.decode(str(curve_oid_der))
# now format it to DER [RFC5480]
s = univ.Sequence()
oid_elliptic_curve_pubkey = univ.ObjectIdentifier('1.2.840.10045.2.1')
s.setComponentByPosition(0,oid_elliptic_curve_pubkey)
s.setComponentByPosition(1,curve_oid)
bs = univ.BitString("'%s'H" % binascii.hexlify(bytearray(pubkey)))
s2 = univ.Sequence()
s2.setComponentByPosition(0,s)
s2.setComponentByPosition(1,bs)
pubkey_der = der_encoder.encode(s2)
print binascii.hexlify(pubkey_der)
# and write result
with open(self.output,"wb") as f:
f.write(pubkey_der)
f.close()
def cmd_put_sm_key(self):
if self.input is None:
print "No input key file"