def keypair(request, session, curve): if request.param == Mode.GENERATE: asymkey = AsymmetricKey.generate( session, 0, "Generate EC", 0xFFFF, CAPABILITY.SIGN_ECDSA | CAPABILITY.DERIVE_ECDH, ALGORITHM.for_curve(curve()), ) public_key = asymkey.get_public_key() else: key = ec.generate_private_key(curve(), backend=default_backend()) asymkey = AsymmetricKey.put( session, 0, "SECP ECDSA Sign Sign", 0xFFFF, CAPABILITY.SIGN_ECDSA | CAPABILITY.DERIVE_ECDH, key, ) public_key = key.public_key() assert public_key.public_bytes( encoding=serialization.Encoding.PEM, format=serialization.PublicFormat.SubjectPublicKeyInfo, ) == asymkey.get_public_key().public_bytes( encoding=serialization.Encoding.PEM, format=serialization.PublicFormat.SubjectPublicKeyInfo, ) yield asymkey, public_key asymkey.delete()
def test_bad_ecdh_keys(self): pubkeys = [ # this is a public key not on the curve (p256) "04cdeb39edd03e2b1a11a5e134ec99d5f25f21673d403f3ecb47bd1fa676638958ea58493b8429598c0b49bbb85c3303ddb1553c3b761c2caacca71606ba9ebaca", # noqa E501 # all zeroes public key "0400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", # noqa E501 # all ff public key "04ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", # noqa E501 ] key = AsymmetricKey.generate( self.session, 0, "badkey ecdh test", 0xFFFF, CAPABILITY.DERIVE_ECDH, ALGORITHM.EC_P256, ) keyid = struct.pack("!H", key.id) for pubkey in pubkeys: with self.assertRaises(YubiHsmDeviceError) as context: self.session.send_secure_cmd(COMMAND.DERIVE_ECDH, keyid + a2b_hex(pubkey)) self.assertEqual(context.exception.code, ERROR.INVALID_DATA) key.delete()
def eddsa_keypair(request, session): if request.param == Mode.GENERATE: key = None asymkey = AsymmetricKey.generate( session, 0, "Generate EC", 0xFFFF, CAPABILITY.SIGN_EDDSA, ALGORITHM.EC_ED25519, ) public_key = asymkey.get_public_key() else: key = ed25519.Ed25519PrivateKey.generate() asymkey = AsymmetricKey.put(session, 0, "Test Ed25519", 0xFFFF, CAPABILITY.SIGN_EDDSA, key) public_key = key.public_key() assert public_key.public_bytes( serialization.Encoding.Raw, serialization.PublicFormat.Raw) == asymkey.get_public_key( ).public_bytes(serialization.Encoding.Raw, serialization.PublicFormat.Raw) yield asymkey, public_key, key asymkey.delete()
def generate_wrap(self): w_id = random.randint(1, 0xFFFE) a_id = random.randint(1, 0xFFFE) wrapkey = WrapKey.generate( self.session, w_id, "Generate Wrap 0x%04x" % w_id, 1, CAPABILITY.EXPORT_WRAPPED | CAPABILITY.IMPORT_WRAPPED, ALGORITHM.AES192_CCM_WRAP, CAPABILITY.SIGN_ECDSA | CAPABILITY.EXPORTABLE_UNDER_WRAP, ) asymkey = AsymmetricKey.generate( self.session, a_id, "Generate Wrap 0x%04x" % a_id, 0xFFFF, CAPABILITY.SIGN_ECDSA | CAPABILITY.EXPORTABLE_UNDER_WRAP, ALGORITHM.EC_P256, ) origin = asymkey.get_info().origin self.assertEqual(origin, 0x01) self.assertTrue(origin.generated) self.assertFalse(origin.imported) self.assertFalse(origin.wrapped) pub = asymkey.get_public_key() data = os.urandom(64) resp = asymkey.sign_ecdsa(data) pub.verify(resp, data, ec.ECDSA(hashes.SHA256())) wrapped = wrapkey.export_wrapped(asymkey) wrapped2 = wrapkey.export_wrapped(asymkey) self.assertNotEqual(wrapped, wrapped2) asymkey.delete() self.assertRaises(YubiHsmDeviceError, asymkey.get_public_key) asymkey = wrapkey.import_wrapped(wrapped) origin = asymkey.get_info().origin self.assertEqual(origin, 0x11) self.assertTrue(origin.generated) self.assertFalse(origin.imported) self.assertTrue(origin.wrapped) data = os.urandom(64) resp = asymkey.sign_ecdsa(data) self.assertNotEqual(resp, None) pub.verify(resp, data, ec.ECDSA(hashes.SHA256())) wrapkey.delete()
def test_generate_sign_long(self): key = AsymmetricKey.generate(self.session, 0, 'Test Ed25519', 0xffff, CAPABILITY.SIGN_EDDSA, ALGORITHM.EC_ED25519) pubkey = key.get_public_key() data = os.urandom(2019) sig = key.sign_eddsa(data) v_key = ed25519.VerifyingKey(serialize_ed25519_public_key(pubkey)) v_key.verify(sig, data) key.delete()
def generate_secp_sign(self, curve, hashtype, length=0): asymkey = AsymmetricKey.generate(self.session, 0, 'Generate SECP Sign', 0xffff, CAPABILITY.SIGN_ECDSA, curve) pub = asymkey.get_public_key() data = os.urandom(64) resp = asymkey.sign_ecdsa(data, hash=hashtype, length=length) pub.verify(resp, data, ec.ECDSA(hashtype)) asymkey.delete()
def generate_rsa_sign(self, algo): asymkey = AsymmetricKey.generate(self.session, 0, "Generate RSA Sign", 0xFFFF, CAPABILITY.SIGN_PKCS, algo) pub = asymkey.get_public_key() data = os.urandom(64) resp = asymkey.sign_pkcs1v1_5(data) pub.verify(resp, data, padding.PKCS1v15(), hashes.SHA256()) asymkey.delete()
def test_generate_wrap(session): w_id = random.randint(1, 0xFFFE) a_id = random.randint(1, 0xFFFE) wrapkey = WrapKey.generate( session, w_id, "Generate Wrap 0x%04x" % w_id, 1, CAPABILITY.EXPORT_WRAPPED | CAPABILITY.IMPORT_WRAPPED, ALGORITHM.AES192_CCM_WRAP, CAPABILITY.SIGN_ECDSA | CAPABILITY.EXPORTABLE_UNDER_WRAP, ) asymkey = AsymmetricKey.generate( session, a_id, "Generate Wrap 0x%04x" % a_id, 0xFFFF, CAPABILITY.SIGN_ECDSA | CAPABILITY.EXPORTABLE_UNDER_WRAP, ALGORITHM.EC_P256, ) origin = asymkey.get_info().origin assert origin == ORIGIN.GENERATED pub = asymkey.get_public_key() data = os.urandom(64) resp = asymkey.sign_ecdsa(data) pub.verify(resp, data, ec.ECDSA(hashes.SHA256())) wrapped = wrapkey.export_wrapped(asymkey) wrapped2 = wrapkey.export_wrapped(asymkey) assert wrapped != wrapped2 asymkey.delete() pytest.raises(YubiHsmDeviceError, asymkey.get_public_key) asymkey = wrapkey.import_wrapped(wrapped) origin = asymkey.get_info().origin assert origin == ORIGIN.IMPORTED_WRAPPED | ORIGIN.GENERATED data = os.urandom(64) resp = asymkey.sign_ecdsa(data) assert resp is not None pub.verify(resp, data, ec.ECDSA(hashes.SHA256())) wrapkey.delete()
def generated_key(request, session): algorithm = request.param key = AsymmetricKey.generate( session, 0, "Test Attestation %x" % algorithm, 0xFFFF, CAPABILITY.NONE, algorithm, ) yield key key.delete()
def key_in_list(self, keytype, algorithm=None): dom = None cap = 0 key_label = "%s%s" % (str( uuid.uuid4()), b"\xf0\x9f\x98\x83".decode("utf8")) if keytype == OBJECT.ASYMMETRIC_KEY: dom = 0xFFFF key = AsymmetricKey.generate(self.session, 0, key_label, dom, cap, algorithm) elif keytype == OBJECT.WRAP_KEY: dom = 0x01 key = WrapKey.generate(self.session, 0, key_label, dom, cap, algorithm, cap) elif keytype == OBJECT.HMAC_KEY: dom = 0x01 key = HmacKey.generate(self.session, 0, key_label, dom, cap, algorithm) elif keytype == OBJECT.AUTHENTICATION_KEY: dom = 0x01 key = AuthenticationKey.put_derived( self.session, 0, key_label, dom, cap, 0, b"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" b"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa", ) objlist = self.session.list_objects(object_id=key.id, object_type=key.object_type) self.assertEqual(objlist[0].id, key.id) self.assertEqual(objlist[0].object_type, key.object_type) objinfo = objlist[0].get_info() self.assertEqual(objinfo.id, key.id) self.assertEqual(objinfo.object_type, key.object_type) self.assertEqual(objinfo.domains, dom) self.assertEqual(objinfo.capabilities, cap) if algorithm: self.assertEqual(objinfo.algorithm, algorithm) if key.object_type == OBJECT.AUTHENTICATION_KEY: self.assertEqual(objinfo.origin, ORIGIN.IMPORTED) else: self.assertEqual(objinfo.origin, ORIGIN.GENERATED) self.assertEqual(objinfo.label, key_label) key.delete()
def generate_bp_r1_sign(self, curve, hashtype): asymkey = AsymmetricKey.generate(self.session, 0, "Generate BP R1 Sign", 0xFFFF, CAPABILITY.SIGN_ECDSA, curve) pub = asymkey.get_public_key() data = os.urandom(64) resp = asymkey.sign_ecdsa(data, hashtype) pub.verify(resp, data, ec.ECDSA(hashtype)) asymkey.delete()
def key_in_list(self, session, keytype, algorithm=None): dom = None cap = CAPABILITY.NONE key_label = "%s%s" % (str(uuid.uuid4()), b"\xf0\x9f\x98\x83".decode()) key: YhsmObject if keytype == OBJECT.ASYMMETRIC_KEY: dom = 0xFFFF key = AsymmetricKey.generate(session, 0, key_label, dom, cap, algorithm) elif keytype == OBJECT.WRAP_KEY: dom = 0x01 key = WrapKey.generate(session, 0, key_label, dom, cap, algorithm, cap) elif keytype == OBJECT.HMAC_KEY: dom = 0x01 key = HmacKey.generate(session, 0, key_label, dom, cap, algorithm) elif keytype == OBJECT.AUTHENTICATION_KEY: dom = 0x01 key = AuthenticationKey.put_derived( session, 0, key_label, dom, cap, cap, "password", ) objlist = session.list_objects(object_id=key.id, object_type=key.object_type) assert objlist[0].id == key.id assert objlist[0].object_type == key.object_type objinfo = objlist[0].get_info() assert objinfo.id == key.id assert objinfo.object_type == key.object_type assert objinfo.domains == dom assert objinfo.capabilities == cap if algorithm: assert objinfo.algorithm == algorithm if key.object_type == OBJECT.AUTHENTICATION_KEY: assert objinfo.origin == ORIGIN.IMPORTED else: assert objinfo.origin == ORIGIN.GENERATED assert objinfo.label == key_label key.delete()
def test_generate_sign_long(self): key = AsymmetricKey.generate( self.session, 0, "Test Ed25519", 0xFFFF, CAPABILITY.SIGN_EDDSA, ALGORITHM.EC_ED25519, ) pubkey = key.get_public_key() data = os.urandom(2019) sig = key.sign_eddsa(data) pubkey.verify(sig, data) key.delete()
def test_attestation(self): algs = [ ALGORITHM.RSA_2048, ALGORITHM.RSA_3072, ALGORITHM.RSA_4096, ALGORITHM.EC_P256, ALGORITHM.EC_P384, ALGORITHM.EC_P521, ALGORITHM.EC_K256, ALGORITHM.EC_P224, ] keys = [ AsymmetricKey.generate( self.session, 0, "Test Attestation %x" % algo, 0xFFFF, 0, algo ) for algo in algs ] for algo in algs: attkey, attcertobj, attcert = self.create_pair(algo) pubkey = attcert.public_key() for key in keys: cert = key.attest(attkey.id) data = cert.tbs_certificate_bytes if isinstance(pubkey, rsa.RSAPublicKey): pubkey.verify( cert.signature, data, padding.PKCS1v15(), cert.signature_hash_algorithm, ) else: pubkey.verify( cert.signature, data, ec.ECDSA(cert.signature_hash_algorithm) ) attkey.delete() attcertobj.delete() for key in keys: key.delete()
from yubihsm import YubiHsm from yubihsm.defs import CAPABILITY, ALGORITHM from yubihsm.objects import AsymmetricKey from yubihsm import eddsa authkeyID = 101 # For consistency, always create key number 101 password = getpass.getpass() hsm = YubiHsm.connect("http://localhost:12345/connector/api") session = hsm.create_session_derived(authkeyID, password) # Generate recovery service keypairs on the YubiHSM for creating signatures. Always # generate two sets of 64 keys, numbered 5001 through 5064 and 6001 through 6064. for keynum in range(10001, 10065): key = AsymmetricKey.generate( # Generate a new key object in the YubiHSM. session, # Secure YubiHsm session to use. keynum, # Object ID "ndau key " + str(keynum), # Label for the object. 1, # Domain(s) for the object. CAPABILITY.SIGN_EDDSA, # Capabilities for the ojbect. ALGORITHM.EC_ED25519, # Algorithm for the key. ) pub_key = eddsa.serialize_ed25519_public_key(key.get_public_key()) print("Public key number " + str(keynum) + ": " + base64.standard_b64encode(pub_key).decode()) session.close() hsm.close()
capabilities, # Delegated capabilities authpass, # Authentication password ) print("Created " + str(authkey)) session.close() # Log in with new authentication key, create EDDSA asymmetric key, delete # default authentication key signkeynum = 1001 # ID used for first BPC signing key session = hsm.create_session_derived(authkeynum, authpass) signkey = AsymmetricKey.generate( session, signkeynum, "ndau BPC signing key", 1, CAPABILITY.SIGN_EDDSA, ALGORITHM.EC_ED25519, ) print("Created " + str(signkey)) print("Public key: " + str( base64.b64encode( eddsa.serialize_ed25519_public_key(signkey.get_public_key())))) # Delete the default authentication key session.get_object(default_authkey, OBJECT.AUTHENTICATION_KEY).delete() session.close() hsm.close() exit(0)