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

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. 

4 

5 

6import typing 

7 

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 

15 

16if typing.TYPE_CHECKING: 

17 from cryptography.hazmat.backends.openssl.backend import Backend 

18 

19 

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 *") 

26 

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]) 

34 

35 return backend._ffi.buffer(sig_buf)[: buflen[0]] 

36 

37 

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 ) 

49 

50 if res != 1: 

51 backend._consume_errors() 

52 raise InvalidSignature 

53 

54 

55class _DSAParameters(dsa.DSAParameters): 

56 def __init__(self, backend: "Backend", dsa_cdata): 

57 self._backend = backend 

58 self._dsa_cdata = dsa_cdata 

59 

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 ) 

73 

74 def generate_private_key(self) -> dsa.DSAPrivateKey: 

75 return self._backend.generate_dsa_private_key(self) 

76 

77 

78class _DSAPrivateKey(dsa.DSAPrivateKey): 

79 _key_size: int 

80 

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 

85 

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]) 

92 

93 @property 

94 def key_size(self) -> int: 

95 return self._key_size 

96 

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 ) 

121 

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) 

140 

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) 

148 

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 ) 

163 

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) 

171 

172 

173class _DSAPublicKey(dsa.DSAPublicKey): 

174 _key_size: int 

175 

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]) 

186 

187 @property 

188 def key_size(self) -> int: 

189 return self._key_size 

190 

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 ) 

212 

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) 

219 

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 ) 

228 

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)