def generate_key(cls, crv: Union[Type['CoseCurve'], str, int], optional_params: dict = None) -> 'OKPKey': """ Generate a random OKPKey COSE key object. :param crv: Specify an elliptic curve. :param optional_params: Optional key attributes for the :class:`~cose.keys.okp.OKPKey` object, e.g., \ :class:`~cose.keys.keyparam.KpAlg` or :class:`~cose.keys.keyparam.KpKid`. :returns: A COSE `OKPKey` key. """ crv = OKPKpCurve.value_parser(crv) if crv.key_type != KtyOKP: raise CoseUnsupportedCurve(f'Unsupported COSE curve: {crv}') encoding = Encoding(serialization.Encoding.Raw) private_format = PrivateFormat(serialization.PrivateFormat.Raw) public_format = PublicFormat(serialization.PublicFormat.Raw) encryption = serialization.NoEncryption() private_key = crv.curve_obj.generate() return OKPKey(crv=crv, x=private_key.public_key().public_bytes( encoding, public_format), d=private_key.private_bytes(encoding, private_format, encryption), optional_params=optional_params)
def crv(self, crv: Union[Type['CoseCurve'], int, str]): crv = OKPKpCurve.value_parser(crv) if crv.key_type != KtyOKP: raise CoseUnsupportedCurve( f"Invalid COSE curve {crv} for key type {OKPKey.__name__}") else: self.store[OKPKpCurve] = crv
def generate_key(cls, crv: Union[Type['CoseCurve'], str, int], optional_params: dict = None) -> 'EC2Key': """ Generate a random EC2Key COSE key object. :param crv: Specify an :class:`~cose.attributes.algorithms.CoseEllipticCurves`. :param optional_params: Optional key attributes for the :class:`~cose.keys.ec2.EC2Key` object, e.g., \ :class:`~cose.keys.keyparam.KpAlg` or :class:`~cose.keys.keyparam.KpKid`. :return: An COSE `EC2Key` key. """ crv = EC2KpCurve.value_parser(crv) if crv.key_type != KtyEC2: raise CoseUnsupportedCurve(f'Unsupported COSE curve: {crv}') private_key = ec.generate_private_key(crv.curve_obj, backend=default_backend()) d_value = private_key.private_numbers().private_value x_coor = private_key.public_key().public_numbers().x y_coor = private_key.public_key().public_numbers().y return EC2Key(crv=crv, d=d_value.to_bytes(crv.size, "big"), x=x_coor.to_bytes(crv.size, "big"), y=y_coor.to_bytes(crv.size, "big"), optional_params=optional_params)
def extract_cose_key(keyobj): ''' Get a COSE version of the local private key. :param keyobj: The cryptography key object. :return: The associated COSE key. :rtype: :py:cls:`CoseKey` ''' if isinstance(keyobj, (rsa.RSAPrivateKey, rsa.RSAPublicKey)): if hasattr(keyobj, 'private_numbers'): priv_nums = keyobj.private_numbers() pub_nums = keyobj.public_key().public_numbers() else: priv_nums = None pub_nums = keyobj.public_numbers() kwargs = dict() if pub_nums: def convert(name, attr=None): val = getattr(pub_nums, attr or name) kwargs[name] = val.to_bytes((val.bit_length() + 7) // 8, byteorder="big") convert('n') convert('e') if priv_nums: def convert(name, attr=None): val = getattr(priv_nums, attr or name) kwargs[name] = val.to_bytes((val.bit_length() + 7) // 8, byteorder="big") convert('d') convert('p') convert('q') convert('dp', 'dmp1') convert('dq', 'dmq1') convert('qinv', 'iqmp') cose_key = RSAKey(**kwargs) cose_key.alg = algorithms.Ps256 elif isinstance( keyobj, (ec.EllipticCurvePrivateKey, ec.EllipticCurvePublicKey)): CURVE_CLS_MAP = { ec.SECP256R1: curves.P256, ec.SECP384R1: curves.P384, ec.SECP521R1: curves.P521, } CURVE_ALG_MAP = { ec.SECP256R1: algorithms.Es256, ec.SECP384R1: algorithms.Es384, ec.SECP521R1: algorithms.Es512, } try: curve_cls = CURVE_CLS_MAP[type(keyobj.curve)] except KeyError: raise CoseUnsupportedCurve('Cannot match curve for {}'.format( repr(keyobj))) LOGGER.debug('Found COSE curve %s', curve_cls) try: alg_cls = CURVE_ALG_MAP[type(keyobj.curve)] except KeyError: raise CoseUnsupportedCurve( 'Cannot match algorithm for {}'.format(repr(keyobj))) LOGGER.debug('Found COSE algorithm %s', alg_cls) if hasattr(keyobj, 'private_numbers'): priv_nums = keyobj.private_numbers() pub_nums = keyobj.public_key().public_numbers() else: priv_nums = None pub_nums = keyobj.public_numbers() kwargs = dict( crv=curve_cls, optional_params={ keyparam.KpAlg: alg_cls, }, ) if pub_nums: x_coor = pub_nums.x y_coor = pub_nums.y kwargs.update( dict(x=x_coor.to_bytes((x_coor.bit_length() + 7) // 8, byteorder="big"), y=y_coor.to_bytes((y_coor.bit_length() + 7) // 8, byteorder="big"))) if priv_nums: d_value = priv_nums.private_value kwargs.update( dict(d=d_value.to_bytes((d_value.bit_length() + 7) // 8, byteorder="big"), )) cose_key = EC2Key(**kwargs) else: raise TypeError('Cannot handle key {}'.format(repr(keyobj))) return cose_key