|
@@ -1,11 +1,19 @@
|
|
|
#!/usr/bin/env python3
|
|
|
|
|
|
+"""
|
|
|
+create a shadowed-private-key in sexp format
|
|
|
+for gnupg's private-keys-v1.d folder
|
|
|
+containing the public key of a
|
|
|
+X.509 certificate signing request or a public key
|
|
|
+"""
|
|
|
+
|
|
|
+import ctypes
|
|
|
+import math
|
|
|
+
|
|
|
import binascii
|
|
|
import cryptography.hazmat.backends
|
|
|
import cryptography.hazmat.primitives.serialization
|
|
|
import cryptography.x509
|
|
|
-import ctypes
|
|
|
-import math
|
|
|
|
|
|
DEFAULT_KEY_OUTPUT_PATH_PATTERN = '{keygrip_hex}.key'
|
|
|
DEFAULT_SMARTCARD_APP_ID_HEX = 'D2760001240102010001234567890000'
|
|
@@ -43,8 +51,8 @@ def keygrip_from_key_sexp(key_sexp_data):
|
|
|
|
|
|
def load_public_key(input_path):
|
|
|
backend = cryptography.hazmat.backends.default_backend()
|
|
|
- with open(input_path, 'rb') as f:
|
|
|
- input_data = f.read()
|
|
|
+ with open(input_path, 'rb') as input_file:
|
|
|
+ input_data = input_file.read()
|
|
|
try:
|
|
|
return cryptography.hazmat.primitives.serialization.load_pem_public_key(
|
|
|
input_data,
|
|
@@ -56,7 +64,8 @@ def load_public_key(input_path):
|
|
|
return req.public_key()
|
|
|
|
|
|
|
|
|
-def create_gpg_key(input_path, gpg_key_output_path_pattern, smartcard_app_id_hex, keygrip_hex_output_path):
|
|
|
+def create_gpg_key(input_path, gpg_key_output_path_pattern,
|
|
|
+ smartcard_app_id_hex, keygrip_hex_output_path):
|
|
|
pubnums = load_public_key(input_path).public_numbers()
|
|
|
key_data = ['shadowed-private-key', [
|
|
|
'rsa',
|
|
@@ -68,17 +77,19 @@ def create_gpg_key(input_path, gpg_key_output_path_pattern, smartcard_app_id_hex
|
|
|
keygrip = keygrip_from_key_sexp(key_sexp_data)
|
|
|
keygrip_hex = binascii.hexlify(keygrip).upper().decode()
|
|
|
if keygrip_hex_output_path:
|
|
|
- with open(keygrip_hex_output_path, 'w') as f:
|
|
|
- f.write(keygrip_hex + '\n')
|
|
|
- with open(gpg_key_output_path_pattern.format(keygrip_hex=keygrip_hex), 'wb') as f:
|
|
|
- f.write(key_sexp_data)
|
|
|
+ with open(keygrip_hex_output_path, 'w') as keygrip_file:
|
|
|
+ keygrip_file.write(keygrip_hex + '\n')
|
|
|
+ with open(gpg_key_output_path_pattern.format(keygrip_hex=keygrip_hex), 'wb') as sexp_file:
|
|
|
+ sexp_file.write(key_sexp_data)
|
|
|
|
|
|
|
|
|
def _init_argparser():
|
|
|
import argparse
|
|
|
argparser = argparse.ArgumentParser(
|
|
|
- description='create a shadowed-private-key in sexp format for gnupg\'s private-keys-v1.d folder'
|
|
|
- + ' containing the public key of a PEM-encoded X.509 certificate signing request (CSR)',
|
|
|
+ description='create a shadowed-private-key in sexp format'
|
|
|
+ ' for gnupg\'s private-keys-v1.d folder'
|
|
|
+ ' containing the public key of a'
|
|
|
+ ' PEM-encoded X.509 certificate signing request (CSR)',
|
|
|
)
|
|
|
argparser.add_argument(
|
|
|
'input_path',
|
|
@@ -90,8 +101,8 @@ def _init_argparser():
|
|
|
metavar='path-pattern',
|
|
|
default=DEFAULT_KEY_OUTPUT_PATH_PATTERN,
|
|
|
help='path to sexp-encoded shadowed-private-key to be created.'
|
|
|
- + ' if specified, {keygrip_hex} will be substituted.'
|
|
|
- + ' (default: "%(default)s")',
|
|
|
+ ' if specified, {keygrip_hex} will be substituted.'
|
|
|
+ ' (default: "%(default)s")',
|
|
|
)
|
|
|
argparser.add_argument(
|
|
|
'--smartcard-app-id',
|
|
@@ -105,7 +116,7 @@ def _init_argparser():
|
|
|
metavar='path',
|
|
|
default=None,
|
|
|
help='path where to save keygrip in hex format'
|
|
|
- + ' (default: no output)',
|
|
|
+ ' (default: no output)',
|
|
|
)
|
|
|
return argparser
|
|
|
|
|
@@ -116,6 +127,7 @@ def main(argv):
|
|
|
create_gpg_key(**vars(args))
|
|
|
return 0
|
|
|
|
|
|
+
|
|
|
if __name__ == '__main__':
|
|
|
import sys
|
|
|
sys.exit(main(sys.argv))
|