Skip to content

Commit 730aa81

Browse files
committed
implement signing feature
1 parent 3a1f652 commit 730aa81

File tree

1 file changed

+45
-3
lines changed

1 file changed

+45
-3
lines changed

ova-compose/ova-compose.py

Lines changed: 45 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@
2525
import tempfile
2626
import shutil
2727

28-
2928
APP_NAME = "ova-compose"
3029

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

12021201

1202+
def sign_manifest(self, keyfile, ovf_file=None, mf_file=None, sign_alg="sha512"):
1203+
if ovf_file == None:
1204+
ovf_file = f"{self.name}.ovf"
1205+
if mf_file == None:
1206+
mf_file = f"{self.name}.mf"
1207+
cert_file = os.path.splitext(ovf_file)[0] + ".cert"
1208+
1209+
with open(cert_file, "wt") as f:
1210+
signature = subprocess.check_output(["openssl", "dgst", f"-{sign_alg}", "-sign", keyfile, "-out", "-", mf_file])
1211+
f.write(f"{sign_alg.upper()}({mf_file})= {signature.hex()}\n")
1212+
1213+
with open(keyfile, "rt") as fin:
1214+
do_copy = False
1215+
for line in fin:
1216+
if (line.startswith("-----BEGIN CERTIFICATE")):
1217+
do_copy = True
1218+
if do_copy:
1219+
f.write(line)
1220+
if (line.startswith("-----END CERTIFICATE")):
1221+
break
1222+
assert do_copy, f"no certificate found in {keyfile}"
1223+
1224+
12031225
def usage():
12041226
print(f"Usage: {sys.argv[0]} -i|--input-file <input file> -o|--output-file <output file> [--format ova|ovf|dir] [-q] [-h]")
12051227
print("")
@@ -1228,7 +1250,7 @@ def yaml_param(loader, node):
12281250
default = None
12291251
key = node.value
12301252

1231-
assert type(key) is str, f"param name must be a string"
1253+
assert type(key) is str, f"param name {key} must be a string"
12321254

12331255
if '=' in key:
12341256
key, default = [t.strip() for t in key.split('=', maxsplit=1)]
@@ -1249,10 +1271,14 @@ def main():
12491271
do_manifest = False
12501272
params = {}
12511273
checksum_type = "sha256"
1274+
sign_keyfile = None
1275+
sign_alg = None
12521276
tar_format = "gnu"
12531277

12541278
try:
1255-
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='])
1279+
opts, args = getopt.getopt(sys.argv[1:],
1280+
'f:hi:mo:q',
1281+
longopts=['format=', 'input-file=', 'manifest', 'output-file=', 'param=', 'checksum-type=', 'sign=', 'sign-alg=', 'tar-format=', 'vmdk-convert='])
12561282
except:
12571283
print ("invalid option")
12581284
sys.exit(2)
@@ -1278,6 +1304,10 @@ def main():
12781304
VMDK_CONVERT = a
12791305
elif o in ['-q']:
12801306
do_quiet = True
1307+
elif o in ['-s', '--sign']:
1308+
sign_keyfile = a
1309+
elif o in ['--sign-alg']:
1310+
sign_alg = a
12811311
elif o in ['-h']:
12821312
usage()
12831313
sys.exit(0)
@@ -1288,6 +1318,12 @@ def main():
12881318
assert output_file != None, "no output file/directory specified"
12891319

12901320
assert checksum_type in ["sha1", "sha512", "sha256"], f"checksum-type '{checksum_type}' is invalid"
1321+
if sign_alg is None:
1322+
sign_alg = checksum_type
1323+
assert sign_alg in ["sha1", "sha512", "sha256"], f"checksum-type '{sign_alg}' is invalid"
1324+
1325+
if sign_keyfile is not None:
1326+
sign_keyfile = os.path.abspath(sign_keyfile)
12911327

12921328
if config_file != None:
12931329
f = open(config_file, 'r')
@@ -1327,6 +1363,8 @@ def main():
13271363
ovf.write_xml(ovf_file=ovf_file)
13281364
if do_manifest:
13291365
ovf.write_manifest(ovf_file=ovf_file, mf_file=mf_file, hash_type=checksum_type)
1366+
if sign_keyfile is not None:
1367+
ovf.sign_manifest(sign_keyfile, ovf_file=ovf_file, mf_file=mf_file, sign_alg=sign_alg)
13301368
elif output_format == "ova" or output_format == "dir":
13311369
pwd = os.getcwd()
13321370
tmpdir = tempfile.mkdtemp(prefix=f"{basename}-", dir=pwd)
@@ -1342,6 +1380,10 @@ def main():
13421380
all_files.append(dst)
13431381

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

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

0 commit comments

Comments
 (0)