25
25
import tempfile
26
26
import shutil
27
27
28
-
29
28
APP_NAME = "ova-compose"
30
29
31
30
VMDK_CONVERT = "vmdk-convert"
@@ -1200,6 +1199,29 @@ def write_manifest(self, ovf_file=None, mf_file=None, hash_type="sha512"):
1200
1199
f .write (f"{ hash_type .upper ()} ({ fname } )= { hash } \n " )
1201
1200
1202
1201
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
+
1203
1225
def usage ():
1204
1226
print (f"Usage: { sys .argv [0 ]} -i|--input-file <input file> -o|--output-file <output file> [--format ova|ovf|dir] [-q] [-h]" )
1205
1227
print ("" )
@@ -1228,7 +1250,7 @@ def yaml_param(loader, node):
1228
1250
default = None
1229
1251
key = node .value
1230
1252
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"
1232
1254
1233
1255
if '=' in key :
1234
1256
key , default = [t .strip () for t in key .split ('=' , maxsplit = 1 )]
@@ -1249,10 +1271,14 @@ def main():
1249
1271
do_manifest = False
1250
1272
params = {}
1251
1273
checksum_type = "sha256"
1274
+ sign_keyfile = None
1275
+ sign_alg = None
1252
1276
tar_format = "gnu"
1253
1277
1254
1278
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=' ])
1256
1282
except :
1257
1283
print ("invalid option" )
1258
1284
sys .exit (2 )
@@ -1278,6 +1304,10 @@ def main():
1278
1304
VMDK_CONVERT = a
1279
1305
elif o in ['-q' ]:
1280
1306
do_quiet = True
1307
+ elif o in ['-s' , '--sign' ]:
1308
+ sign_keyfile = a
1309
+ elif o in ['--sign-alg' ]:
1310
+ sign_alg = a
1281
1311
elif o in ['-h' ]:
1282
1312
usage ()
1283
1313
sys .exit (0 )
@@ -1288,6 +1318,12 @@ def main():
1288
1318
assert output_file != None , "no output file/directory specified"
1289
1319
1290
1320
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 )
1291
1327
1292
1328
if config_file != None :
1293
1329
f = open (config_file , 'r' )
@@ -1327,6 +1363,8 @@ def main():
1327
1363
ovf .write_xml (ovf_file = ovf_file )
1328
1364
if do_manifest :
1329
1365
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 )
1330
1368
elif output_format == "ova" or output_format == "dir" :
1331
1369
pwd = os .getcwd ()
1332
1370
tmpdir = tempfile .mkdtemp (prefix = f"{ basename } -" , dir = pwd )
@@ -1342,6 +1380,10 @@ def main():
1342
1380
all_files .append (dst )
1343
1381
1344
1382
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 )
1345
1387
1346
1388
if output_format == "ova" :
1347
1389
ret = subprocess .check_call (["tar" , f"--format={ tar_format } " , "-h" ,
0 commit comments