Skip to content

Commit 91e4189

Browse files
authored
Port DSA to Rust (#8978)
1 parent f302d28 commit 91e4189

File tree

20 files changed

+445
-364
lines changed

20 files changed

+445
-364
lines changed

src/_cffi_src/openssl/bignum.py

-2
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,6 @@
3939
int BN_MONT_CTX_set(BN_MONT_CTX *, const BIGNUM *, BN_CTX *);
4040
void BN_MONT_CTX_free(BN_MONT_CTX *);
4141
42-
BIGNUM *BN_dup(const BIGNUM *);
43-
4442
int BN_set_word(BIGNUM *, BN_ULONG);
4543
4644
char *BN_bn2hex(const BIGNUM *);

src/_cffi_src/openssl/dsa.py

-3
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,7 @@
2323
int DSA_verify(int, const unsigned char *, int, const unsigned char *, int,
2424
DSA *);
2525
26-
void DSA_get0_pqg(const DSA *, const BIGNUM **, const BIGNUM **,
27-
const BIGNUM **);
2826
int DSA_set0_pqg(DSA *, BIGNUM *, BIGNUM *, BIGNUM *);
29-
void DSA_get0_key(const DSA *, const BIGNUM **, const BIGNUM **);
3027
int DSA_set0_key(DSA *, BIGNUM *, BIGNUM *);
3128
int DSA_generate_parameters_ex(DSA *, int, unsigned char *, int,
3229
int *, unsigned long *, BN_GENCB *);

src/_cffi_src/openssl/evp.py

-1
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,6 @@
6666
int EVP_PKEY_type(int);
6767
int EVP_PKEY_size(EVP_PKEY *);
6868
RSA *EVP_PKEY_get1_RSA(EVP_PKEY *);
69-
DSA *EVP_PKEY_get1_DSA(EVP_PKEY *);
7069
7170
int EVP_PKEY_encrypt(EVP_PKEY_CTX *, unsigned char *, size_t *,
7271
const unsigned char *, size_t);

src/cryptography/hazmat/backends/openssl/backend.py

+16-101
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,6 @@
1515
from cryptography.hazmat.backends.openssl import aead
1616
from cryptography.hazmat.backends.openssl.ciphers import _CipherContext
1717
from cryptography.hazmat.backends.openssl.cmac import _CMACContext
18-
from cryptography.hazmat.backends.openssl.dsa import (
19-
_DSAParameters,
20-
_DSAPrivateKey,
21-
_DSAPublicKey,
22-
)
2318
from cryptography.hazmat.backends.openssl.ec import (
2419
_EllipticCurvePrivateKey,
2520
_EllipticCurvePublicKey,
@@ -551,10 +546,9 @@ def _evp_pkey_to_private_key(
551546
unsafe_skip_rsa_key_validation=unsafe_skip_rsa_key_validation,
552547
)
553548
elif key_type == self._lib.EVP_PKEY_DSA:
554-
dsa_cdata = self._lib.EVP_PKEY_get1_DSA(evp_pkey)
555-
self.openssl_assert(dsa_cdata != self._ffi.NULL)
556-
dsa_cdata = self._ffi.gc(dsa_cdata, self._lib.DSA_free)
557-
return _DSAPrivateKey(self, dsa_cdata, evp_pkey)
549+
return rust_openssl.dsa.private_key_from_ptr(
550+
int(self._ffi.cast("uintptr_t", evp_pkey))
551+
)
558552
elif key_type == self._lib.EVP_PKEY_EC:
559553
ec_cdata = self._lib.EVP_PKEY_get1_EC_KEY(evp_pkey)
560554
self.openssl_assert(ec_cdata != self._ffi.NULL)
@@ -613,10 +607,9 @@ def _evp_pkey_to_public_key(self, evp_pkey) -> PublicKeyTypes:
613607
self.openssl_assert(res == 1)
614608
return self.load_der_public_key(self._read_mem_bio(bio))
615609
elif key_type == self._lib.EVP_PKEY_DSA:
616-
dsa_cdata = self._lib.EVP_PKEY_get1_DSA(evp_pkey)
617-
self.openssl_assert(dsa_cdata != self._ffi.NULL)
618-
dsa_cdata = self._ffi.gc(dsa_cdata, self._lib.DSA_free)
619-
return _DSAPublicKey(self, dsa_cdata, evp_pkey)
610+
return rust_openssl.dsa.public_key_from_ptr(
611+
int(self._ffi.cast("uintptr_t", evp_pkey))
612+
)
620613
elif key_type == self._lib.EVP_PKEY_EC:
621614
ec_cdata = self._lib.EVP_PKEY_get1_EC_KEY(evp_pkey)
622615
if ec_cdata == self._ffi.NULL:
@@ -696,115 +689,41 @@ def generate_dsa_parameters(self, key_size: int) -> dsa.DSAParameters:
696689
"Key size must be 1024, 2048, 3072, or 4096 bits."
697690
)
698691

699-
ctx = self._lib.DSA_new()
700-
self.openssl_assert(ctx != self._ffi.NULL)
701-
ctx = self._ffi.gc(ctx, self._lib.DSA_free)
702-
703-
res = self._lib.DSA_generate_parameters_ex(
704-
ctx,
705-
key_size,
706-
self._ffi.NULL,
707-
0,
708-
self._ffi.NULL,
709-
self._ffi.NULL,
710-
self._ffi.NULL,
711-
)
712-
713-
self.openssl_assert(res == 1)
714-
715-
return _DSAParameters(self, ctx)
692+
return rust_openssl.dsa.generate_parameters(key_size)
716693

717694
def generate_dsa_private_key(
718695
self, parameters: dsa.DSAParameters
719696
) -> dsa.DSAPrivateKey:
720-
ctx = self._lib.DSAparams_dup(
721-
parameters._dsa_cdata # type: ignore[attr-defined]
722-
)
723-
self.openssl_assert(ctx != self._ffi.NULL)
724-
ctx = self._ffi.gc(ctx, self._lib.DSA_free)
725-
self._lib.DSA_generate_key(ctx)
726-
evp_pkey = self._dsa_cdata_to_evp_pkey(ctx)
727-
728-
return _DSAPrivateKey(self, ctx, evp_pkey)
697+
return parameters.generate_private_key()
729698

730699
def generate_dsa_private_key_and_parameters(
731700
self, key_size: int
732701
) -> dsa.DSAPrivateKey:
733702
parameters = self.generate_dsa_parameters(key_size)
734703
return self.generate_dsa_private_key(parameters)
735704

736-
def _dsa_cdata_set_values(
737-
self, dsa_cdata, p, q, g, pub_key, priv_key
738-
) -> None:
739-
res = self._lib.DSA_set0_pqg(dsa_cdata, p, q, g)
740-
self.openssl_assert(res == 1)
741-
res = self._lib.DSA_set0_key(dsa_cdata, pub_key, priv_key)
742-
self.openssl_assert(res == 1)
743-
744705
def load_dsa_private_numbers(
745706
self, numbers: dsa.DSAPrivateNumbers
746707
) -> dsa.DSAPrivateKey:
747708
dsa._check_dsa_private_numbers(numbers)
748-
parameter_numbers = numbers.public_numbers.parameter_numbers
749-
750-
dsa_cdata = self._lib.DSA_new()
751-
self.openssl_assert(dsa_cdata != self._ffi.NULL)
752-
dsa_cdata = self._ffi.gc(dsa_cdata, self._lib.DSA_free)
753-
754-
p = self._int_to_bn(parameter_numbers.p)
755-
q = self._int_to_bn(parameter_numbers.q)
756-
g = self._int_to_bn(parameter_numbers.g)
757-
pub_key = self._int_to_bn(numbers.public_numbers.y)
758-
priv_key = self._int_to_bn(numbers.x)
759-
self._dsa_cdata_set_values(dsa_cdata, p, q, g, pub_key, priv_key)
760-
761-
evp_pkey = self._dsa_cdata_to_evp_pkey(dsa_cdata)
762-
763-
return _DSAPrivateKey(self, dsa_cdata, evp_pkey)
709+
return rust_openssl.dsa.from_private_numbers(numbers)
764710

765711
def load_dsa_public_numbers(
766712
self, numbers: dsa.DSAPublicNumbers
767713
) -> dsa.DSAPublicKey:
768714
dsa._check_dsa_parameters(numbers.parameter_numbers)
769-
dsa_cdata = self._lib.DSA_new()
770-
self.openssl_assert(dsa_cdata != self._ffi.NULL)
771-
dsa_cdata = self._ffi.gc(dsa_cdata, self._lib.DSA_free)
772-
773-
p = self._int_to_bn(numbers.parameter_numbers.p)
774-
q = self._int_to_bn(numbers.parameter_numbers.q)
775-
g = self._int_to_bn(numbers.parameter_numbers.g)
776-
pub_key = self._int_to_bn(numbers.y)
777-
priv_key = self._ffi.NULL
778-
self._dsa_cdata_set_values(dsa_cdata, p, q, g, pub_key, priv_key)
779-
780-
evp_pkey = self._dsa_cdata_to_evp_pkey(dsa_cdata)
781-
782-
return _DSAPublicKey(self, dsa_cdata, evp_pkey)
715+
return rust_openssl.dsa.from_public_numbers(numbers)
783716

784717
def load_dsa_parameter_numbers(
785718
self, numbers: dsa.DSAParameterNumbers
786719
) -> dsa.DSAParameters:
787720
dsa._check_dsa_parameters(numbers)
788-
dsa_cdata = self._lib.DSA_new()
789-
self.openssl_assert(dsa_cdata != self._ffi.NULL)
790-
dsa_cdata = self._ffi.gc(dsa_cdata, self._lib.DSA_free)
791-
792-
p = self._int_to_bn(numbers.p)
793-
q = self._int_to_bn(numbers.q)
794-
g = self._int_to_bn(numbers.g)
795-
res = self._lib.DSA_set0_pqg(dsa_cdata, p, q, g)
796-
self.openssl_assert(res == 1)
797-
798-
return _DSAParameters(self, dsa_cdata)
799-
800-
def _dsa_cdata_to_evp_pkey(self, dsa_cdata):
801-
evp_pkey = self._create_evp_pkey_gc()
802-
res = self._lib.EVP_PKEY_set1_DSA(evp_pkey, dsa_cdata)
803-
self.openssl_assert(res == 1)
804-
return evp_pkey
721+
return rust_openssl.dsa.from_parameter_numbers(numbers)
805722

806723
def dsa_supported(self) -> bool:
807-
return not self._fips_enabled
724+
return (
725+
not self._lib.CRYPTOGRAPHY_IS_BORINGSSL and not self._fips_enabled
726+
)
808727

809728
def dsa_hash_supported(self, algorithm: hashes.HashAlgorithm) -> bool:
810729
if not self.dsa_supported():
@@ -1409,8 +1328,6 @@ def _private_key_bytes(
14091328
if encoding is serialization.Encoding.PEM:
14101329
if key_type == self._lib.EVP_PKEY_RSA:
14111330
write_bio = self._lib.PEM_write_bio_RSAPrivateKey
1412-
elif key_type == self._lib.EVP_PKEY_DSA:
1413-
write_bio = self._lib.PEM_write_bio_DSAPrivateKey
14141331
else:
14151332
assert key_type == self._lib.EVP_PKEY_EC
14161333
write_bio = self._lib.PEM_write_bio_ECPrivateKey
@@ -1426,11 +1343,9 @@ def _private_key_bytes(
14261343
)
14271344
if key_type == self._lib.EVP_PKEY_RSA:
14281345
write_bio = self._lib.i2d_RSAPrivateKey_bio
1429-
elif key_type == self._lib.EVP_PKEY_EC:
1430-
write_bio = self._lib.i2d_ECPrivateKey_bio
14311346
else:
1432-
assert key_type == self._lib.EVP_PKEY_DSA
1433-
write_bio = self._lib.i2d_DSAPrivateKey_bio
1347+
assert key_type == self._lib.EVP_PKEY_EC
1348+
write_bio = self._lib.i2d_ECPrivateKey_bio
14341349
return self._bio_func_output(write_bio, cdata)
14351350

14361351
raise ValueError("Unsupported encoding for TraditionalOpenSSL")

0 commit comments

Comments
 (0)