예제 #1
0
    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)
예제 #2
0
 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
예제 #3
0
    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)
예제 #4
0
    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