@@ -871,6 +871,69 @@ def test_sign_file_callback_signer_managed(self):
871871 finally :
872872 shutil .rmtree (temp_dir )
873873
874+ def test_sign_file_callback_signer_managed_multiple_uses (self ):
875+ """Test that a signer can be used multiple times with context managers."""
876+
877+ temp_dir = tempfile .mkdtemp ()
878+
879+ try :
880+ # Create builder and signer with context managers
881+ with Builder (self .manifestDefinition ) as builder , create_signer (
882+ callback = self .callback_signer_es256 ,
883+ alg = SigningAlg .ES256 ,
884+ certs = self .certs .decode ('utf-8' ),
885+ tsa_url = "http://timestamp.digicert.com"
886+ ) as signer :
887+
888+ # First signing operation
889+ output_path_1 = os .path .join (temp_dir , "signed_output_1.jpg" )
890+ result_1 , manifest_bytes_1 = builder .sign_file (
891+ source_path = self .testPath ,
892+ dest_path = output_path_1 ,
893+ signer = signer
894+ )
895+
896+ # Verify first signing was successful
897+ self .assertTrue (os .path .exists (output_path_1 ))
898+ self .assertIsInstance (result_1 , int )
899+ self .assertIsInstance (manifest_bytes_1 , bytes )
900+ self .assertGreater (len (manifest_bytes_1 ), 0 )
901+
902+ # Second signing operation with the same signer
903+ # This is to verify we don't free the signer or the callback too early
904+ output_path_2 = os .path .join (temp_dir , "signed_output_2.jpg" )
905+ result_2 , manifest_bytes_2 = builder .sign_file (
906+ source_path = self .testPath ,
907+ dest_path = output_path_2 ,
908+ signer = signer
909+ )
910+
911+ # Verify second signing was successful
912+ self .assertTrue (os .path .exists (output_path_2 ))
913+ self .assertIsInstance (result_2 , int )
914+ self .assertIsInstance (manifest_bytes_2 , bytes )
915+ self .assertGreater (len (manifest_bytes_2 ), 0 )
916+
917+ # Verify both files contain valid C2PA data
918+ for output_path in [output_path_1 , output_path_2 ]:
919+ with open (output_path , "rb" ) as file , Reader ("image/jpeg" , file ) as reader :
920+ json_data = reader .json ()
921+ self .assertIn ("Python Test" , json_data )
922+ self .assertNotIn ("validation_status" , json_data )
923+
924+ # Parse the JSON and verify the signature algorithm
925+ manifest_data = json .loads (json_data )
926+ active_manifest_id = manifest_data ["active_manifest" ]
927+ active_manifest = manifest_data ["manifests" ][active_manifest_id ]
928+
929+ # Verify the signature_info contains the correct algorithm
930+ self .assertIn ("signature_info" , active_manifest )
931+ signature_info = active_manifest ["signature_info" ]
932+ self .assertEqual (signature_info ["alg" ], self .callback_signer_alg )
933+
934+ finally :
935+ shutil .rmtree (temp_dir )
936+
874937 def test_builder_sign_file_callback_signer_from_callback (self ):
875938 """Test signing a file using the sign_file method with Signer.from_callback."""
876939
0 commit comments