Skip to content
Snippets Groups Projects
Commit 8c5d1e7b authored by Tobias Dussa's avatar Tobias Dussa
Browse files

Added first support for GPGSM.

parent 5e6db1be
No related branches found
No related tags found
No related merge requests found
...@@ -114,6 +114,7 @@ if args.sign: ...@@ -114,6 +114,7 @@ if args.sign:
match args.sign: match args.sign:
case 'gpg' | 'gpgsm': case 'gpg' | 'gpgsm':
# Import dependencies for GPG-based mail signing if necessary # Import dependencies for GPG-based mail signing if necessary
from base64 import b64encode
from email.mime.multipart import MIMEMultipart from email.mime.multipart import MIMEMultipart
import gnupg import gnupg
case 'openssl': case 'openssl':
...@@ -210,6 +211,73 @@ data = dict() ...@@ -210,6 +211,73 @@ data = dict()
template = jinja2.Template(open(args.template.format_map(SafeDict(basedir=args.basedir, campaign=args.campaign, infix=args.infix, webserver=args.webserver, salt=args.salt))).read()) template = jinja2.Template(open(args.template.format_map(SafeDict(basedir=args.basedir, campaign=args.campaign, infix=args.infix, webserver=args.webserver, salt=args.salt))).read())
# Set up GPG context if necessary
gpg = None
if args.sign == 'gpg':
gpg = gnupg.GPG(**args.signinitarg)
elif args.sign == 'gpgsm':
class GPGSM(gnupg.GPG):
def __init__(self,
gpgbinary='gpgsm',
gnupghome=None,
verbose=False,
use_agent=False,
keyring=None,
options=None,
secret_keyring=None,
env=None):
self.gpgbinary = gpgbinary
self.gnupghome = gnupghome
self.env = env
if gnupghome and not os.path.isdir(gnupghome):
raise ValueError('gnupghome should be a directory (it isn\'t): %s' % gnupghome)
if keyring:
if isinstance(keyring, string_types):
keyring = [keyring]
self.keyring = keyring
if secret_keyring: # pragma: no cover
if isinstance(secret_keyring, string_types):
secret_keyring = [secret_keyring]
self.secret_keyring = secret_keyring
self.verbose = verbose
self.use_agent = use_agent
if isinstance(options, str): # pragma: no cover
options = [options]
self.options = options
self.on_data = None # or a callable - will be called with data chunks
self.encoding = 'latin-1'
if gnupghome and not os.path.isdir(self.gnupghome): # pragma: no cover
os.makedirs(self.gnupghome, 0o700)
self.check_fingerprint_collisions = False
def make_args(self, args, passphrase):
cmd = ['gpgsm', '--status-fd', '2', '--no-tty', '--no-verbose']
if 'DEBUG_IPC' in os.environ: # pragma: no cover
cmd.extend(['--debug', 'ipc'])
if passphrase and hasattr(self, 'version'):
if self.version >= (2, 1):
cmd[1:1] = ['--pinentry-mode', 'loopback']
cmd.extend(['--batch', '--with-colons'])
if self.gnupghome:
cmd.extend(['--homedir', no_quote(self.gnupghome)])
if self.keyring:
cmd.append('--no-default-keyring')
for fn in self.keyring:
cmd.extend(['--keyring', no_quote(fn)])
if self.secret_keyring: # pragma: no cover
for fn in self.secret_keyring:
cmd.extend(['--secret-keyring', no_quote(fn)])
if passphrase:
cmd.extend(['--passphrase-fd', '0'])
if self.use_agent: # pragma: no cover
cmd.append('--use-agent')
if self.options:
cmd.extend(self.options)
cmd.extend(args)
return cmd
gpg = GPGSM(gpgbinary='gpgsm', **args.signinitarg)
args.signarg['binary'] = True
# Convert int to hex # Convert int to hex
def toHex(serial): def toHex(serial):
tmpString = hex(serial)[2:].upper() tmpString = hex(serial)[2:].upper()
...@@ -220,12 +288,6 @@ def toHex(serial): ...@@ -220,12 +288,6 @@ def toHex(serial):
# Sign message with GPG/GPGSM # Sign message with GPG/GPGSM
def signMailGPG(message): def signMailGPG(message):
# Set up GPG context
if args.sign == 'gpg':
gpg = gnupg.GPG(**args.signinitarg)
else:
gpg = gnupg.GPG(gpgbinary='gpgsm', **args.signinitarg)
# Sign mail # Sign mail
try: try:
signature = str(gpg.sign(message.as_string().replace('\n', '\r\n'), detach=True, **args.signarg)) signature = str(gpg.sign(message.as_string().replace('\n', '\r\n'), detach=True, **args.signarg))
...@@ -244,6 +306,8 @@ def signMailGPG(message): ...@@ -244,6 +306,8 @@ def signMailGPG(message):
else: else:
signatureMessage['Content-Type'] = 'application/pkcs7-signature; name="smime.p7s"' signatureMessage['Content-Type'] = 'application/pkcs7-signature; name="smime.p7s"'
signatureMessage['Content-Description'] = 'S/MIME digital signature' signatureMessage['Content-Description'] = 'S/MIME digital signature'
signatureMessage['Content-Transfer-Encoding'] = 'base64'
signature = b64encode(signature.encode('latin1'))
signatureMessage.set_payload(signature) signatureMessage.set_payload(signature)
# Assemble new message # Assemble new message
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment