def dump_tsspem(db, obj, pin, is_sopin, output_prefix): tokid = obj['tokid'] pid = db.getpid_by_tokid(tokid) pobj = db.getprimary(pid) attrs = yaml.safe_load(io.StringIO(obj['attrs'])) pub_blob = TPM2B_PUBLIC.unmarshal( binascii.unhexlify(attrs[CKA_TPM2_PUB_BLOB]))[0] priv_blob = TPM2B_PRIVATE.unmarshal( binascii.unhexlify(attrs[CKA_TPM2_PRIV_BLOB]))[0] objauth, pobj_handle = getauth(db, obj, pin, is_sopin, attrs) with ESAPI(os.getenv('TPM2TOOLS_TCTI', None)) as e: tr_handle = ESYS_TR.deserialize(e, pobj_handle) tpm_handle = e.tr_get_tpm_handle(tr_handle) key = TSSPrivKey(priv_blob, pub_blob, empty_auth=len(objauth) == 0, parent=tpm_handle) with open(output_prefix + ".pem", "wb") as f: f.write(key.to_pem()) _dump_outputs(objauth, pobj)
def test_bad_oid(self): _, _, der = pem.unarmor(rsa_pem) dc = TSSPrivKey._tssprivkey_der.load(der) dc["type"] = ObjectIdentifier("1.2.3.4") badder = dc.dump() with self.assertRaises(TypeError) as e: TSSPrivKey.from_der(badder) self.assertEqual(str(e.exception), "unsupported key type")
def test_no_ecc(self): cap_data = TPMS_CAPABILITY_DATA() cap_data.data.algorithms[0] = TPMS_ALG_PROPERTY(alg=TPM2_ALG.RSA) def mock_getcap(*args, **kwargs): return (False, cap_data) self.ectx.get_capability = mock_getcap TSSPrivKey.create_ecc(self.ectx)
def test_no_ecc_no_rsa(self): cap_data = TPMS_CAPABILITY_DATA() def mock_getcap(*args, **kwargs): return (False, cap_data) self.ectx.get_capability = mock_getcap with self.assertRaises(RuntimeError) as e: TSSPrivKey.create_ecc(self.ectx) self.assertEqual(str(e.exception), "Unable to find supported parent key type")
def test_persistent_parent_ecc(self): insens = TPM2B_SENSITIVE_CREATE() inpublic = TPM2B_PUBLIC(publicArea=parent_ecc_template) parent, _, _, _, _ = self.ectx.CreatePrimary(insens, inpublic) phandle = self.ectx.EvictControl( ESYS_TR.RH_OWNER, parent, 0x81000081, session1=ESYS_TR.PASSWORD ) key = TSSPrivKey.create_ecc(self.ectx, parent=0x81000081) key.load(self.ectx) self.assertEqual(key.parent, 0x81000081)
def create_from_tss_key(self, pobj, objauth, hierarchyauth, tpm2, alg, keypath, d): keypath = keypath[0] with open(keypath, "rb") as f: keybytes = f.read() tss2_privkey = TSSPrivKey.from_pem(keybytes) is_empty_auth = tss2_privkey.empty_auth phandle = tss2_privkey.parent pubbytes = tss2_privkey.public.marshal() privbytes = tss2_privkey.private.marshal() pid = pobj['id'] pobj_config = yaml.safe_load(pobj['config']) is_transient = pobj_config['transient'] if not is_transient and (phandle == tpm2.TPM2_RH_OWNER or \ (phandle >> tpm2.TPM2_HR_SHIFT != tpm2.TPM2_HT_PERSISTENT)): sys.exit('The primary object (id: {:d}) is persistent and' ' the TSS Engine key does not have a persistent parent,' ' got: 0x{:x}'.format(pid, phandle)) elif is_transient and not (phandle == tpm2.TPM2_RH_OWNER or phandle == 0): # tpm2-tss-engine < 1.1.0 used a phandle of 0 instead of tpm2.TPM2_RH_OWNER sys.exit('The primary object (id: {:d}) is transient and' ' the TSS Engine key has a parent handle,' ' got: 0x{:x}'.format(pid, phandle)) if is_empty_auth and len(self._auth) if self._auth is not None else 0: sys.exit( 'Key expected to have auth value, please specify via option --auth' ) if not is_transient: # Im diving into the ESYS_TR serialized format, # this isn't the smartest thing to do... hexhandle = pobj_config['esys-tr'] handle_bytes = binascii.unhexlify(hexhandle)[0:4] expected_handle = struct.unpack(">I", handle_bytes)[0] if phandle != expected_handle: sys.exit("Key must be parent of 0x{:X}, got 0x{:X}".format( expected_handle, phandle)) pobj_handle = get_pobject(pobj, tpm2, hierarchyauth, d) pobjauth = pobj['objauth'] ctx = tpm2.load(pobj_handle, pobjauth, privbytes, pubbytes) tertiarypubdata, _ = tpm2.readpublic(ctx, False) privfd, tertiarypriv = mkstemp(prefix='', suffix='.priv', dir=d) try: os.write(privfd, privbytes) finally: os.close(privfd) pubfd, tertiarypub = mkstemp(prefix='', suffix='.pub', dir=d) try: os.write(pubfd, pubbytes) finally: os.close(pubfd) return (tertiarypriv, tertiarypub, tertiarypubdata)
def test_create_load_ecc(self): key = TSSPrivKey.create_ecc(self.ectx) key.load(self.ectx)
def test_rsa_topem(self): key = TSSPrivKey.fromPEM(rsa_pem) pem = key.toPEM() self.assertEqual(pem, rsa_pem)
def test_rsa_frompem(self): key = TSSPrivKey.fromPEM(rsa_pem)
def test_bad_pem_type(self): bad_pem = rsa_pem.replace(b"TSS2", b"BORK") with self.assertRaises(TypeError) as e: TSSPrivKey.from_pem(bad_pem) self.assertEqual(str(e.exception), "unsupported PEM type")
def test_create_no_password_load_password(self): key = TSSPrivKey.create_ecc(self.ectx) with self.assertWarns(UserWarning) as w: key.load(self.ectx, password=b"1234") self.assertEqual(str(w.warning), "password specified but empty_auth is true")
def test_create_password_load_no_password(self): key = TSSPrivKey.create_ecc(self.ectx, password=b"1234") with self.assertRaises(RuntimeError) as e: key.load(self.ectx) self.assertEqual(str(e.exception), "no password specified but it is required")
def test_create_load_ecc_password(self): key = TSSPrivKey.create_ecc(self.ectx, password=b"1234") key.load(self.ectx, password=b"1234")