88import contextlib
99import itertools
1010import typing
11- from contextlib import contextmanager
1211
1312from cryptography import utils , x509
1413from cryptography .exceptions import UnsupportedAlgorithm , _Reasons
1514from cryptography .hazmat .backends .openssl import aead
1615from cryptography .hazmat .backends .openssl .ciphers import _CipherContext
1716from cryptography .hazmat .backends .openssl .cmac import _CMACContext
18- from cryptography .hazmat .backends .openssl .ec import (
19- _EllipticCurvePrivateKey ,
20- _EllipticCurvePublicKey ,
21- )
2217from cryptography .hazmat .backends .openssl .rsa import (
2318 _RSAPrivateKey ,
2419 _RSAPublicKey ,
@@ -542,10 +537,9 @@ def _evp_pkey_to_private_key(
542537 int (self ._ffi .cast ("uintptr_t" , evp_pkey ))
543538 )
544539 elif key_type == self ._lib .EVP_PKEY_EC :
545- ec_cdata = self ._lib .EVP_PKEY_get1_EC_KEY (evp_pkey )
546- self .openssl_assert (ec_cdata != self ._ffi .NULL )
547- ec_cdata = self ._ffi .gc (ec_cdata , self ._lib .EC_KEY_free )
548- return _EllipticCurvePrivateKey (self , ec_cdata , evp_pkey )
540+ return rust_openssl .ec .private_key_from_ptr (
541+ int (self ._ffi .cast ("uintptr_t" , evp_pkey ))
542+ )
549543 elif key_type in self ._dh_types :
550544 return rust_openssl .dh .private_key_from_ptr (
551545 int (self ._ffi .cast ("uintptr_t" , evp_pkey ))
@@ -603,12 +597,9 @@ def _evp_pkey_to_public_key(self, evp_pkey) -> PublicKeyTypes:
603597 int (self ._ffi .cast ("uintptr_t" , evp_pkey ))
604598 )
605599 elif key_type == self ._lib .EVP_PKEY_EC :
606- ec_cdata = self ._lib .EVP_PKEY_get1_EC_KEY (evp_pkey )
607- if ec_cdata == self ._ffi .NULL :
608- errors = self ._consume_errors ()
609- raise ValueError ("Unable to load EC key" , errors )
610- ec_cdata = self ._ffi .gc (ec_cdata , self ._lib .EC_KEY_free )
611- return _EllipticCurvePublicKey (self , ec_cdata , evp_pkey )
600+ return rust_openssl .ec .public_key_from_ptr (
601+ int (self ._ffi .cast ("uintptr_t" , evp_pkey ))
602+ )
612603 elif key_type in self ._dh_types :
613604 return rust_openssl .dh .public_key_from_ptr (
614605 int (self ._ffi .cast ("uintptr_t" , evp_pkey ))
@@ -944,20 +935,7 @@ def elliptic_curve_supported(self, curve: ec.EllipticCurve) -> bool:
944935 ):
945936 return False
946937
947- try :
948- curve_nid = self ._elliptic_curve_to_nid (curve )
949- except UnsupportedAlgorithm :
950- curve_nid = self ._lib .NID_undef
951-
952- group = self ._lib .EC_GROUP_new_by_curve_name (curve_nid )
953-
954- if group == self ._ffi .NULL :
955- self ._consume_errors ()
956- return False
957- else :
958- self .openssl_assert (curve_nid != self ._lib .NID_undef )
959- self ._lib .EC_GROUP_free (group )
960- return True
938+ return rust_openssl .ec .curve_supported (curve )
961939
962940 def elliptic_curve_signature_algorithm_supported (
963941 self ,
@@ -979,158 +957,27 @@ def generate_elliptic_curve_private_key(
979957 """
980958 Generate a new private key on the named curve.
981959 """
982-
983- if self .elliptic_curve_supported (curve ):
984- ec_cdata = self ._ec_key_new_by_curve (curve )
985-
986- res = self ._lib .EC_KEY_generate_key (ec_cdata )
987- self .openssl_assert (res == 1 )
988-
989- evp_pkey = self ._ec_cdata_to_evp_pkey (ec_cdata )
990-
991- return _EllipticCurvePrivateKey (self , ec_cdata , evp_pkey )
992- else :
993- raise UnsupportedAlgorithm (
994- f"Backend object does not support { curve .name } ." ,
995- _Reasons .UNSUPPORTED_ELLIPTIC_CURVE ,
996- )
960+ return rust_openssl .ec .generate_private_key (curve )
997961
998962 def load_elliptic_curve_private_numbers (
999963 self , numbers : ec .EllipticCurvePrivateNumbers
1000964 ) -> ec .EllipticCurvePrivateKey :
1001- public = numbers .public_numbers
1002-
1003- ec_cdata = self ._ec_key_new_by_curve (public .curve )
1004-
1005- private_value = self ._ffi .gc (
1006- self ._int_to_bn (numbers .private_value ), self ._lib .BN_clear_free
1007- )
1008- res = self ._lib .EC_KEY_set_private_key (ec_cdata , private_value )
1009- if res != 1 :
1010- self ._consume_errors ()
1011- raise ValueError ("Invalid EC key." )
1012-
1013- with self ._tmp_bn_ctx () as bn_ctx :
1014- self ._ec_key_set_public_key_affine_coordinates (
1015- ec_cdata , public .x , public .y , bn_ctx
1016- )
1017- # derive the expected public point and compare it to the one we
1018- # just set based on the values we were given. If they don't match
1019- # this isn't a valid key pair.
1020- group = self ._lib .EC_KEY_get0_group (ec_cdata )
1021- self .openssl_assert (group != self ._ffi .NULL )
1022- set_point = backend ._lib .EC_KEY_get0_public_key (ec_cdata )
1023- self .openssl_assert (set_point != self ._ffi .NULL )
1024- computed_point = self ._lib .EC_POINT_new (group )
1025- self .openssl_assert (computed_point != self ._ffi .NULL )
1026- computed_point = self ._ffi .gc (
1027- computed_point , self ._lib .EC_POINT_free
1028- )
1029- res = self ._lib .EC_POINT_mul (
1030- group ,
1031- computed_point ,
1032- private_value ,
1033- self ._ffi .NULL ,
1034- self ._ffi .NULL ,
1035- bn_ctx ,
1036- )
1037- self .openssl_assert (res == 1 )
1038- if (
1039- self ._lib .EC_POINT_cmp (
1040- group , set_point , computed_point , bn_ctx
1041- )
1042- != 0
1043- ):
1044- raise ValueError ("Invalid EC key." )
1045-
1046- evp_pkey = self ._ec_cdata_to_evp_pkey (ec_cdata )
1047-
1048- return _EllipticCurvePrivateKey (self , ec_cdata , evp_pkey )
965+ return rust_openssl .ec .from_private_numbers (numbers )
1049966
1050967 def load_elliptic_curve_public_numbers (
1051968 self , numbers : ec .EllipticCurvePublicNumbers
1052969 ) -> ec .EllipticCurvePublicKey :
1053- ec_cdata = self ._ec_key_new_by_curve (numbers .curve )
1054- with self ._tmp_bn_ctx () as bn_ctx :
1055- self ._ec_key_set_public_key_affine_coordinates (
1056- ec_cdata , numbers .x , numbers .y , bn_ctx
1057- )
1058- evp_pkey = self ._ec_cdata_to_evp_pkey (ec_cdata )
1059-
1060- return _EllipticCurvePublicKey (self , ec_cdata , evp_pkey )
970+ return rust_openssl .ec .from_public_numbers (numbers )
1061971
1062972 def load_elliptic_curve_public_bytes (
1063973 self , curve : ec .EllipticCurve , point_bytes : bytes
1064974 ) -> ec .EllipticCurvePublicKey :
1065- ec_cdata = self ._ec_key_new_by_curve (curve )
1066- group = self ._lib .EC_KEY_get0_group (ec_cdata )
1067- self .openssl_assert (group != self ._ffi .NULL )
1068- point = self ._lib .EC_POINT_new (group )
1069- self .openssl_assert (point != self ._ffi .NULL )
1070- point = self ._ffi .gc (point , self ._lib .EC_POINT_free )
1071- with self ._tmp_bn_ctx () as bn_ctx :
1072- res = self ._lib .EC_POINT_oct2point (
1073- group , point , point_bytes , len (point_bytes ), bn_ctx
1074- )
1075- if res != 1 :
1076- self ._consume_errors ()
1077- raise ValueError ("Invalid public bytes for the given curve" )
1078-
1079- res = self ._lib .EC_KEY_set_public_key (ec_cdata , point )
1080- self .openssl_assert (res == 1 )
1081- evp_pkey = self ._ec_cdata_to_evp_pkey (ec_cdata )
1082- return _EllipticCurvePublicKey (self , ec_cdata , evp_pkey )
975+ return rust_openssl .ec .from_public_bytes (curve , point_bytes )
1083976
1084977 def derive_elliptic_curve_private_key (
1085978 self , private_value : int , curve : ec .EllipticCurve
1086979 ) -> ec .EllipticCurvePrivateKey :
1087- ec_cdata = self ._ec_key_new_by_curve (curve )
1088-
1089- group = self ._lib .EC_KEY_get0_group (ec_cdata )
1090- self .openssl_assert (group != self ._ffi .NULL )
1091-
1092- point = self ._lib .EC_POINT_new (group )
1093- self .openssl_assert (point != self ._ffi .NULL )
1094- point = self ._ffi .gc (point , self ._lib .EC_POINT_free )
1095-
1096- value = self ._int_to_bn (private_value )
1097- value = self ._ffi .gc (value , self ._lib .BN_clear_free )
1098-
1099- with self ._tmp_bn_ctx () as bn_ctx :
1100- res = self ._lib .EC_POINT_mul (
1101- group , point , value , self ._ffi .NULL , self ._ffi .NULL , bn_ctx
1102- )
1103- self .openssl_assert (res == 1 )
1104-
1105- bn_x = self ._lib .BN_CTX_get (bn_ctx )
1106- bn_y = self ._lib .BN_CTX_get (bn_ctx )
1107-
1108- res = self ._lib .EC_POINT_get_affine_coordinates (
1109- group , point , bn_x , bn_y , bn_ctx
1110- )
1111- if res != 1 :
1112- self ._consume_errors ()
1113- raise ValueError ("Unable to derive key from private_value" )
1114-
1115- res = self ._lib .EC_KEY_set_public_key (ec_cdata , point )
1116- self .openssl_assert (res == 1 )
1117- private = self ._int_to_bn (private_value )
1118- private = self ._ffi .gc (private , self ._lib .BN_clear_free )
1119- res = self ._lib .EC_KEY_set_private_key (ec_cdata , private )
1120- self .openssl_assert (res == 1 )
1121-
1122- evp_pkey = self ._ec_cdata_to_evp_pkey (ec_cdata )
1123-
1124- return _EllipticCurvePrivateKey (self , ec_cdata , evp_pkey )
1125-
1126- def _ec_key_new_by_curve (self , curve : ec .EllipticCurve ):
1127- curve_nid = self ._elliptic_curve_to_nid (curve )
1128- return self ._ec_key_new_by_curve_nid (curve_nid )
1129-
1130- def _ec_key_new_by_curve_nid (self , curve_nid : int ):
1131- ec_cdata = self ._lib .EC_KEY_new_by_curve_name (curve_nid )
1132- self .openssl_assert (ec_cdata != self ._ffi .NULL )
1133- return self ._ffi .gc (ec_cdata , self ._lib .EC_KEY_free )
980+ return rust_openssl .ec .derive_private_key (private_value , curve )
1134981
1135982 def elliptic_curve_exchange_algorithm_supported (
1136983 self , algorithm : ec .ECDH , curve : ec .EllipticCurve
@@ -1139,73 +986,6 @@ def elliptic_curve_exchange_algorithm_supported(
1139986 algorithm , ec .ECDH
1140987 )
1141988
1142- def _ec_cdata_to_evp_pkey (self , ec_cdata ):
1143- evp_pkey = self ._create_evp_pkey_gc ()
1144- res = self ._lib .EVP_PKEY_set1_EC_KEY (evp_pkey , ec_cdata )
1145- self .openssl_assert (res == 1 )
1146- return evp_pkey
1147-
1148- def _elliptic_curve_to_nid (self , curve : ec .EllipticCurve ) -> int :
1149- """
1150- Get the NID for a curve name.
1151- """
1152-
1153- curve_aliases = {"secp192r1" : "prime192v1" , "secp256r1" : "prime256v1" }
1154-
1155- curve_name = curve_aliases .get (curve .name , curve .name )
1156-
1157- curve_nid = self ._lib .OBJ_sn2nid (curve_name .encode ())
1158- if curve_nid == self ._lib .NID_undef :
1159- raise UnsupportedAlgorithm (
1160- f"{ curve .name } is not a supported elliptic curve" ,
1161- _Reasons .UNSUPPORTED_ELLIPTIC_CURVE ,
1162- )
1163- return curve_nid
1164-
1165- @contextmanager
1166- def _tmp_bn_ctx (self ):
1167- bn_ctx = self ._lib .BN_CTX_new ()
1168- self .openssl_assert (bn_ctx != self ._ffi .NULL )
1169- bn_ctx = self ._ffi .gc (bn_ctx , self ._lib .BN_CTX_free )
1170- self ._lib .BN_CTX_start (bn_ctx )
1171- try :
1172- yield bn_ctx
1173- finally :
1174- self ._lib .BN_CTX_end (bn_ctx )
1175-
1176- def _ec_key_set_public_key_affine_coordinates (
1177- self ,
1178- ec_cdata ,
1179- x : int ,
1180- y : int ,
1181- bn_ctx ,
1182- ) -> None :
1183- """
1184- Sets the public key point in the EC_KEY context to the affine x and y
1185- values.
1186- """
1187-
1188- if x < 0 or y < 0 :
1189- raise ValueError (
1190- "Invalid EC key. Both x and y must be non-negative."
1191- )
1192-
1193- x = self ._ffi .gc (self ._int_to_bn (x ), self ._lib .BN_free )
1194- y = self ._ffi .gc (self ._int_to_bn (y ), self ._lib .BN_free )
1195- group = self ._lib .EC_KEY_get0_group (ec_cdata )
1196- self .openssl_assert (group != self ._ffi .NULL )
1197- point = self ._lib .EC_POINT_new (group )
1198- self .openssl_assert (point != self ._ffi .NULL )
1199- point = self ._ffi .gc (point , self ._lib .EC_POINT_free )
1200- res = self ._lib .EC_POINT_set_affine_coordinates (
1201- group , point , x , y , bn_ctx
1202- )
1203- if res != 1 :
1204- self ._consume_errors ()
1205- raise ValueError ("Invalid EC key." )
1206- res = self ._lib .EC_KEY_set_public_key (ec_cdata , point )
1207- self .openssl_assert (res == 1 )
1208-
1209989 def _private_key_bytes (
1210990 self ,
1211991 encoding : serialization .Encoding ,
@@ -1278,11 +1058,8 @@ def _private_key_bytes(
12781058 key_type = self ._lib .EVP_PKEY_id (evp_pkey )
12791059
12801060 if encoding is serialization .Encoding .PEM :
1281- if key_type == self ._lib .EVP_PKEY_RSA :
1282- write_bio = self ._lib .PEM_write_bio_RSAPrivateKey
1283- else :
1284- assert key_type == self ._lib .EVP_PKEY_EC
1285- write_bio = self ._lib .PEM_write_bio_ECPrivateKey
1061+ assert key_type == self ._lib .EVP_PKEY_RSA
1062+ write_bio = self ._lib .PEM_write_bio_RSAPrivateKey
12861063 return self ._private_key_bytes_via_bio (
12871064 write_bio , cdata , password
12881065 )
@@ -1293,11 +1070,8 @@ def _private_key_bytes(
12931070 "Encryption is not supported for DER encoded "
12941071 "traditional OpenSSL keys"
12951072 )
1296- if key_type == self ._lib .EVP_PKEY_RSA :
1297- write_bio = self ._lib .i2d_RSAPrivateKey_bio
1298- else :
1299- assert key_type == self ._lib .EVP_PKEY_EC
1300- write_bio = self ._lib .i2d_ECPrivateKey_bio
1073+ assert key_type == self ._lib .EVP_PKEY_RSA
1074+ write_bio = self ._lib .i2d_RSAPrivateKey_bio
13011075 return self ._bio_func_output (write_bio , cdata )
13021076
13031077 raise ValueError ("Unsupported encoding for TraditionalOpenSSL" )
@@ -1374,8 +1148,7 @@ def _public_key_bytes(
13741148 if format is serialization .PublicFormat .PKCS1 :
13751149 # Only RSA is supported here.
13761150 key_type = self ._lib .EVP_PKEY_id (evp_pkey )
1377- if key_type != self ._lib .EVP_PKEY_RSA :
1378- raise ValueError ("PKCS1 format is supported only for RSA keys" )
1151+ self .openssl_assert (key_type == self ._lib .EVP_PKEY_RSA )
13791152
13801153 if encoding is serialization .Encoding .PEM :
13811154 write_bio = self ._lib .PEM_write_bio_RSAPublicKey
0 commit comments