Beispiel #1
0
 def generate_private_key(self):
     parameters = self.session.create_domain_parameters(
         KeyType.EC,
         {Attribute.EC_PARAMS: encode_named_curve_parameters('secp256r1')},
         local=True)
     public_template = {
         Attribute.KEY_TYPE: KeyType.EC,
         Attribute.CLASS: ObjectClass.PUBLIC_KEY,
         Attribute.TOKEN: True,
         Attribute.VERIFY: True,
     }
     private_template = {
         Attribute.KEY_TYPE: KeyType.EC,
         Attribute.CLASS: ObjectClass.PRIVATE_KEY,
         Attribute.TOKEN: True,
         Attribute.PRIVATE: True,
         Attribute.SIGN: True,
         Attribute.EXTRACTABLE: False,
         Attribute.SENSITIVE: True
     }
     public_key, private_key = parameters.generate_keypair(
         store=True,
         public_template=public_template,
         private_template=private_template)
     ecpt = bytes(OctetString.load(public_key[Attribute.EC_POINT]))
     hash = hashlib.sha256(ecpt)
     ski = hash.digest()
     hexski = hash.hexdigest()
     public_key[Attribute.ID] = ski
     public_key[Attribute.LABEL] = hexski
     private_key[Attribute.ID] = ski
     private_key[Attribute.LABEL] = hexski
     return PKCS11KeyPair(public_key, private_key)
Beispiel #2
0
    def test_ecdh(self):
        # A key we generated earlier
        self.session.create_domain_parameters(KeyType.EC, {
            Attribute.EC_PARAMS: encode_named_curve_parameters('secp256r1'),
        }, local=True)\
            .generate_keypair()

        # Retrieve our keypair, with our public key encoded for interchange
        alice_priv = self.session.get_key(key_type=KeyType.EC,
                                          object_class=ObjectClass.PRIVATE_KEY)
        alice_pub = self.session.get_key(key_type=KeyType.EC,
                                         object_class=ObjectClass.PUBLIC_KEY)
        alice_pub = encode_ec_public_key(alice_pub)

        from cryptography.hazmat.backends import default_backend
        from cryptography.hazmat.primitives.asymmetric import ec
        from cryptography.hazmat.primitives.serialization import \
            Encoding, PublicFormat, load_der_public_key

        # Bob generates a keypair, with their public key encoded for
        # interchange
        bob_priv = ec.generate_private_key(ec.SECP256R1, default_backend())
        bob_pub = bob_priv.public_key().public_bytes(
            Encoding.DER,
            PublicFormat.SubjectPublicKeyInfo,
        )

        # Bob converts Alice's key to internal format and generates their
        # shared key
        bob_shared_key = bob_priv.exchange(
            ec.ECDH(),
            load_der_public_key(alice_pub, default_backend()),
        )

        key = alice_priv.derive_key(
            KeyType.GENERIC_SECRET,
            256,
            mechanism_param=(
                KDF.NULL,
                None,
                # N.B. it seems like SoftHSMv2 requires an EC_POINT to be
                # DER-encoded, which is not what the spec says
                decode_ec_public_key(bob_pub, encode_ec_point=Is.softhsm2)
                [Attribute.EC_POINT],
            ),
            template={
                Attribute.SENSITIVE: False,
                Attribute.EXTRACTABLE: True,
            },
        )
        alice_shared_key = key[Attribute.VALUE]

        # We should have the same shared key
        self.assertEqual(bob_shared_key, alice_shared_key)
Beispiel #3
0
    def test_sign_ecdsa(self):
        parameters = self.session.create_domain_parameters(
            KeyType.EC,
            {Attribute.EC_PARAMS: encode_named_curve_parameters('secp256r1')},
            local=True)

        pub, priv = parameters.generate_keypair()

        mechanism = Mechanism.ECDSA
        data = b'HI BOB!'
        ecdsa = priv.sign(data, mechanism=mechanism)
        self.assertTrue(pub.verify(data, ecdsa, mechanism=mechanism))
Beispiel #4
0
    def test_sign_eddsa(self):
        parameters = self.session.create_domain_parameters(
            KeyType.EC,
            {
                # use "Ed25519" once https://github.com/wbond/asn1crypto/pull/134
                # is merged
                Attribute.EC_PARAMS:
                encode_named_curve_parameters('1.3.101.112')
            },
            local=True)

        pub, priv = parameters.generate_keypair()

        mechanism = Mechanism.EDDSA
        data = b'HI BOB!'
        eddsa = priv.sign(data, mechanism=mechanism)
        self.assertTrue(pub.verify(data, eddsa, mechanism=mechanism))
    def generate(self):
        if not self._address:
            # if we got here, we didn't succeed in loading during _load_key, so we can just generate a new one without
            # being afraid of multiple objects
            # todo: handle multiple objects a little more gracefully? We'll see how other HSMs handle this shit...
            with self.token.open(rw=True, user_pin=self.user_pin) as session:
                ecparams = session.create_domain_parameters(
                    pkcs11.KeyType.EC, {
                        pkcs11.Attribute.EC_PARAMS:
                        ec.encode_named_curve_parameters('secp256k1'),
                    },
                    local=True)

                pub, _ = ecparams.generate_keypair(label=self.label,
                                                   store=True)
                self._address = self._address_from_pub(pub)
                self.public_key = encode_ec_public_key(pub)[24:]
        return self.label
Beispiel #6
0
    def generate_ec(self, curve, label, object_id='', store=True):
        """
        Generates an EC key.

        @param curve: The name of the desired elliptic curve.
        @param label: The label of the key.
        @param object_id: The unique identifier of the key as a string.
        @raise ValueError: Raised when an invalid curve is passed.
        @return: The key.
        """
        if curve not in Session.__ec_curves:
            raise ValueError('Invalid EC curve.')
        parameters = self.p11.create_domain_parameters(
            KeyType.EC,
            {Attribute.EC_PARAMS: encode_named_curve_parameters(curve)},
            local=True)
        return parameters.generate_keypair(label=label,
                                           id=bytes(object_id, 'utf-8'),
                                           store=store)
Beispiel #7
0
    def test_ecdsa(self):
        # A key we generated earlier
        self.session.create_domain_parameters(KeyType.EC, {
            Attribute.EC_PARAMS: encode_named_curve_parameters('secp256r1'),
        }, local=True)\
            .generate_keypair()

        priv = self.session.get_key(key_type=KeyType.EC,
                                    object_class=ObjectClass.PRIVATE_KEY)

        signature = priv.sign(b'Data to sign', mechanism=Mechanism.ECDSA_SHA1)
        # Encode as ASN.1 for OpenSSL
        signature = encode_ecdsa_signature(signature)

        from oscrypto.asymmetric import load_public_key, ecdsa_verify

        pub = self.session.get_key(key_type=KeyType.EC,
                                   object_class=ObjectClass.PUBLIC_KEY)
        pub = load_public_key(encode_ec_public_key(pub))

        ecdsa_verify(pub, signature, b'Data to sign', 'sha1')
tokens = lib.get_tokens()
token = next(tokens)  # get any token

try:
    # connect to hsm via pkcs11 token and pin
    with token.open(user_pin=os.environ['USER_PIN'], rw=True) as session:

        # ec curve params
        ecparams = session.create_domain_parameters(
            KeyType.EC,
            {
                # hardcoded curve name for secp256k1 taken from https://www.flexiprovider.de/CurveOIDs.html
                # asn1crypto python library currently missing the secp256k1 named curve parameters
                Attribute.EC_PARAMS:
                ec.encode_named_curve_parameters('1.3.132.0.10'),
            },
            local=True)

        try:
            pub, priv = ecparams.generate_keypair(store=True,
                                                  label="{}".format(
                                                      os.environ['KEY_LABEL']))
        except Exception as e:
            print("key already exists")
            for obj in session.get_objects({
                    Attribute.KEY_TYPE:
                    KeyType.EC,
                    Attribute.LABEL:
                    "{}".format(os.environ['KEY_LABEL'])
            }):
Beispiel #9
0
from pkcs11.util.ec import encode_named_curve_parameters

if __name__ == "__main__":
    lib = pkcs11.lib("/usr/lib/softhsm/libsofthsm2.so")
    token = lib.get_token(token_label="token")

    with token.open(rw=True, user_pin="1234") as session:
        session.generate_keypair(pkcs11.KeyType.RSA,
                                 2048,
                                 label="small_rsa_key",
                                 store=True)
        session.generate_keypair(pkcs11.KeyType.RSA,
                                 4096,
                                 label="big_rsa_key",
                                 store=True)

        session.generate_keypair(pkcs11.KeyType.DSA,
                                 2048,
                                 label="dsa_key",
                                 store=True)

        ecparams = session.create_domain_parameters(
            pkcs11.KeyType.EC,
            {
                pkcs11.Attribute.EC_PARAMS:
                encode_named_curve_parameters("secp256r1")
            },
            local=True,
        )
        ecparams.generate_keypair(store=True, label="ec_key")