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

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 ( 

14 dsa, 

15 utils as asym_utils, 

16) 

17 

18 

19if typing.TYPE_CHECKING: 

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

21 

22 

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

29 

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

37 

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

39 

40 

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 ) 

52 

53 if res != 1: 

54 backend._consume_errors() 

55 raise InvalidSignature 

56 

57 

58class _DSAParameters(dsa.DSAParameters): 

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

60 self._backend = backend 

61 self._dsa_cdata = dsa_cdata 

62 

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 ) 

76 

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

78 return self._backend.generate_dsa_private_key(self) 

79 

80 

81class _DSAPrivateKey(dsa.DSAPrivateKey): 

82 _key_size: int 

83 

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 

88 

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

95 

96 @property 

97 def key_size(self) -> int: 

98 return self._key_size 

99 

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 ) 

124 

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) 

143 

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) 

151 

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 ) 

166 

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) 

174 

175 

176class _DSAPublicKey(dsa.DSAPublicKey): 

177 _key_size: int 

178 

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

189 

190 @property 

191 def key_size(self) -> int: 

192 return self._key_size 

193 

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 ) 

215 

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) 

222 

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 ) 

231 

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)