forked from GmSSL/GmSSL-Python
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtest_errors.py
More file actions
310 lines (225 loc) · 9.98 KB
/
test_errors.py
File metadata and controls
310 lines (225 loc) · 9.98 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
#!/usr/bin/env python
#
# Copyright 2023 The GmSSL Project. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the License); you may
# not use this file except in compliance with the License.
#
# http://www.apache.org/licenses/LICENSE-2.0
"""
Error handling and exception tests for GmSSL Python binding.
Tests various error conditions and exception handling to ensure
robust error reporting and proper validation.
"""
import pytest
from gmssl import (
DO_DECRYPT,
DO_ENCRYPT,
DO_SIGN,
DO_VERIFY,
SM2_DEFAULT_ID,
SM2_MAX_PLAINTEXT_SIZE,
Sm2Key,
Sm2Signature,
Sm3Hmac,
Sm4,
Sm4Cbc,
Sm4Ctr,
Sm4Gcm,
StateError,
Zuc,
sm3_pbkdf2,
)
# =============================================================================
# SM3 Error Tests
# =============================================================================
def test_sm3_hmac_invalid_key_too_short():
"""SM3-HMAC should reject keys that are too short."""
with pytest.raises(ValueError, match="Invalid SM3 HMAC key length"):
Sm3Hmac(b"short")
def test_sm3_hmac_invalid_key_too_long():
"""SM3-HMAC should reject keys that are too long."""
# SM3_HMAC_MAX_KEY_SIZE is 64
with pytest.raises(ValueError, match="Invalid SM3 HMAC key length"):
Sm3Hmac(b"x" * 65)
def test_sm3_pbkdf2_invalid_salt_too_long():
"""SM3-PBKDF2 should reject salt that is too long."""
# SM3_PBKDF2_MAX_SALT_SIZE is 64
with pytest.raises(ValueError, match="Invalid salt length"):
sm3_pbkdf2("password", b"x" * 65, 10000, 32)
def test_sm3_pbkdf2_invalid_iterator_too_small():
"""SM3-PBKDF2 should reject iterator count that is too small."""
# SM3_PBKDF2_MIN_ITER is 1
with pytest.raises(ValueError, match="Invalid iterator value"):
sm3_pbkdf2("password", b"salt", 0, 32)
def test_sm3_pbkdf2_invalid_iterator_too_large():
"""SM3-PBKDF2 should reject iterator count that is too large."""
# SM3_PBKDF2_MAX_ITER is 16777216
with pytest.raises(ValueError, match="Invalid iterator value"):
sm3_pbkdf2("password", b"salt", 16777217, 32)
def test_sm3_pbkdf2_invalid_keylen_too_large():
"""SM3-PBKDF2 should reject key length that is too large."""
# SM3_PBKDF2_MAX_KEY_SIZE is 256
with pytest.raises(ValueError, match="Invalid key length"):
sm3_pbkdf2("password", b"salt", 10000, 257)
# =============================================================================
# SM4 Error Tests
# =============================================================================
def test_sm4_invalid_key_length():
"""SM4 should reject invalid key length."""
with pytest.raises(ValueError, match="Invalid key length"):
Sm4(b"short_key", DO_ENCRYPT)
def test_sm4_invalid_block_size():
"""SM4 encrypt should reject invalid block size."""
sm4 = Sm4(b"1234567812345678", DO_ENCRYPT)
with pytest.raises(ValueError, match="Invalid block size"):
sm4.encrypt(b"short")
def test_sm4_decrypt_on_encrypt_mode():
"""SM4 decrypt should fail when called on encryption mode instance."""
sm4 = Sm4(b"1234567812345678", DO_ENCRYPT)
with pytest.raises(ValueError, match="Cannot call decrypt\\(\\) on encryption mode instance"):
sm4.decrypt(b"1234567812345678")
def test_sm4_decrypt_invalid_block_size():
"""SM4 decrypt should reject invalid block size."""
sm4 = Sm4(b"1234567812345678", DO_DECRYPT)
with pytest.raises(ValueError, match="Invalid block size"):
sm4.decrypt(b"short")
def test_sm4_cbc_invalid_key_length():
"""SM4-CBC should reject invalid key length."""
with pytest.raises(ValueError, match="Invalid key length"):
Sm4Cbc(b"short", b"1234567812345678", DO_ENCRYPT)
def test_sm4_cbc_invalid_iv_size():
"""SM4-CBC should reject invalid IV size."""
with pytest.raises(ValueError, match="Invalid IV size"):
Sm4Cbc(b"1234567812345678", b"short", DO_ENCRYPT)
def test_sm4_ctr_invalid_key_length():
"""SM4-CTR should reject invalid key length."""
with pytest.raises(ValueError, match="Invalid key length"):
Sm4Ctr(b"short", b"1234567812345678")
def test_sm4_ctr_invalid_ctr_size():
"""SM4-CTR should reject invalid CTR size."""
with pytest.raises(ValueError, match="Invalid CTR size"):
Sm4Ctr(b"1234567812345678", b"short")
def test_sm4_gcm_invalid_key_length():
"""SM4-GCM should reject invalid key length."""
with pytest.raises(ValueError, match="Invalid key length"):
Sm4Gcm(b"short", b"0123456789ab", b"aad", 16, DO_ENCRYPT)
def test_sm4_gcm_invalid_iv_too_short():
"""SM4-GCM should reject IV that is too short."""
# SM4_GCM_MIN_IV_SIZE is 1
with pytest.raises(ValueError, match="Invalid IV size"):
Sm4Gcm(b"1234567812345678", b"", b"aad", 16, DO_ENCRYPT)
def test_sm4_gcm_invalid_iv_too_long():
"""SM4-GCM should reject IV that is too long."""
# SM4_GCM_MAX_IV_SIZE is 64
with pytest.raises(ValueError, match="Invalid IV size"):
Sm4Gcm(b"1234567812345678", b"x" * 65, b"aad", 16, DO_ENCRYPT)
def test_sm4_gcm_invalid_tag_length():
"""SM4-GCM should reject invalid tag length."""
with pytest.raises(ValueError, match="Invalid Tag length"):
Sm4Gcm(b"1234567812345678", b"0123456789ab", b"aad", 0, DO_ENCRYPT)
# =============================================================================
# ZUC Error Tests
# =============================================================================
def test_zuc_invalid_key_length():
"""ZUC should reject invalid key length."""
with pytest.raises(ValueError, match="Invalid key length"):
Zuc(b"short", b"1234567812345678")
def test_zuc_invalid_iv_size():
"""ZUC should reject invalid IV size."""
with pytest.raises(ValueError, match="Invalid IV size"):
Zuc(b"1234567812345678", b"short")
# =============================================================================
# SM2 Error Tests
# =============================================================================
def test_sm2_sign_without_private_key():
"""SM2 sign should fail without private key."""
sm2 = Sm2Key()
# Key not generated, no private key
with pytest.raises(TypeError, match="has no private key"):
sm2.sign(b"0" * 32)
def test_sm2_encrypt_without_public_key():
"""SM2 encrypt should fail without public key."""
sm2 = Sm2Key()
# Key not generated, no public key
with pytest.raises(TypeError, match="has no public key"):
sm2.encrypt(b"plaintext")
def test_sm2_verify_without_public_key():
"""SM2 verify should fail without public key."""
sm2 = Sm2Key()
# Key not generated, no public key
with pytest.raises(TypeError, match="has no public key"):
sm2.verify(b"0" * 32, b"signature")
def test_sm2_decrypt_without_private_key():
"""SM2 decrypt should fail without private key."""
sm2 = Sm2Key()
# Key not generated, no private key
with pytest.raises(TypeError, match="has no private key"):
sm2.decrypt(b"ciphertext")
def test_sm2_compute_z_without_public_key():
"""SM2 compute_z should fail without public key."""
sm2 = Sm2Key()
# Key not generated, no public key
with pytest.raises(TypeError, match="has no public key"):
sm2.compute_z(SM2_DEFAULT_ID)
def test_sm2_sign_invalid_digest_size():
"""SM2 sign should reject invalid digest size."""
sm2 = Sm2Key()
sm2.generate_key()
with pytest.raises(ValueError, match="Invalid SM3 digest size"):
sm2.sign(b"invalid_digest")
def test_sm2_verify_invalid_digest_size():
"""SM2 verify should reject invalid digest size."""
sm2 = Sm2Key()
sm2.generate_key()
with pytest.raises(ValueError, match="Invalid SM3 digest size"):
sm2.verify(b"invalid_digest", b"signature")
def test_sm2_encrypt_plaintext_too_long():
"""SM2 encrypt should reject plaintext that is too long."""
sm2 = Sm2Key()
sm2.generate_key()
with pytest.raises(ValueError, match="Plaintext too long"):
sm2.encrypt(b"x" * (SM2_MAX_PLAINTEXT_SIZE + 1))
def test_sm2_export_private_key_without_private_key():
"""SM2 export private key should fail without private key."""
sm2 = Sm2Key()
# Key not generated, no private key
with pytest.raises(TypeError, match="has no private key"):
sm2.export_encrypted_private_key_info_pem("/tmp/test.pem", "password")
def test_sm2_export_public_key_without_public_key():
"""SM2 export public key should fail without public key."""
sm2 = Sm2Key()
# Key not generated, no public key
with pytest.raises(TypeError, match="has no public key"):
sm2.export_public_key_info_pem("/tmp/test.pem")
# =============================================================================
# SM2 Signature State Error Tests
# =============================================================================
def test_sm2_signature_sign_in_verify_state():
"""SM2 Signature sign should fail in verify state."""
sm2 = Sm2Key()
sm2.generate_key()
verify = Sm2Signature(sm2, SM2_DEFAULT_ID, DO_VERIFY)
verify.update(b"message")
with pytest.raises(StateError, match="not sign state"):
verify.sign()
def test_sm2_signature_verify_in_sign_state():
"""SM2 Signature verify should fail in sign state."""
sm2 = Sm2Key()
sm2.generate_key()
sign = Sm2Signature(sm2, SM2_DEFAULT_ID, DO_SIGN)
sign.update(b"message")
with pytest.raises(StateError, match="not verify state"):
sign.verify(b"signature")
def test_sm2_signature_init_without_private_key():
"""SM2 Signature init for signing should fail without private key."""
sm2 = Sm2Key()
# Key not generated, no private key
with pytest.raises(TypeError, match="SM2 key has no private key"):
Sm2Signature(sm2, SM2_DEFAULT_ID, DO_SIGN)
def test_sm2_signature_init_without_public_key():
"""SM2 Signature init for verifying should fail without public key."""
sm2 = Sm2Key()
# Key not generated, no public key
with pytest.raises(TypeError, match="SM2 key has no public key"):
Sm2Signature(sm2, SM2_DEFAULT_ID, DO_VERIFY)