Skip to content

Commit

Permalink
implement signing feature
Browse files Browse the repository at this point in the history
  • Loading branch information
oliverkurth committed Jul 30, 2024
1 parent 3a1f652 commit 730aa81
Showing 1 changed file with 45 additions and 3 deletions.
48 changes: 45 additions & 3 deletions ova-compose/ova-compose.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@
import tempfile
import shutil


APP_NAME = "ova-compose"

VMDK_CONVERT = "vmdk-convert"
Expand Down Expand Up @@ -1200,6 +1199,29 @@ def write_manifest(self, ovf_file=None, mf_file=None, hash_type="sha512"):
f.write(f"{hash_type.upper()}({fname})= {hash}\n")


def sign_manifest(self, keyfile, ovf_file=None, mf_file=None, sign_alg="sha512"):
if ovf_file == None:
ovf_file = f"{self.name}.ovf"
if mf_file == None:
mf_file = f"{self.name}.mf"
cert_file = os.path.splitext(ovf_file)[0] + ".cert"

with open(cert_file, "wt") as f:
signature = subprocess.check_output(["openssl", "dgst", f"-{sign_alg}", "-sign", keyfile, "-out", "-", mf_file])
f.write(f"{sign_alg.upper()}({mf_file})= {signature.hex()}\n")

with open(keyfile, "rt") as fin:
do_copy = False
for line in fin:
if (line.startswith("-----BEGIN CERTIFICATE")):
do_copy = True
if do_copy:
f.write(line)
if (line.startswith("-----END CERTIFICATE")):
break
assert do_copy, f"no certificate found in {keyfile}"


def usage():
print(f"Usage: {sys.argv[0]} -i|--input-file <input file> -o|--output-file <output file> [--format ova|ovf|dir] [-q] [-h]")
print("")
Expand Down Expand Up @@ -1228,7 +1250,7 @@ def yaml_param(loader, node):
default = None
key = node.value

assert type(key) is str, f"param name must be a string"
assert type(key) is str, f"param name {key} must be a string"

if '=' in key:
key, default = [t.strip() for t in key.split('=', maxsplit=1)]
Expand All @@ -1249,10 +1271,14 @@ def main():
do_manifest = False
params = {}
checksum_type = "sha256"
sign_keyfile = None
sign_alg = None
tar_format = "gnu"

try:
opts, args = getopt.getopt(sys.argv[1:], 'f:hi:mo:q', longopts=['format=', 'input-file=', 'manifest', 'output-file=', 'param=', 'checksum-type=', 'tar-format=', 'vmdk-convert='])
opts, args = getopt.getopt(sys.argv[1:],
'f:hi:mo:q',
longopts=['format=', 'input-file=', 'manifest', 'output-file=', 'param=', 'checksum-type=', 'sign=', 'sign-alg=', 'tar-format=', 'vmdk-convert='])
except:
print ("invalid option")
sys.exit(2)
Expand All @@ -1278,6 +1304,10 @@ def main():
VMDK_CONVERT = a
elif o in ['-q']:
do_quiet = True
elif o in ['-s', '--sign']:
sign_keyfile = a
elif o in ['--sign-alg']:
sign_alg = a
elif o in ['-h']:
usage()
sys.exit(0)
Expand All @@ -1288,6 +1318,12 @@ def main():
assert output_file != None, "no output file/directory specified"

assert checksum_type in ["sha1", "sha512", "sha256"], f"checksum-type '{checksum_type}' is invalid"
if sign_alg is None:
sign_alg = checksum_type
assert sign_alg in ["sha1", "sha512", "sha256"], f"checksum-type '{sign_alg}' is invalid"

if sign_keyfile is not None:
sign_keyfile = os.path.abspath(sign_keyfile)

if config_file != None:
f = open(config_file, 'r')
Expand Down Expand Up @@ -1327,6 +1363,8 @@ def main():
ovf.write_xml(ovf_file=ovf_file)
if do_manifest:
ovf.write_manifest(ovf_file=ovf_file, mf_file=mf_file, hash_type=checksum_type)
if sign_keyfile is not None:
ovf.sign_manifest(sign_keyfile, ovf_file=ovf_file, mf_file=mf_file, sign_alg=sign_alg)
elif output_format == "ova" or output_format == "dir":
pwd = os.getcwd()
tmpdir = tempfile.mkdtemp(prefix=f"{basename}-", dir=pwd)
Expand All @@ -1342,6 +1380,10 @@ def main():
all_files.append(dst)

ovf.write_manifest(ovf_file=ovf_file, mf_file=mf_file, hash_type=checksum_type)
if sign_keyfile is not None:
ovf.sign_manifest(sign_keyfile, ovf_file=ovf_file, mf_file=mf_file, sign_alg=sign_alg)
cert_file = os.path.splitext(ovf_file)[0] + ".cert"
all_files.append(cert_file)

if output_format == "ova":
ret = subprocess.check_call(["tar", f"--format={tar_format}", "-h",
Expand Down

0 comments on commit 730aa81

Please sign in to comment.