diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/cryptography/hazmat/backends/openssl/backend.py | 11 | ||||
-rw-r--r-- | src/cryptography/hazmat/backends/openssl/ec.py | 57 | ||||
-rw-r--r-- | src/cryptography/hazmat/primitives/serialization/base.py | 3 |
3 files changed, 64 insertions, 7 deletions
diff --git a/src/cryptography/hazmat/backends/openssl/backend.py b/src/cryptography/hazmat/backends/openssl/backend.py index ab0daa28..b5232ba0 100644 --- a/src/cryptography/hazmat/backends/openssl/backend.py +++ b/src/cryptography/hazmat/backends/openssl/backend.py @@ -1690,6 +1690,10 @@ class Backend(object): "format must be an item from the PrivateFormat enum" ) + # X9.62 encoding is only valid for EC public keys + if encoding is serialization.Encoding.X962: + raise ValueError("X9.62 format is only valid for EC public keys") + # Raw format and encoding are only valid for X25519, Ed25519, X448, and # Ed448 keys. We capture those cases before this method is called so if # we see those enum values here it means the caller has passed them to @@ -1792,6 +1796,13 @@ class Backend(object): if not isinstance(encoding, serialization.Encoding): raise TypeError("encoding must be an item from the Encoding enum") + # Compressed/UncompressedPoint are only valid for EC keys and those + # cases are handled by the ECPublicKey public_bytes method before this + # method is called + if format in (serialization.PublicFormat.UncompressedPoint, + serialization.PublicFormat.CompressedPoint): + raise ValueError("Point formats are not valid for this key type") + # Raw format and encoding are only valid for X25519, Ed25519, X448, and # Ed448 keys. We capture those cases before this method is called so if # we see those enum values here it means the caller has passed them to diff --git a/src/cryptography/hazmat/backends/openssl/ec.py b/src/cryptography/hazmat/backends/openssl/ec.py index 852b4918..a8d69bdf 100644 --- a/src/cryptography/hazmat/backends/openssl/ec.py +++ b/src/cryptography/hazmat/backends/openssl/ec.py @@ -275,19 +275,62 @@ class _EllipticCurvePublicKey(object): curve=self._curve ) + def _encode_point(self, format): + if format is serialization.PublicFormat.CompressedPoint: + conversion = self._backend._lib.POINT_CONVERSION_COMPRESSED + else: + assert format is serialization.PublicFormat.UncompressedPoint + conversion = self._backend._lib.POINT_CONVERSION_UNCOMPRESSED + + group = self._backend._lib.EC_KEY_get0_group(self._ec_key) + self._backend.openssl_assert(group != self._backend._ffi.NULL) + point = self._backend._lib.EC_KEY_get0_public_key(self._ec_key) + self._backend.openssl_assert(point != self._backend._ffi.NULL) + with self._backend._tmp_bn_ctx() as bn_ctx: + buflen = self._backend._lib.EC_POINT_point2oct( + group, point, conversion, self._backend._ffi.NULL, 0, bn_ctx + ) + self._backend.openssl_assert(buflen > 0) + buf = self._backend._ffi.new("char[]", buflen) + res = self._backend._lib.EC_POINT_point2oct( + group, point, conversion, buf, buflen, bn_ctx + ) + self._backend.openssl_assert(buflen == res) + + return self._backend._ffi.buffer(buf)[:] + def public_bytes(self, encoding, format): if format is serialization.PublicFormat.PKCS1: raise ValueError( "EC public keys do not support PKCS1 serialization" ) - return self._backend._public_key_bytes( - encoding, - format, - self, - self._evp_pkey, - None - ) + if ( + encoding is serialization.Encoding.X962 or + format is serialization.PublicFormat.CompressedPoint or + format is serialization.PublicFormat.UncompressedPoint + ): + if ( + encoding is not serialization.Encoding.X962 or + format not in ( + serialization.PublicFormat.CompressedPoint, + serialization.PublicFormat.UncompressedPoint + ) + ): + raise ValueError( + "X962 encoding must be used with CompressedPoint or " + "UncompressedPoint format" + ) + + return self._encode_point(format) + else: + return self._backend._public_key_bytes( + encoding, + format, + self, + self._evp_pkey, + None + ) def verify(self, signature, data, signature_algorithm): _check_signature_algorithm(signature_algorithm) diff --git a/src/cryptography/hazmat/primitives/serialization/base.py b/src/cryptography/hazmat/primitives/serialization/base.py index 1670fd18..4218ea82 100644 --- a/src/cryptography/hazmat/primitives/serialization/base.py +++ b/src/cryptography/hazmat/primitives/serialization/base.py @@ -41,6 +41,7 @@ class Encoding(Enum): DER = "DER" OpenSSH = "OpenSSH" Raw = "Raw" + X962 = "ANSI X9.62" class PrivateFormat(Enum): @@ -54,6 +55,8 @@ class PublicFormat(Enum): PKCS1 = "Raw PKCS#1" OpenSSH = "OpenSSH" Raw = "Raw" + CompressedPoint = "X9.62 Compressed Point" + UncompressedPoint = "X9.62 Uncompressed Point" class ParameterFormat(Enum): |