Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/cryptography/hazmat/backends/openssl/dsa.py: 26%
118 statements
« prev ^ index » next coverage.py v7.0.1, created at 2022-12-25 06:11 +0000
« prev ^ index » next coverage.py v7.0.1, created at 2022-12-25 06:11 +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 (
14 dsa,
15 utils as asym_utils,
16)
19if typing.TYPE_CHECKING:
20 from cryptography.hazmat.backends.openssl.backend import Backend
23def _dsa_sig_sign(
24 backend: "Backend", private_key: "_DSAPrivateKey", data: bytes
25) -> bytes:
26 sig_buf_len = backend._lib.DSA_size(private_key._dsa_cdata)
27 sig_buf = backend._ffi.new("unsigned char[]", sig_buf_len)
28 buflen = backend._ffi.new("unsigned int *")
30 # The first parameter passed to DSA_sign is unused by OpenSSL but
31 # must be an integer.
32 res = backend._lib.DSA_sign(
33 0, data, len(data), sig_buf, buflen, private_key._dsa_cdata
34 )
35 backend.openssl_assert(res == 1)
36 backend.openssl_assert(buflen[0])
38 return backend._ffi.buffer(sig_buf)[: buflen[0]]
41def _dsa_sig_verify(
42 backend: "Backend",
43 public_key: "_DSAPublicKey",
44 signature: bytes,
45 data: bytes,
46) -> None:
47 # The first parameter passed to DSA_verify is unused by OpenSSL but
48 # must be an integer.
49 res = backend._lib.DSA_verify(
50 0, data, len(data), signature, len(signature), public_key._dsa_cdata
51 )
53 if res != 1:
54 backend._consume_errors()
55 raise InvalidSignature
58class _DSAParameters(dsa.DSAParameters):
59 def __init__(self, backend: "Backend", dsa_cdata):
60 self._backend = backend
61 self._dsa_cdata = dsa_cdata
63 def parameter_numbers(self) -> dsa.DSAParameterNumbers:
64 p = self._backend._ffi.new("BIGNUM **")
65 q = self._backend._ffi.new("BIGNUM **")
66 g = self._backend._ffi.new("BIGNUM **")
67 self._backend._lib.DSA_get0_pqg(self._dsa_cdata, p, q, g)
68 self._backend.openssl_assert(p[0] != self._backend._ffi.NULL)
69 self._backend.openssl_assert(q[0] != self._backend._ffi.NULL)
70 self._backend.openssl_assert(g[0] != self._backend._ffi.NULL)
71 return dsa.DSAParameterNumbers(
72 p=self._backend._bn_to_int(p[0]),
73 q=self._backend._bn_to_int(q[0]),
74 g=self._backend._bn_to_int(g[0]),
75 )
77 def generate_private_key(self) -> dsa.DSAPrivateKey:
78 return self._backend.generate_dsa_private_key(self)
81class _DSAPrivateKey(dsa.DSAPrivateKey):
82 _key_size: int
84 def __init__(self, backend: "Backend", dsa_cdata, evp_pkey):
85 self._backend = backend
86 self._dsa_cdata = dsa_cdata
87 self._evp_pkey = evp_pkey
89 p = self._backend._ffi.new("BIGNUM **")
90 self._backend._lib.DSA_get0_pqg(
91 dsa_cdata, p, self._backend._ffi.NULL, self._backend._ffi.NULL
92 )
93 self._backend.openssl_assert(p[0] != backend._ffi.NULL)
94 self._key_size = self._backend._lib.BN_num_bits(p[0])
96 @property
97 def key_size(self) -> int:
98 return self._key_size
100 def private_numbers(self) -> dsa.DSAPrivateNumbers:
101 p = self._backend._ffi.new("BIGNUM **")
102 q = self._backend._ffi.new("BIGNUM **")
103 g = self._backend._ffi.new("BIGNUM **")
104 pub_key = self._backend._ffi.new("BIGNUM **")
105 priv_key = self._backend._ffi.new("BIGNUM **")
106 self._backend._lib.DSA_get0_pqg(self._dsa_cdata, p, q, g)
107 self._backend.openssl_assert(p[0] != self._backend._ffi.NULL)
108 self._backend.openssl_assert(q[0] != self._backend._ffi.NULL)
109 self._backend.openssl_assert(g[0] != self._backend._ffi.NULL)
110 self._backend._lib.DSA_get0_key(self._dsa_cdata, pub_key, priv_key)
111 self._backend.openssl_assert(pub_key[0] != self._backend._ffi.NULL)
112 self._backend.openssl_assert(priv_key[0] != self._backend._ffi.NULL)
113 return dsa.DSAPrivateNumbers(
114 public_numbers=dsa.DSAPublicNumbers(
115 parameter_numbers=dsa.DSAParameterNumbers(
116 p=self._backend._bn_to_int(p[0]),
117 q=self._backend._bn_to_int(q[0]),
118 g=self._backend._bn_to_int(g[0]),
119 ),
120 y=self._backend._bn_to_int(pub_key[0]),
121 ),
122 x=self._backend._bn_to_int(priv_key[0]),
123 )
125 def public_key(self) -> dsa.DSAPublicKey:
126 dsa_cdata = self._backend._lib.DSAparams_dup(self._dsa_cdata)
127 self._backend.openssl_assert(dsa_cdata != self._backend._ffi.NULL)
128 dsa_cdata = self._backend._ffi.gc(
129 dsa_cdata, self._backend._lib.DSA_free
130 )
131 pub_key = self._backend._ffi.new("BIGNUM **")
132 self._backend._lib.DSA_get0_key(
133 self._dsa_cdata, pub_key, self._backend._ffi.NULL
134 )
135 self._backend.openssl_assert(pub_key[0] != self._backend._ffi.NULL)
136 pub_key_dup = self._backend._lib.BN_dup(pub_key[0])
137 res = self._backend._lib.DSA_set0_key(
138 dsa_cdata, pub_key_dup, self._backend._ffi.NULL
139 )
140 self._backend.openssl_assert(res == 1)
141 evp_pkey = self._backend._dsa_cdata_to_evp_pkey(dsa_cdata)
142 return _DSAPublicKey(self._backend, dsa_cdata, evp_pkey)
144 def parameters(self) -> dsa.DSAParameters:
145 dsa_cdata = self._backend._lib.DSAparams_dup(self._dsa_cdata)
146 self._backend.openssl_assert(dsa_cdata != self._backend._ffi.NULL)
147 dsa_cdata = self._backend._ffi.gc(
148 dsa_cdata, self._backend._lib.DSA_free
149 )
150 return _DSAParameters(self._backend, dsa_cdata)
152 def private_bytes(
153 self,
154 encoding: serialization.Encoding,
155 format: serialization.PrivateFormat,
156 encryption_algorithm: serialization.KeySerializationEncryption,
157 ) -> bytes:
158 return self._backend._private_key_bytes(
159 encoding,
160 format,
161 encryption_algorithm,
162 self,
163 self._evp_pkey,
164 self._dsa_cdata,
165 )
167 def sign(
168 self,
169 data: bytes,
170 algorithm: typing.Union[asym_utils.Prehashed, hashes.HashAlgorithm],
171 ) -> bytes:
172 data, _ = _calculate_digest_and_algorithm(data, algorithm)
173 return _dsa_sig_sign(self._backend, self, data)
176class _DSAPublicKey(dsa.DSAPublicKey):
177 _key_size: int
179 def __init__(self, backend: "Backend", dsa_cdata, evp_pkey):
180 self._backend = backend
181 self._dsa_cdata = dsa_cdata
182 self._evp_pkey = evp_pkey
183 p = self._backend._ffi.new("BIGNUM **")
184 self._backend._lib.DSA_get0_pqg(
185 dsa_cdata, p, self._backend._ffi.NULL, self._backend._ffi.NULL
186 )
187 self._backend.openssl_assert(p[0] != backend._ffi.NULL)
188 self._key_size = self._backend._lib.BN_num_bits(p[0])
190 @property
191 def key_size(self) -> int:
192 return self._key_size
194 def public_numbers(self) -> dsa.DSAPublicNumbers:
195 p = self._backend._ffi.new("BIGNUM **")
196 q = self._backend._ffi.new("BIGNUM **")
197 g = self._backend._ffi.new("BIGNUM **")
198 pub_key = self._backend._ffi.new("BIGNUM **")
199 self._backend._lib.DSA_get0_pqg(self._dsa_cdata, p, q, g)
200 self._backend.openssl_assert(p[0] != self._backend._ffi.NULL)
201 self._backend.openssl_assert(q[0] != self._backend._ffi.NULL)
202 self._backend.openssl_assert(g[0] != self._backend._ffi.NULL)
203 self._backend._lib.DSA_get0_key(
204 self._dsa_cdata, pub_key, self._backend._ffi.NULL
205 )
206 self._backend.openssl_assert(pub_key[0] != self._backend._ffi.NULL)
207 return dsa.DSAPublicNumbers(
208 parameter_numbers=dsa.DSAParameterNumbers(
209 p=self._backend._bn_to_int(p[0]),
210 q=self._backend._bn_to_int(q[0]),
211 g=self._backend._bn_to_int(g[0]),
212 ),
213 y=self._backend._bn_to_int(pub_key[0]),
214 )
216 def parameters(self) -> dsa.DSAParameters:
217 dsa_cdata = self._backend._lib.DSAparams_dup(self._dsa_cdata)
218 dsa_cdata = self._backend._ffi.gc(
219 dsa_cdata, self._backend._lib.DSA_free
220 )
221 return _DSAParameters(self._backend, dsa_cdata)
223 def public_bytes(
224 self,
225 encoding: serialization.Encoding,
226 format: serialization.PublicFormat,
227 ) -> bytes:
228 return self._backend._public_key_bytes(
229 encoding, format, self, self._evp_pkey, None
230 )
232 def verify(
233 self,
234 signature: bytes,
235 data: bytes,
236 algorithm: typing.Union[asym_utils.Prehashed, hashes.HashAlgorithm],
237 ) -> None:
238 data, _ = _calculate_digest_and_algorithm(data, algorithm)
239 return _dsa_sig_verify(self._backend, self, signature, data)