@@ -128,74 +128,58 @@ def open_block_device(path):
128128 return NamedFile (file_obj , path )
129129
130130
131- def report_verification_results (context , sigs ):
132- """
133- This is a helper function which reports the GPG signature verification
134- results. The 'context' argument is the gpg context object, and the 'sigs'
135- argument contains the results of the 'gpg.verify()' function.
131+ def verify_bmap_signature (args , bmap_obj , bmap_path ):
136132 """
133+ Verify GPG signature of the bmap file if it is present. The signature may
134+ be in a separate file (detached) or it may be inside the bmap file itself
135+ (clearsign signature).
137136
138- import gpg
139-
140- for sig in sigs :
141- if (sig .summary & gpg .constants .SIGSUM_VALID ) != 0 :
142- key = context .get_key (sig .fpr )
143- author = "%s <%s>" % (key .uids [0 ].name , key .uids [0 ].email )
144- log .info (
145- "successfully verified bmap file signature of %s "
146- "(fingerprint %s)" % (author , sig .fpr )
147- )
148- else :
149- error_out (
150- "signature verification failed (fingerprint %s): %s\n "
151- "Either fix the problem or use --no-sig-verify to "
152- "disable signature verification" ,
153- sig .fpr ,
154- sig .status [2 ].lower (),
155- )
156-
137+ If user specifies the --bmap-sig option, the signature is assumed to be
138+ detached and is taken from the user-specified file. Otherwise, this
139+ function verifies whether the bmap file has clearsign signature, and if
140+ not, it tries to automatically discover the detached signature by searching
141+ for a ".sig" or ".asc" file at the same path and with the same basename as
142+ the bmap file. This function then verifies the signature and reports the
143+ results.
157144
158- def verify_detached_bmap_signature (args , bmap_obj , bmap_path ):
159- """
160- This is a helper function for 'verify_bmap_signature()' which handles the
161- detached signature case.
145+ In case of the clearsign signature, the bmap file has "invalid" format,
146+ meaning that the proper bmap XML contents is in the GPG clearsign
147+ container. The XML contents has to be extracted from the container before
148+ further processing. And this is be done even if user specified the
149+ --no-sig-verify option. This function returns an open file object with the
150+ extracted XML bmap file contents in this case. Otherwise, this function
151+ returns None.
162152 """
163153
164- if args . no_sig_verify :
154+ if not bmap_obj :
165155 return None
166156
167- if args .bmap_sig :
157+ clearsign_marker = b"-----BEGIN PGP SIGNED MESSAGE-----"
158+ buf = bmap_obj .read (len (clearsign_marker ))
159+ bmap_obj .seek (0 )
160+
161+ if buf == clearsign_marker :
162+ log .info ("discovered inline signature" )
163+ detached_sig = None
164+ elif args .no_sig_verify :
165+ return None
166+ elif args .bmap_sig :
168167 try :
169- sig_obj = TransRead .TransRead (args .bmap_sig )
168+ detached_sig = TransRead .TransRead (args .bmap_sig )
170169 except TransRead .Error as err :
171170 error_out ("cannot open bmap signature file '%s':\n %s" , args .bmap_sig , err )
172- sig_path = args .bmap_sig
173171 else :
174172 # Check if there is a stand-alone signature file
175173 try :
176- sig_path = bmap_path + ".asc"
177- sig_obj = TransRead .TransRead (sig_path )
174+ detached_sig = TransRead .TransRead (bmap_path + ".asc" )
178175 except TransRead .Error :
179176 try :
180- sig_path = bmap_path + ".sig"
181- sig_obj = TransRead .TransRead (sig_path )
177+ detached_sig = TransRead .TransRead (bmap_path + ".sig" )
182178 except TransRead .Error :
183- # No signatures found
179+ # No detached signatures found
184180 return None
185181
186- log .info ("discovered signature file for bmap '%s'" % sig_path )
187-
188- # If the stand-alone signature file is not local, make a local copy
189- if sig_obj .is_url :
190- try :
191- tmp_obj = tempfile .NamedTemporaryFile ("wb+" )
192- except IOError as err :
193- error_out ("cannot create a temporary file for the signature:\n %s" , err )
194-
195- shutil .copyfileobj (sig_obj , tmp_obj )
196- tmp_obj .seek (0 )
197- sig_obj .close ()
198- sig_obj = tmp_obj
182+ log .info ("discovered signature file for bmap '%s'" % detached_sig .name )
199183
200184 try :
201185 import gpg
@@ -207,124 +191,70 @@ def verify_detached_bmap_signature(args, bmap_obj, bmap_path):
207191 )
208192
209193 try :
210- context = gpg .Context ()
211- signature = io .FileIO (sig_obj .name )
212- signed_data = io .FileIO (bmap_obj .name )
213- sigs = context .verify (signed_data , signature , None )[1 ].signatures
214- except gpg .errors .GPGMEError as err :
215- error_out (
216- "failure when trying to verify GPG signature: %s\n "
217- 'Make sure file "%s" has proper GPG format' ,
218- err .getstring (),
219- sig_path ,
220- )
221- except gpg .errors .BadSignatures as err :
222- error_out ("discovered a BAD GPG signature: %s\n " , sig_path )
223-
224- sig_obj .close ()
225-
226- if len (sigs ) == 0 :
227- log .warning (
228- 'the "%s" signature file does not actually contain '
229- "any valid signatures" % sig_path
230- )
231- else :
232- report_verification_results (context , sigs )
233-
234- return None
235-
194+ bmap_data = bmap_obj .read ()
195+ bmap_obj .seek (0 )
236196
237- def verify_clearsign_bmap_signature (args , bmap_obj ):
238- """
239- This is a helper function for 'verify_bmap_signature()' which handles the
240- clarsign signature case.
241- """
242-
243- if args .bmap_sig :
244- error_out (
245- "the bmap file has clearsign format and already contains "
246- "the signature, so --bmap-sig option should not be used"
247- )
248-
249- try :
250- import gpg
251- except ImportError :
252- error_out (
253- 'cannot verify the signature because the python "gpg"'
254- "module is not installed on your system\n Cannot extract "
255- "block map from the bmap file which has clearsign format, "
256- "please, install the module"
257- )
197+ if detached_sig :
198+ det_sig_data = detached_sig .read ()
199+ detached_sig .close ()
200+ else :
201+ det_sig_data = None
258202
259- try :
260203 context = gpg .Context ()
261- signature = io .FileIO (bmap_obj .name )
262- plaintext = io .BytesIO ()
263- sigs = context .verify (plaintext , signature , None )
204+ plaintext , sigs = context .verify (bmap_data , det_sig_data )
205+ sigs = sigs .signatures
264206 except gpg .errors .GPGMEError as err :
265207 error_out (
266208 "failure when trying to verify GPG signature: %s\n "
267209 "make sure the bmap file has proper GPG format" ,
268210 err [2 ].lower (),
269211 )
270212 except gpg .errors .BadSignatures as err :
271- error_out ("discovered a BAD GPG signature: %s\n " , sig_path )
213+ error_out (
214+ "discovered a BAD GPG signature: %s\n " ,
215+ detached_sig .name if detached_sig else bmap_obj .name
216+ )
272217
273218 if not args .no_sig_verify :
274219 if len (sigs ) == 0 :
275220 log .warning (
221+ 'the "%s" signature file does not actually contain '
222+ "any valid signatures" % detached_sig .name if detached_sig
223+ else
276224 "the bmap file clearsign signature does not actually "
277225 "contain any valid signatures"
278226 )
279227 else :
280- report_verification_results (context , sigs )
228+ for sig in sigs :
229+ if (sig .summary & gpg .constants .SIGSUM_VALID ) != 0 :
230+ key = context .get_key (sig .fpr )
231+ author = "%s <%s>" % (key .uids [0 ].name , key .uids [0 ].email )
232+ log .info (
233+ "successfully verified bmap file signature of %s "
234+ "(fingerprint %s)" % (author , sig .fpr )
235+ )
236+ else :
237+ error_out (
238+ "signature verification failed (fingerprint %s)\n "
239+ "Either fix the problem or use --no-sig-verify to "
240+ "disable signature verification" ,
241+ sig .fpr ,
242+ )
243+
244+ if detached_sig :
245+ # for detached signatures we are done
246+ return None
281247
282248 try :
283- tmp_obj = tempfile .TemporaryFile ("w+" )
249+ tmp_obj = tempfile .TemporaryFile ("w+b " )
284250 except IOError as err :
285251 error_out ("cannot create a temporary file for bmap:\n %s" , err )
286252
287- tmp_obj .write (plaintext . getvalue () )
253+ tmp_obj .write (plaintext )
288254 tmp_obj .seek (0 )
289255 return tmp_obj
290256
291257
292- def verify_bmap_signature (args , bmap_obj , bmap_path ):
293- """
294- Verify GPG signature of the bmap file if it is present. The signature may
295- be in a separate file (detached) or it may be inside the bmap file itself
296- (clearsign signature).
297-
298- If user specifies the --bmap-sig option, the signature is assumed to be
299- detached and is taken from the user-specified file. Otherwise, this
300- function verifies whether the bmap file has clearsign signature, and if
301- not, it tries to automatically discover the detached signature by searching
302- for a ".sig" or ".asc" file at the same path and with the same basename as
303- the bmap file. This function then verifies the signature and reports the
304- results.
305-
306- In case of the clearsign signature, the bmap file has "invalid" format,
307- meaning that the proper bmap XML contents is in the GPG clearsign
308- container. The XML contents has to be extracted from the container before
309- further processing. And this is be done even if user specified the
310- --no-sig-verify option. This function returns an open file object with the
311- extracted XML bmap file contents in this case. Otherwise, this function
312- returns None.
313- """
314-
315- if not bmap_obj :
316- return None
317-
318- clearsign_marker = "-----BEGIN PGP SIGNED MESSAGE-----"
319- buf = bmap_obj .read (len (clearsign_marker ))
320- bmap_obj .seek (0 )
321-
322- if buf == clearsign_marker :
323- return verify_clearsign_bmap_signature (args , bmap_obj )
324- else :
325- return verify_detached_bmap_signature (args , bmap_obj , bmap_path )
326-
327-
328258def find_and_open_bmap (args ):
329259 """
330260 This is a helper function for 'open_files()' which discovers and opens the
0 commit comments