Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/cryptography/hazmat/backends/openssl/dsa.py: 27%
119 statements
« prev ^ index » next coverage.py v7.2.2, created at 2023-03-26 06:36 +0000
« prev ^ index » next coverage.py v7.2.2, created at 2023-03-26 06:36 +0000
1# This file is dual licensed under the terms of the Apache License, Version
2# 2.0, and the BSD License. See the LICENSE file in the root of this repository
3# for complete details.
6import typing
8from cryptography.exceptions import InvalidSignature
9from cryptography.hazmat.backends.openssl.utils import (
10 _calculate_digest_and_algorithm,
11)
12from cryptography.hazmat.primitives import hashes, serialization
13from cryptography.hazmat.primitives.asymmetric import dsa
14from cryptography.hazmat.primitives.asymmetric import utils as asym_utils
16if typing.TYPE_CHECKING:
17 from cryptography.hazmat.backends.openssl.backend import Backend
20def _dsa_sig_sign(
21 backend: "Backend", private_key: "_DSAPrivateKey", data: bytes
22) -> bytes:
23 sig_buf_len = backend._lib.DSA_size(private_key._dsa_cdata)
24 sig_buf = backend._ffi.new("unsigned char[]", sig_buf_len)
25 buflen = backend._ffi.new("unsigned int *")
27 # The first parameter passed to DSA_sign is unused by OpenSSL but
28 # must be an integer.
29 res = backend._lib.DSA_sign(
30 0, data, len(data), sig_buf, buflen, private_key._dsa_cdata
31 )
32 backend.openssl_assert(res == 1)
33 backend.openssl_assert(buflen[0])
35 return backend._ffi.buffer(sig_buf)[: buflen[0]]
38def _dsa_sig_verify(
39 backend: "Backend",
40 public_key: "_DSAPublicKey",
41 signature: bytes,
42 data: bytes,
43) -> None:
44 # The first parameter passed to DSA_verify is unused by OpenSSL but
45 # must be an integer.
46 res = backend._lib.DSA_verify(
47 0, data, len(data), signature, len(signature), public_key._dsa_cdata
48 )
50 if res != 1:
51 backend._consume_errors()
52 raise InvalidSignature
55class _DSAParameters(dsa.DSAParameters):
56 def __init__(self, backend: "Backend", dsa_cdata):
57 self._backend = backend
58 self._dsa_cdata = dsa_cdata
60 def parameter_numbers(self) -> dsa.DSAParameterNumbers:
61 p = self._backend._ffi.new("BIGNUM **")
62 q = self._backend._ffi.new("BIGNUM **")
63 g = self._backend._ffi.new("BIGNUM **")
64 self._backend._lib.DSA_get0_pqg(self._dsa_cdata, p, q, g)
65 self._backend.openssl_assert(p[0] != self._backend._ffi.NULL)
66 self._backend.openssl_assert(q[0] != self._backend._ffi.NULL)
67 self._backend.openssl_assert(g[0] != self._backend._ffi.NULL)
68 return dsa.DSAParameterNumbers(
69 p=self._backend._bn_to_int(p[0]),
70 q=self._backend._bn_to_int(q[0]),
71 g=self._backend._bn_to_int(g[0]),
72 )
74 def generate_private_key(self) -> dsa.DSAPrivateKey:
75 return self._backend.generate_dsa_private_key(self)
78class _DSAPrivateKey(dsa.DSAPrivateKey):
79 _key_size: int
81 def __init__(self, backend: "Backend", dsa_cdata, evp_pkey):
82 self._backend = backend
83 self._dsa_cdata = dsa_cdata
84 self._evp_pkey = evp_pkey
86 p = self._backend._ffi.new("BIGNUM **")
87 self._backend._lib.DSA_get0_pqg(
88 dsa_cdata, p, self._backend._ffi.NULL, self._backend._ffi.NULL
89 )
90 self._backend.openssl_assert(p[0] != backend._ffi.NULL)
91 self._key_size = self._backend._lib.BN_num_bits(p[0])
93 @property
94 def key_size(self) -> int:
95 return self._key_size
97 def private_numbers(self) -> dsa.DSAPrivateNumbers:
98 p = self._backend._ffi.new("BIGNUM **")
99 q = self._backend._ffi.new("BIGNUM **")
100 g = self._backend._ffi.new("BIGNUM **")
101 pub_key = self._backend._ffi.new("BIGNUM **")
102 priv_key = self._backend._ffi.new("BIGNUM **")
103 self._backend._lib.DSA_get0_pqg(self._dsa_cdata, p, q, g)
104 self._backend.openssl_assert(p[0] != self._backend._ffi.NULL)
105 self._backend.openssl_assert(q[0] != self._backend._ffi.NULL)
106 self._backend.openssl_assert(g[0] != self._backend._ffi.NULL)
107 self._backend._lib.DSA_get0_key(self._dsa_cdata, pub_key, priv_key)
108 self._backend.openssl_assert(pub_key[0] != self._backend._ffi.NULL)
109 self._backend.openssl_assert(priv_key[0] != self._backend._ffi.NULL)
110 return dsa.DSAPrivateNumbers(
111 public_numbers=dsa.DSAPublicNumbers(
112 parameter_numbers=dsa.DSAParameterNumbers(
113 p=self._backend._bn_to_int(p[0]),
114 q=self._backend._bn_to_int(q[0]),
115 g=self._backend._bn_to_int(g[0]),
116 ),
117 y=self._backend._bn_to_int(pub_key[0]),
118 ),
119 x=self._backend._bn_to_int(priv_key[0]),
120 )
122 def public_key(self) -> dsa.DSAPublicKey:
123 dsa_cdata = self._backend._lib.DSAparams_dup(self._dsa_cdata)
124 self._backend.openssl_assert(dsa_cdata != self._backend._ffi.NULL)
125 dsa_cdata = self._backend._ffi.gc(
126 dsa_cdata, self._backend._lib.DSA_free
127 )
128 pub_key = self._backend._ffi.new("BIGNUM **")
129 self._backend._lib.DSA_get0_key(
130 self._dsa_cdata, pub_key, self._backend._ffi.NULL
131 )
132 self._backend.openssl_assert(pub_key[0] != self._backend._ffi.NULL)
133 pub_key_dup = self._backend._lib.BN_dup(pub_key[0])
134 res = self._backend._lib.DSA_set0_key(
135 dsa_cdata, pub_key_dup, self._backend._ffi.NULL
136 )
137 self._backend.openssl_assert(res == 1)
138 evp_pkey = self._backend._dsa_cdata_to_evp_pkey(dsa_cdata)
139 return _DSAPublicKey(self._backend, dsa_cdata, evp_pkey)
141 def parameters(self) -> dsa.DSAParameters:
142 dsa_cdata = self._backend._lib.DSAparams_dup(self._dsa_cdata)
143 self._backend.openssl_assert(dsa_cdata != self._backend._ffi.NULL)
144 dsa_cdata = self._backend._ffi.gc(
145 dsa_cdata, self._backend._lib.DSA_free
146 )
147 return _DSAParameters(self._backend, dsa_cdata)
149 def private_bytes(
150 self,
151 encoding: serialization.Encoding,
152 format: serialization.PrivateFormat,
153 encryption_algorithm: serialization.KeySerializationEncryption,
154 ) -> bytes:
155 return self._backend._private_key_bytes(
156 encoding,
157 format,
158 encryption_algorithm,
159 self,
160 self._evp_pkey,
161 self._dsa_cdata,
162 )
164 def sign(
165 self,
166 data: bytes,
167 algorithm: typing.Union[asym_utils.Prehashed, hashes.HashAlgorithm],
168 ) -> bytes:
169 data, _ = _calculate_digest_and_algorithm(data, algorithm)
170 return _dsa_sig_sign(self._backend, self, data)
173class _DSAPublicKey(dsa.DSAPublicKey):
174 _key_size: int
176 def __init__(self, backend: "Backend", dsa_cdata, evp_pkey):
177 self._backend = backend
178 self._dsa_cdata = dsa_cdata
179 self._evp_pkey = evp_pkey
180 p = self._backend._ffi.new("BIGNUM **")
181 self._backend._lib.DSA_get0_pqg(
182 dsa_cdata, p, self._backend._ffi.NULL, self._backend._ffi.NULL
183 )
184 self._backend.openssl_assert(p[0] != backend._ffi.NULL)
185 self._key_size = self._backend._lib.BN_num_bits(p[0])
187 @property
188 def key_size(self) -> int:
189 return self._key_size
191 def public_numbers(self) -> dsa.DSAPublicNumbers:
192 p = self._backend._ffi.new("BIGNUM **")
193 q = self._backend._ffi.new("BIGNUM **")
194 g = self._backend._ffi.new("BIGNUM **")
195 pub_key = self._backend._ffi.new("BIGNUM **")
196 self._backend._lib.DSA_get0_pqg(self._dsa_cdata, p, q, g)
197 self._backend.openssl_assert(p[0] != self._backend._ffi.NULL)
198 self._backend.openssl_assert(q[0] != self._backend._ffi.NULL)
199 self._backend.openssl_assert(g[0] != self._backend._ffi.NULL)
200 self._backend._lib.DSA_get0_key(
201 self._dsa_cdata, pub_key, self._backend._ffi.NULL
202 )
203 self._backend.openssl_assert(pub_key[0] != self._backend._ffi.NULL)
204 return dsa.DSAPublicNumbers(
205 parameter_numbers=dsa.DSAParameterNumbers(
206 p=self._backend._bn_to_int(p[0]),
207 q=self._backend._bn_to_int(q[0]),
208 g=self._backend._bn_to_int(g[0]),
209 ),
210 y=self._backend._bn_to_int(pub_key[0]),
211 )
213 def parameters(self) -> dsa.DSAParameters:
214 dsa_cdata = self._backend._lib.DSAparams_dup(self._dsa_cdata)
215 dsa_cdata = self._backend._ffi.gc(
216 dsa_cdata, self._backend._lib.DSA_free
217 )
218 return _DSAParameters(self._backend, dsa_cdata)
220 def public_bytes(
221 self,
222 encoding: serialization.Encoding,
223 format: serialization.PublicFormat,
224 ) -> bytes:
225 return self._backend._public_key_bytes(
226 encoding, format, self, self._evp_pkey, None
227 )
229 def verify(
230 self,
231 signature: bytes,
232 data: bytes,
233 algorithm: typing.Union[asym_utils.Prehashed, hashes.HashAlgorithm],
234 ) -> None:
235 data, _ = _calculate_digest_and_algorithm(data, algorithm)
236 return _dsa_sig_verify(self._backend, self, signature, data)