Exemplo n.º 1
0
def test_ed448_unsupported(backend):
    with raises_unsupported_algorithm(
            _Reasons.UNSUPPORTED_PUBLIC_KEY_ALGORITHM):
        Ed448PublicKey.from_public_bytes(b"0" * 57)

    with raises_unsupported_algorithm(
            _Reasons.UNSUPPORTED_PUBLIC_KEY_ALGORITHM):
        Ed448PrivateKey.from_private_bytes(b"0" * 57)

    with raises_unsupported_algorithm(
            _Reasons.UNSUPPORTED_PUBLIC_KEY_ALGORITHM):
        Ed448PrivateKey.generate()
Exemplo n.º 2
0
def test_ed448_unsupported(backend):
    with raises_unsupported_algorithm(
        _Reasons.UNSUPPORTED_PUBLIC_KEY_ALGORITHM
    ):
        Ed448PublicKey.from_public_bytes(b"0" * 57)

    with raises_unsupported_algorithm(
        _Reasons.UNSUPPORTED_PUBLIC_KEY_ALGORITHM
    ):
        Ed448PrivateKey.from_private_bytes(b"0" * 57)

    with raises_unsupported_algorithm(
        _Reasons.UNSUPPORTED_PUBLIC_KEY_ALGORITHM
    ):
        Ed448PrivateKey.generate()
Exemplo n.º 3
0
 def test_pub_priv_bytes_raw(self, vector, backend):
     sk = binascii.unhexlify(vector["secret"])
     pk = binascii.unhexlify(vector["public"])
     private_key = Ed448PrivateKey.from_private_bytes(sk)
     assert (
         private_key.private_bytes(
             serialization.Encoding.Raw,
             serialization.PrivateFormat.Raw,
             serialization.NoEncryption(),
         )
         == sk
     )
     assert (
         private_key.public_key().public_bytes(
             serialization.Encoding.Raw, serialization.PublicFormat.Raw
         )
         == pk
     )
     public_key = Ed448PublicKey.from_public_bytes(pk)
     assert (
         public_key.public_bytes(
             serialization.Encoding.Raw, serialization.PublicFormat.Raw
         )
         == pk
     )
Exemplo n.º 4
0
def cryptography_okp_public_key(
        credential_public_key: OKPCredentialPublicKey) -> OKPPublicKey:
    """Convert an `OKPCredentialPublicKey` into a cryptography `OKPPublicKey`.

    Args:
      credential_public_key (EC2CredentialPublicKey): The key to convert.

    Returns:
      A cryptography `EC2PublicKey`.

    Raises:
      UnimplementedError: If the conversion logic for the given type of
        CredentialPublicKey has not been implemented.
      PublicKeyConversionError: If the provided key could not be converted
        into a valid cryptography `EC2PublicKey`.
    """
    try:
        if credential_public_key.crv.name == 'ED25519':
            return Ed25519PublicKey.from_public_bytes(credential_public_key.x)
        elif credential_public_key.crv.name == 'ED448':
            return Ed448PublicKey.from_public_bytes(credential_public_key.x)
        else:
            raise UnimplementedError(
                'Unsupported cryptography OKP curve {}'.format(
                    credential_public_key.crv.name))
    except ValueError:
        raise PublicKeyConversionError('Invalid OKP public key')
Exemplo n.º 5
0
    def verify(self,
               to_be_verified: bytes,
               signature: bytes,
               alg: Optional[CoseAlgorithms] = None,
               curve: Optional[CoseEllipticCurves] = None) -> bool:
        """
        Verifies the digital signature over 'to_be_verified'. The parameter 'alg' and 'curve' parameters are optional in
        case they are already provided by the key object self.

        :param to_be_verified: Data that was signed.
        :param signature: Signature to verify.
        :param alg: An optional algorithm parameter.
        :param curve: An optional curve
        :return: True when the signature is valid and False if the signature is invalid.
        """

        self._check_key_conf(algorithm=alg,
                             key_operation=KeyOps.VERIFY,
                             curve=curve)

        if self.crv == CoseEllipticCurves.ED25519:
            vk = Ed25519PublicKey.from_public_bytes(self.x)
        elif self._crv == CoseEllipticCurves.ED448:
            vk = Ed448PublicKey.from_public_bytes(self.x)
        else:
            raise CoseIllegalCurve(
                f"Illegal curve for OKP singing: {self.crv}")

        try:
            vk.verify(signature, to_be_verified)
            return True
        except InvalidSignature:
            return False
Exemplo n.º 6
0
        def from_jwk(jwk):
            try:
                if isinstance(jwk, str):
                    obj = json.loads(jwk)
                elif isinstance(jwk, dict):
                    obj = jwk
                else:
                    raise ValueError
            except ValueError:
                raise InvalidKeyError("Key is not valid JSON")

            if obj.get("kty") != "OKP":
                raise InvalidKeyError("Not an Octet Key Pair")

            curve = obj.get("crv")
            if curve != "Ed25519" and curve != "Ed448":
                raise InvalidKeyError(f"Invalid curve: {curve}")

            if "x" not in obj:
                raise InvalidKeyError('OKP should have "x" parameter')
            x = base64url_decode(obj.get("x"))

            try:
                if "d" not in obj:
                    if curve == "Ed25519":
                        return Ed25519PublicKey.from_public_bytes(x)
                    return Ed448PublicKey.from_public_bytes(x)
                d = base64url_decode(obj.get("d"))
                if curve == "Ed25519":
                    return Ed25519PrivateKey.from_private_bytes(d)
                return Ed448PrivateKey.from_private_bytes(d)
            except ValueError as err:
                raise InvalidKeyError("Invalid key parameter") from err
Exemplo n.º 7
0
def cryptography_okp_public_key(
        credential_public_key: OKPCredentialPublicKey) -> PublicKey:
    if credential_public_key.crv.name == 'ED25519':
        return Ed25519PublicKey.from_public_bytes(credential_public_key.x)
    elif credential_public_key.crv.name == 'ED448':
        return Ed448PublicKey.from_public_bytes(credential_public_key.x)
    else:
        raise UnimplementedError(
            'Unsupported cryptography OKP curve {}'.format(
                credential_public_key.crv.name))
Exemplo n.º 8
0
    def verify(cls, key: 'OKP', data: bytes, signature: bytes) -> bool:
        if key.crv.fullname == 'ED25519':
            vk = Ed25519PublicKey.from_public_bytes(key.x)
        elif key.crv.fullname == 'ED448':
            vk = Ed448PublicKey.from_public_bytes(key.x)
        else:
            raise CoseException(f"Illegal curve for OKP singing: {key.crv}")

        try:
            vk.verify(signature, data)
            return True
        except InvalidSignature:
            return False
Exemplo n.º 9
0
def test_ed448_signature(backend, wycheproof):
    key = Ed448PublicKey.from_public_bytes(
        binascii.unhexlify(wycheproof.testgroup["key"]["pk"]))

    if wycheproof.valid or wycheproof.acceptable:
        key.verify(
            binascii.unhexlify(wycheproof.testcase["sig"]),
            binascii.unhexlify(wycheproof.testcase["msg"]),
        )
    else:
        with pytest.raises(InvalidSignature):
            key.verify(
                binascii.unhexlify(wycheproof.testcase["sig"]),
                binascii.unhexlify(wycheproof.testcase["msg"]),
            )
Exemplo n.º 10
0
 def test_malleability(self, backend):
     # This is a signature where r > the group order. It should be
     # rejected to prevent signature malleability issues. This test can
     # be removed when wycheproof grows ed448 vectors
     public_bytes = binascii.unhexlify(
         "fedb02a658d74990244d9d10cf338e977565cbbda6b24c716829ed6ee1e4f28cf"
         "2620c052db8d878f6243bffc22242816c1aaa67d2f3603600")
     signature = binascii.unhexlify(
         "0cc16ba24d69277f927c1554b0f08a2a711bbdd20b058ccc660d00ca13542a3ce"
         "f9e5c44c54ab23a2eb14f947e167b990b080863e28b399380f30db6e54d5d1406"
         "d23378ffde11b1fb81b2b438a3b8e8aa7f7f4e1befcc905023fab5a5465053844"
         "f04cf0c1b51d84760f869588687f57500")
     key = Ed448PublicKey.from_public_bytes(public_bytes)
     with pytest.raises(InvalidSignature):
         key.verify(signature, b"8")
Exemplo n.º 11
0
 def test_pub_priv_bytes_raw(self, vector, backend):
     sk = binascii.unhexlify(vector["secret"])
     pk = binascii.unhexlify(vector["public"])
     private_key = Ed448PrivateKey.from_private_bytes(sk)
     assert private_key.private_bytes(
         serialization.Encoding.Raw,
         serialization.PrivateFormat.Raw,
         serialization.NoEncryption()
     ) == sk
     assert private_key.public_key().public_bytes(
         serialization.Encoding.Raw, serialization.PublicFormat.Raw
     ) == pk
     public_key = Ed448PublicKey.from_public_bytes(pk)
     assert public_key.public_bytes(
         serialization.Encoding.Raw, serialization.PublicFormat.Raw
     ) == pk
Exemplo n.º 12
0
 def test_malleability(self, backend):
     # This is a signature where r > the group order. It should be
     # rejected to prevent signature malleability issues. This test can
     # be removed when wycheproof grows ed448 vectors
     public_bytes = binascii.unhexlify(
         "fedb02a658d74990244d9d10cf338e977565cbbda6b24c716829ed6ee1e4f28cf"
         "2620c052db8d878f6243bffc22242816c1aaa67d2f3603600"
     )
     signature = binascii.unhexlify(
         "0cc16ba24d69277f927c1554b0f08a2a711bbdd20b058ccc660d00ca13542a3ce"
         "f9e5c44c54ab23a2eb14f947e167b990b080863e28b399380f30db6e54d5d1406"
         "d23378ffde11b1fb81b2b438a3b8e8aa7f7f4e1befcc905023fab5a5465053844"
         "f04cf0c1b51d84760f869588687f57500"
     )
     key = Ed448PublicKey.from_public_bytes(public_bytes)
     with pytest.raises(InvalidSignature):
         key.verify(signature, b"8")
Exemplo n.º 13
0
 def test_invalid_length_from_public_bytes(self, backend):
     with pytest.raises(ValueError):
         Ed448PublicKey.from_public_bytes(b"a" * 56)
     with pytest.raises(ValueError):
         Ed448PublicKey.from_public_bytes(b"a" * 58)
Exemplo n.º 14
0
 def test_invalid_type_public_bytes(self, backend):
     with pytest.raises(TypeError):
         Ed448PublicKey.from_public_bytes(object())
Exemplo n.º 15
0
 def test_invalid_length_from_public_bytes(self, backend):
     with pytest.raises(ValueError):
         Ed448PublicKey.from_public_bytes(b"a" * 56)
     with pytest.raises(ValueError):
         Ed448PublicKey.from_public_bytes(b"a" * 58)
Exemplo n.º 16
0
    def __init__(self, params: Dict[int, Any]):
        super().__init__(params)
        self._public_key: Any = None
        self._private_key: Any = None
        self._hash_alg: Any = None
        self._x = None
        self._d = None

        # Validate kty.
        if params[1] != 1:
            raise ValueError("kty(1) should be OKP(1).")

        # Validate crv.
        if -1 not in params:
            raise ValueError("crv(-1) not found.")
        self._crv = params[-1]
        if not isinstance(self._crv, int):
            raise ValueError("crv(-1) should be int.")
        if self._crv not in [4, 5, 6, 7]:
            raise ValueError(
                f"Unsupported or unknown crv(-1) for OKP: {self._crv}.")
        if self._crv in [4, 5]:
            if not self._alg:
                raise ValueError("X25519/X448 needs alg explicitly.")
            if self._alg in [-25, -27]:
                self._hash_alg = hashes.SHA256
            elif self._alg in [-26, -28]:
                self._hash_alg = hashes.SHA512
            else:
                raise ValueError(
                    f"Unsupported or unknown alg used with X25519/X448: {self._alg}."
                )

        # Validate alg and key_ops.
        if self._key_ops:
            if set(self._key_ops) & set([3, 4, 5, 6, 9, 10]):
                raise ValueError(
                    "Unknown or not permissible key_ops(4) for OKP.")
        else:
            if self._crv in [4, 5]:
                self._key_ops = [7, 8] if -4 in params else []
            else:  # self._crv in [6, 7]
                self._key_ops = [1, 2] if -4 in params else [2]
        if self._alg:
            if self._alg in COSE_ALGORITHMS_SIG_OKP.values():
                if -4 in params:
                    # private key for signing.
                    if not (set(self._key_ops) & set([1, 2])):
                        raise ValueError("Invalid key_ops for signing key.")
                    if set(self._key_ops) & set([7, 8]):
                        raise ValueError(
                            "Signing key should not be used for key derivation."
                        )
                else:
                    # public key for signing.
                    if 2 not in self._key_ops or len(self._key_ops) != 1:
                        raise ValueError("Invalid key_ops for public key.")
            elif self._alg in COSE_ALGORITHMS_CKDM_KEY_AGREEMENT.values():
                if -4 in params:
                    # private key for key derivation.
                    if not (set(self._key_ops) & set([7, 8])):
                        raise ValueError("Invalid key_ops for key derivation.")
                    if set(self._key_ops) & set([1, 2]):
                        raise ValueError(
                            "Private key for ECDHE should not be used for signing."
                        )
                else:
                    # public key for key derivation.
                    if self._key_ops:
                        raise ValueError(
                            "Public key for ECDHE should not have key_ops.")
            else:
                raise ValueError(
                    f"Unsupported or unknown alg(3) for OKP: {self._alg}.")
        else:
            if -4 in params:
                # private key.
                if set(self._key_ops) & set([1, 2]):
                    # private key for signing.
                    if set(self._key_ops) & set([7, 8]):
                        raise ValueError(
                            "OKP private key should not be used for both signing and key derivation."
                        )
                    self._alg = -8  # EdDSA
            else:
                # public key.
                if 2 in self._key_ops:
                    if len(self._key_ops) > 1:
                        raise ValueError("Invalid key_ops for public key.")
                else:
                    raise ValueError("Invalid key_ops for public key.")

        if self._alg in COSE_ALGORITHMS_CKDM_KEY_AGREEMENT_ES.values():
            if -2 not in params:
                return

        # Validate x.
        if -2 not in params:
            raise ValueError("x(-2) not found.")
        if not isinstance(params[-2], bytes):
            raise ValueError("x(-2) should be bytes(bstr).")
        self._x = params[-2]
        try:
            if -4 not in params:
                if self._crv == 4:  # X25519
                    self._public_key = X25519PublicKey.from_public_bytes(
                        self._x)
                elif self._crv == 5:  # X448
                    self._public_key = X448PublicKey.from_public_bytes(self._x)
                elif self._crv == 6:  # Ed25519
                    self._public_key = Ed25519PublicKey.from_public_bytes(
                        self._x)
                else:  # self._crv == 7 (Ed448)
                    self._public_key = Ed448PublicKey.from_public_bytes(
                        self._x)
                self._key = self._public_key
                return
        except ValueError as err:
            raise ValueError("Invalid key parameter.") from err

        if not isinstance(params[-4], bytes):
            raise ValueError("d(-4) should be bytes(bstr).")

        try:
            self._d = params[-4]
            if self._crv == 4:  # X25519
                self._private_key = X25519PrivateKey.from_private_bytes(
                    self._d)
            elif self._crv == 5:  # X448
                self._private_key = X448PrivateKey.from_private_bytes(self._d)
            elif self._crv == 6:  # Ed25519
                self._private_key = Ed25519PrivateKey.from_private_bytes(
                    self._d)
            else:  # self._crv == 7 (Ed448)
                self._private_key = Ed448PrivateKey.from_private_bytes(self._d)
            self._key = self._private_key
        except ValueError as err:
            raise ValueError("Invalid key parameter.") from err
        return
Exemplo n.º 17
0
 def test_invalid_type_public_bytes(self, backend):
     with pytest.raises(TypeError):
         Ed448PublicKey.from_public_bytes(object())