8
8
9
9
import subprocess
10
10
from pathlib import Path
11
+ from typing import Optional
11
12
12
13
class PgpSigner :
13
14
"""Implementation of PGP signing
@@ -20,18 +21,18 @@ class PgpSigner:
20
21
You are required to supply key name and password for signing. Signing is done non-interactively without any
21
22
user prompts.
22
23
"""
23
- def __init__ (self , homedir : Path , key_name : str , key_pwd : str ):
24
+ def __init__ (self , * , key_name : str , key_pwd : str , homedir : Optional [ str | Path ] = None ):
24
25
"""Constructor for PgpSigner class
25
26
26
27
Args:
27
- homedir: GPG home directory. This is normally Path.home() / '.gpg' but can be set to anything for
28
- custom configuration
29
28
key_name: name or identifier of the key to use
30
29
key_pwd: password of the key
30
+ homedir: GPG home directory. If not specified the gpg defaults are used (including
31
+ honoring GNUPGHOME environment variable)
31
32
"""
32
33
self .__homedir = homedir
33
- self .__keyName = key_name
34
- self .__keyPwd = key_pwd
34
+ self .__key_name = key_name
35
+ self .__key_pwd = key_pwd
35
36
36
37
def sign_external (self , path : Path , sig_path : Path ):
37
38
"""Signs a given file producing text (aka "armored") signature in a separate file
@@ -40,14 +41,17 @@ def sign_external(self, path: Path, sig_path: Path):
40
41
path: file to sign
41
42
sig_path: path to write the signature to
42
43
"""
43
- subprocess .run (['gpg' , '--batch' , '--quiet' , '--pinentry-mode=loopback' ,
44
- '--homedir' , self .__homedir ,
45
- '--armor' , '--detach-sign' , '--sign' ,
46
- '--default-key' , self .__keyName ,
47
- '--passphrase' , self .__keyPwd ,
48
- '--digest-algo' , 'sha512' ,
49
- '-o' , sig_path , path
50
- ], check = True )
44
+ command = ['gpg' , '--batch' , '--quiet' , '--pinentry-mode=loopback' ]
45
+ if self .__homedir is not None :
46
+ command += ['--homedir' , self .__homedir ]
47
+ command += [
48
+ '--armor' , '--detach-sign' , '--sign' ,
49
+ '--default-key' , self .__key_name ,
50
+ '--passphrase' , self .__key_pwd ,
51
+ '--digest-algo' , 'sha512' ,
52
+ '-o' , sig_path , path
53
+ ]
54
+ subprocess .run (command , check = True )
51
55
52
56
def binary_sign_external (self , path : Path , sig_path : Path ):
53
57
"""Signs a given file producing binary signature in a separate file
@@ -56,14 +60,17 @@ def binary_sign_external(self, path: Path, sig_path: Path):
56
60
path: file to sign
57
61
sig_path: path to write the signature to
58
62
"""
59
- subprocess .run (['gpg' , '--batch' , '--quiet' , '--pinentry-mode=loopback' ,
60
- '--homedir' , self .__homedir ,
61
- '--detach-sign' , '--sign' ,
62
- '--default-key' , self .__keyName ,
63
- '--passphrase' , self .__keyPwd ,
64
- '--digest-algo' , 'sha512' ,
65
- '-o' , sig_path , path
66
- ], check = True )
63
+ command = ['gpg' , '--batch' , '--quiet' , '--pinentry-mode=loopback' ]
64
+ if self .__homedir is not None :
65
+ command += ['--homedir' , self .__homedir ]
66
+ command += [
67
+ '--detach-sign' , '--sign' ,
68
+ '--default-key' , self .__key_name ,
69
+ '--passphrase' , self .__key_pwd ,
70
+ '--digest-algo' , 'sha512' ,
71
+ '-o' , sig_path , path
72
+ ]
73
+ subprocess .run (command , check = True )
67
74
68
75
def sign_inline (self , path : Path , out_path : Path ):
69
76
"""Adds a signature to a given text file
@@ -72,23 +79,29 @@ def sign_inline(self, path: Path, out_path: Path):
72
79
path: file to sign
73
80
out_path: path to write the signed content to
74
81
"""
75
- subprocess .run (['gpg' , '--batch' , '--quiet' , '--pinentry-mode=loopback' ,
76
- '--homedir' , self .__homedir ,
77
- '--armor' , '--detach-sign' , '--sign' , '--clearsign' ,
78
- '--default-key' , self .__keyName ,
79
- '--passphrase' , self .__keyPwd ,
80
- '--digest-algo' , 'sha512' ,
81
- '-o' , out_path , path
82
- ], check = True )
82
+ command = ['gpg' , '--batch' , '--quiet' , '--pinentry-mode=loopback' ]
83
+ if self .__homedir is not None :
84
+ command += ['--homedir' , self .__homedir ]
85
+ command += [
86
+ '--armor' , '--detach-sign' , '--sign' , '--clearsign' ,
87
+ '--default-key' , self .__key_name ,
88
+ '--passphrase' , self .__key_pwd ,
89
+ '--digest-algo' , 'sha512' ,
90
+ '-o' , out_path , path
91
+ ]
92
+ subprocess .run (command , check = True )
83
93
84
94
def export_public_key (self , path : Path ):
85
95
"""Utility method to export the public key of the signing key into a file
86
96
Args:
87
97
path: path of the file to write the public key to
88
98
"""
89
- subprocess .run (['gpg' , '--batch' , '--quiet' ,
90
- '--homedir' , self .__homedir ,
91
- '--output' , path ,
92
- '--armor' , '--export' , self .__keyName
93
- ], check = True )
99
+ command = ['gpg' , '--batch' , '--quiet' ]
100
+ if self .__homedir is not None :
101
+ command += ['--homedir' , self .__homedir ]
102
+ command += [
103
+ '--output' , path ,
104
+ '--armor' , '--export' , self .__key_name
105
+ ]
106
+ subprocess .run (command , check = True )
94
107
0 commit comments