@@ -138,7 +138,12 @@ class Signature(NamedTuple):
138138 uid : str
139139
140140
141- def verify_bmap_signature_gpgme (bmap_obj , detached_sig ):
141+ def verify_bmap_signature_gpgme (bmap_obj , detached_sig , keyring ):
142+ if keyring :
143+ error_out (
144+ "Python gpgme binding is not able to verify "
145+ "signatures against a custom keyring."
146+ )
142147 try :
143148 import gpg
144149 except ImportError :
@@ -186,8 +191,17 @@ def fpr2uid(fpr):
186191 ]
187192
188193
189- def verify_bmap_signature_gpgbin (bmap_obj , detached_sig , gpgargv ):
194+ def verify_bmap_signature_gpgbin (bmap_obj , detached_sig , gpgargv , keyring ):
190195 with tempfile .TemporaryDirectory (suffix = ".bmaptool.gnupg" ) as td :
196+ if keyring :
197+ if gpgargv [0 ] == "gpg" :
198+ gpgargv .extend (
199+ [
200+ f"--homedir={ td } " ,
201+ "--no-default-keyring" ,
202+ ]
203+ )
204+ gpgargv .append (f"--keyring={ keyring } " )
191205 if detached_sig :
192206 with open (f"{ td } /sig" , "wb" ) as f :
193207 shutil .copyfileobj (detached_sig , f )
@@ -236,13 +250,13 @@ def verify_bmap_signature_gpgbin(bmap_obj, detached_sig, gpgargv):
236250 ]
237251
238252
239- def verify_bmap_signature_gpgv (bmap_obj , detached_sig ):
253+ def verify_bmap_signature_gpgv (bmap_obj , detached_sig , keyring ):
240254 return verify_bmap_signature_gpgbin (
241- bmap_obj , detached_sig , ["gpgv" , "--output=-" , "--status-fd=2" ]
255+ bmap_obj , detached_sig , ["gpgv" , "--output=-" , "--status-fd=2" ], keyring
242256 )
243257
244258
245- def verify_bmap_signature_gpg (bmap_obj , detached_sig ):
259+ def verify_bmap_signature_gpg (bmap_obj , detached_sig , keyring ):
246260 return verify_bmap_signature_gpgbin (
247261 bmap_obj ,
248262 detached_sig ,
@@ -256,6 +270,7 @@ def verify_bmap_signature_gpg(bmap_obj, detached_sig):
256270 "-" ,
257271 "--status-fd=2" ,
258272 ],
273+ keyring ,
259274 )
260275
261276
@@ -308,6 +323,10 @@ def verify_bmap_signature(args, bmap_obj, bmap_path):
308323 detached_sig = TransRead .TransRead (bmap_path + ".sig" )
309324 except TransRead .Error :
310325 # No detached signatures found
326+ if args .fingerprint :
327+ error_out ("no signature found but --fingerprint given" )
328+ if args .keyring :
329+ error_out ("no signature found but --keyring given" )
311330 return None
312331
313332 log .info ("discovered signature file for bmap '%s'" % detached_sig .name )
@@ -318,12 +337,16 @@ def verify_bmap_signature(args, bmap_obj, bmap_path):
318337 "gpgv" : verify_bmap_signature_gpgv ,
319338 }
320339 have_method = set ()
321- try :
322- import gpg
323340
324- have_method .add ("gpgme" )
325- except ImportError :
326- pass
341+ if not args .keyring :
342+ # The python gpgme binding is not able to verify against a custom
343+ # keyring. Only try this method if we have no keyring.
344+ try :
345+ import gpg
346+
347+ have_method .add ("gpgme" )
348+ except ImportError :
349+ pass
327350 if shutil .which ("gpg" ) is not None :
328351 have_method .add ("gpg" )
329352 if shutil .which ("gpgv" ) is not None :
@@ -333,10 +356,10 @@ def verify_bmap_signature(args, bmap_obj, bmap_path):
333356 error_out ("Cannot verify GPG signature without GPG" )
334357
335358 for method in ["gpgme" , "gpgv" , "gpg" ]:
336- log .info (f"Trying to verify signature using { method } " )
337359 if method not in have_method :
338360 continue
339- plaintext , sigs = methods [method ](bmap_obj , detached_sig )
361+ log .info (f"Trying to verify signature using { method } " )
362+ plaintext , sigs = methods [method ](bmap_obj , detached_sig , args .keyring )
340363 break
341364 bmap_obj .seek (0 )
342365
@@ -350,6 +373,12 @@ def verify_bmap_signature(args, bmap_obj, bmap_path):
350373 "contain any valid signatures"
351374 )
352375 else :
376+ if args .fingerprint and args .fingerprint not in [sig .fpr for sig in sigs ]:
377+ error_out (
378+ f"requested fingerprint { args .fingerprint } "
379+ "did not sign the bmap file. Only have these sigs: "
380+ + ("" .join ([f"\n * { sig .fpr } " for sig in sigs ]))
381+ )
353382 for sig in sigs :
354383 if sig .valid :
355384 log .info (
@@ -554,6 +583,12 @@ def copy_command(args):
554583 if args .bmap_sig and args .no_sig_verify :
555584 error_out ("--bmap-sig and --no-sig-verify cannot be used together" )
556585
586+ if args .no_sig_verify and args .keyring :
587+ error_out ("--no-sig-verify and --keyring cannot be used together" )
588+
589+ if args .no_sig_verify and args .fingerprint :
590+ error_out ("--no-sig-verify and --fingerprint cannot be used together" )
591+
557592 image_obj , dest_obj , bmap_obj , bmap_path , image_size , dest_is_blkdev = open_files (
558593 args
559594 )
@@ -779,6 +814,14 @@ def parse_arguments():
779814 text = "do not verify bmap file GPG signature"
780815 parser_copy .add_argument ("--no-sig-verify" , action = "store_true" , help = text )
781816
817+ # The --keyring option
818+ text = "the GPG keyring to verify the GPG signature on the bmap file"
819+ parser_copy .add_argument ("--keyring" , help = text )
820+
821+ # The --fingerprint option
822+ text = "the GPG fingerprint that is expected to have signed the bmap file"
823+ parser_copy .add_argument ("--fingerprint" , help = text )
824+
782825 # The --no-verify option
783826 text = "do not verify the data checksum while writing"
784827 parser_copy .add_argument ("--no-verify" , action = "store_true" , help = text )
0 commit comments