1616
1717from cryptography import x509
1818from cryptography .hazmat .primitives import hashes
19- from cryptography .hazmat .primitives .asymmetric import rsa , ec , ed25519 , padding
20- from cryptography .hazmat .primitives .serialization import Encoding , PublicFormat
19+ from cryptography .hazmat .primitives .asymmetric import rsa , ec , ed25519
20+ from cryptography .hazmat .primitives .serialization import Encoding
2121from cryptography .hazmat .backends import default_backend
2222from cryptography .x509 .oid import NameOID
2323import datetime
@@ -189,284 +189,6 @@ def ca_cert(
189189 )
190190
191191
192- def signatures (force : bool ) -> None :
193- rsa_pub_exponent : int = 0x10001
194- backend : Any = default_backend ()
195- all_key_types : dict [str , ANY_PRIV_KEY ] = {
196- "ed25519" : ed25519 .Ed25519PrivateKey .generate (),
197- "ecdsa_p256" : ec .generate_private_key (ec .SECP256R1 (), backend ),
198- "ecdsa_p384" : ec .generate_private_key (ec .SECP384R1 (), backend ),
199- "ecdsa_p521" : ec .generate_private_key (ec .SECP521R1 (), backend ),
200- "rsa_1024_not_supported" : rsa .generate_private_key (
201- rsa_pub_exponent , 1024 , backend
202- ),
203- "rsa_2048" : rsa .generate_private_key (rsa_pub_exponent , 2048 , backend ),
204- "rsa_3072" : rsa .generate_private_key (rsa_pub_exponent , 3072 , backend ),
205- "rsa_4096" : rsa .generate_private_key (rsa_pub_exponent , 4096 , backend ),
206- }
207-
208- feature_gates = {
209- "ECDSA_P521_SHA256" : 'all(not(feature = "ring"), feature = "aws-lc-rs")' ,
210- "ECDSA_P521_SHA384" : 'all(not(feature = "ring"), feature = "aws-lc-rs")' ,
211- "ECDSA_P521_SHA512" : 'all(not(feature = "ring"), feature = "aws-lc-rs")' ,
212- }
213-
214- rsa_types : list [str ] = [
215- "RSA_PKCS1_2048_8192_SHA256" ,
216- "RSA_PKCS1_2048_8192_SHA384" ,
217- "RSA_PKCS1_2048_8192_SHA512" ,
218- "RSA_PSS_2048_8192_SHA256_LEGACY_KEY" ,
219- "RSA_PSS_2048_8192_SHA384_LEGACY_KEY" ,
220- "RSA_PSS_2048_8192_SHA512_LEGACY_KEY" ,
221- ]
222-
223- webpki_algs : dict [str , Iterable [str ]] = {
224- "ed25519" : ["ED25519" ],
225- "ecdsa_p256" : ["ECDSA_P256_SHA384" , "ECDSA_P256_SHA256" ],
226- "ecdsa_p384" : ["ECDSA_P384_SHA384" , "ECDSA_P384_SHA256" ],
227- "ecdsa_p521" : ["ECDSA_P521_SHA512" , "ECDSA_P521_SHA256" , "ECDSA_P521_SHA384" ],
228- "rsa_2048" : rsa_types ,
229- "rsa_3072" : rsa_types + ["RSA_PKCS1_3072_8192_SHA384" ],
230- "rsa_4096" : rsa_types + ["RSA_PKCS1_3072_8192_SHA384" ],
231- }
232-
233- pss_sha256 : padding .PSS = padding .PSS (
234- mgf = padding .MGF1 (hashes .SHA256 ()), salt_length = 32
235- )
236- pss_sha384 : padding .PSS = padding .PSS (
237- mgf = padding .MGF1 (hashes .SHA384 ()), salt_length = 48
238- )
239- pss_sha512 : padding .PSS = padding .PSS (
240- mgf = padding .MGF1 (hashes .SHA512 ()), salt_length = 64
241- )
242-
243- how_to_sign : dict [str , SIGNER ] = {
244- "ED25519" : lambda key , message : key .sign (message ),
245- "ECDSA_P256_SHA256" : lambda key , message : key .sign (
246- message , ec .ECDSA (hashes .SHA256 ())
247- ),
248- "ECDSA_P256_SHA384" : lambda key , message : key .sign (
249- message , ec .ECDSA (hashes .SHA384 ())
250- ),
251- "ECDSA_P384_SHA256" : lambda key , message : key .sign (
252- message , ec .ECDSA (hashes .SHA256 ())
253- ),
254- "ECDSA_P384_SHA384" : lambda key , message : key .sign (
255- message , ec .ECDSA (hashes .SHA384 ())
256- ),
257- "ECDSA_P521_SHA256" : lambda key , message : key .sign (
258- message , ec .ECDSA (hashes .SHA256 ())
259- ),
260- "ECDSA_P521_SHA384" : lambda key , message : key .sign (
261- message , ec .ECDSA (hashes .SHA384 ())
262- ),
263- "ECDSA_P521_SHA512" : lambda key , message : key .sign (
264- message , ec .ECDSA (hashes .SHA512 ())
265- ),
266- "RSA_PKCS1_2048_8192_SHA256" : lambda key , message : key .sign (
267- message , padding .PKCS1v15 (), hashes .SHA256 ()
268- ),
269- "RSA_PKCS1_2048_8192_SHA384" : lambda key , message : key .sign (
270- message , padding .PKCS1v15 (), hashes .SHA384 ()
271- ),
272- "RSA_PKCS1_2048_8192_SHA512" : lambda key , message : key .sign (
273- message , padding .PKCS1v15 (), hashes .SHA512 ()
274- ),
275- "RSA_PKCS1_3072_8192_SHA384" : lambda key , message : key .sign (
276- message , padding .PKCS1v15 (), hashes .SHA384 ()
277- ),
278- "RSA_PSS_2048_8192_SHA256_LEGACY_KEY" : lambda key , message : key .sign (
279- message , pss_sha256 , hashes .SHA256 ()
280- ),
281- "RSA_PSS_2048_8192_SHA384_LEGACY_KEY" : lambda key , message : key .sign (
282- message , pss_sha384 , hashes .SHA384 ()
283- ),
284- "RSA_PSS_2048_8192_SHA512_LEGACY_KEY" : lambda key , message : key .sign (
285- message , pss_sha512 , hashes .SHA512 ()
286- ),
287- }
288-
289- output_dir : str = "signatures"
290- if not os .path .isdir (output_dir ):
291- os .mkdir (output_dir )
292-
293- message = b"hello world!"
294- message_path : str = os .path .join (output_dir , "message.bin" )
295- write_der (message_path , message , force )
296-
297- def _cert_path (cert_type : str ) -> str :
298- return os .path .join (output_dir , f"{ cert_type } .ee.der" )
299-
300- def _rpk_path (rpk_type : str ) -> str :
301- return os .path .join (output_dir , f"{ rpk_type } .spki.der" )
302-
303- for name , private_key in all_key_types .items ():
304- ee_subject = x509 .Name (
305- [x509 .NameAttribute (NameOID .ORGANIZATION_NAME , name + " test" )]
306- )
307- issuer_subject = x509 .Name (
308- [x509 .NameAttribute (NameOID .ORGANIZATION_NAME , name + " issuer" )]
309- )
310- certificate : x509 .Certificate = end_entity_cert (
311- subject_name = ee_subject ,
312- subject_key = private_key ,
313- issuer_name = issuer_subject ,
314- )
315-
316- rpk_pub_key = private_key .public_key ().public_bytes (
317- Encoding .DER , PublicFormat .SubjectPublicKeyInfo
318- )
319- write_der (_rpk_path (name ), rpk_pub_key , force )
320- write_der (_cert_path (name ), certificate .public_bytes (Encoding .DER ), force )
321-
322- def _test (
323- test_name : str , cert_type : str , algorithm : str , signature : bytes , expected : str
324- ) -> None :
325- nonlocal message_path # noqa: F824
326- cert_path : str = _cert_path (cert_type )
327- rpk_path : str = _rpk_path (cert_type )
328- lower_test_name : str = test_name .lower ()
329-
330- sig_path : str = os .path .join (output_dir , f"{ lower_test_name } .sig.bin" )
331- write_der (sig_path , signature , force )
332- feature_gate : str = feature_gates .get (algorithm , "" )
333- if feature_gate :
334- feature_gate = f"#[cfg({ feature_gate } )]\n "
335-
336- print (
337- """
338- #[test]
339- %(feature_gate)sfn %(lower_test_name)s() {
340- let ee = include_bytes!("%(cert_path)s");
341- let message = include_bytes!("%(message_path)s");
342- let signature = include_bytes!("%(sig_path)s");
343- assert_eq!(
344- check_sig(ee, %(algorithm)s, message, signature),
345- %(expected)s
346- );
347- }""" % locals (),
348- file = output ,
349- )
350-
351- print (
352- """
353- #[test]
354- %(feature_gate)sfn %(lower_test_name)s_rpk() {
355- let rpk = include_bytes!("%(rpk_path)s");
356- let message = include_bytes!("%(message_path)s");
357- let signature = include_bytes!("%(sig_path)s");
358- assert_eq!(
359- check_sig_rpk(rpk, %(algorithm)s, message, signature),
360- %(expected)s
361- );
362- }""" % locals (),
363- file = output ,
364- )
365-
366- def good_signature (
367- test_name : str , cert_type : str , algorithm : str , signer : SIGNER
368- ) -> None :
369- signature : bytes = signer (all_key_types [cert_type ], message )
370- _test (test_name , cert_type , algorithm , signature , expected = "Ok(())" )
371-
372- def good_signature_but_rejected (
373- test_name : str , cert_type : str , algorithm : str , signer : SIGNER
374- ) -> None :
375- signature : bytes = signer (all_key_types [cert_type ], message )
376- _test (
377- test_name ,
378- cert_type ,
379- algorithm ,
380- signature ,
381- expected = "Err(webpki::Error::InvalidSignatureForPublicKey)" ,
382- )
383-
384- def bad_signature (
385- test_name : str , cert_type : str , algorithm : str , signer : SIGNER
386- ) -> None :
387- signature : bytes = signer (all_key_types [cert_type ], message + b"?" )
388- _test (
389- test_name ,
390- cert_type ,
391- algorithm ,
392- signature ,
393- expected = "Err(webpki::Error::InvalidSignatureForPublicKey)" ,
394- )
395-
396- def bad_algorithms_for_key (
397- test_name : str , cert_type : str , unusable_algs : set [str ]
398- ) -> None :
399- cert_path : str = _cert_path (cert_type )
400- test_name_lower : str = test_name .lower ()
401- unusable_algs_str : str = ", " .join (alg for alg in sorted (unusable_algs ))
402- print (
403- """
404- #[test]
405- fn %(test_name_lower)s() {
406- let ee = include_bytes!("%(cert_path)s");
407- for algorithm in &[ %(unusable_algs_str)s ] {
408- assert!(matches!(
409- check_sig(ee, *algorithm, b"", b""),
410- Err(webpki::Error::UnsupportedSignatureAlgorithmForPublicKey(_))
411- ));
412- }
413- }""" % locals (),
414- file = output ,
415- )
416-
417- with trim_top ("signatures.rs" ) as output :
418- # compute all webpki algorithms covered by these tests
419- all_webpki_algs : set [str ] = set (
420- [item for algs in webpki_algs .values () for item in algs ]
421- )
422-
423- for type , algs in webpki_algs .items ():
424- for alg in algs :
425- signer : SIGNER = how_to_sign [alg ]
426- good_signature (
427- type + "_key_and_" + alg + "_good_signature" ,
428- cert_type = type ,
429- algorithm = alg ,
430- signer = signer ,
431- )
432- bad_signature (
433- type + "_key_and_" + alg + "_detects_bad_signature" ,
434- cert_type = type ,
435- algorithm = alg ,
436- signer = signer ,
437- )
438-
439- unusable_algs = set (all_webpki_algs )
440- for alg in algs :
441- unusable_algs .remove (alg )
442-
443- # special case: tested separately below
444- if type == "rsa_2048" :
445- unusable_algs .remove ("RSA_PKCS1_3072_8192_SHA384" )
446-
447- unusable_algs = {
448- (
449- "#[cfg(%s)] %s" % (feature_gates [alg ], alg )
450- if alg in feature_gates
451- else alg
452- )
453- for alg in unusable_algs
454- }
455-
456- bad_algorithms_for_key (
457- type + "_key_rejected_by_other_algorithms" ,
458- cert_type = type ,
459- unusable_algs = unusable_algs ,
460- )
461-
462- good_signature_but_rejected (
463- "rsa_2048_key_rejected_by_RSA_PKCS1_3072_8192_SHA384" ,
464- cert_type = "rsa_2048" ,
465- algorithm = "RSA_PKCS1_3072_8192_SHA384" ,
466- signer = signer ,
467- )
468-
469-
470192def client_auth_revocation (force : bool ) -> None :
471193 output_dir : str = "client_auth_revocation"
472194 if not os .path .isdir (output_dir ):
@@ -1840,12 +1562,6 @@ def _expired_crl_enforce_expiration() -> None:
18401562
18411563if __name__ == "__main__" :
18421564 parser = argparse .ArgumentParser ()
1843- parser .add_argument (
1844- "--signatures" ,
1845- action = argparse .BooleanOptionalAction ,
1846- default = True ,
1847- help = "Generate signature testcases" ,
1848- )
18491565 parser .add_argument (
18501566 "--client-auth-revocation" ,
18511567 action = argparse .BooleanOptionalAction ,
@@ -1872,8 +1588,6 @@ def _expired_crl_enforce_expiration() -> None:
18721588 )
18731589 args = parser .parse_args ()
18741590
1875- if args .signatures :
1876- signatures (args .force )
18771591 if args .client_auth_revocation :
18781592 client_auth_revocation (args .force )
18791593
0 commit comments