mirror of
https://gitlab.com/fdroid/fdroidserver.git
synced 2024-10-03 17:50:11 +02:00
Merge branch 'smartcard_hsm' into 'master'
switch publish to common.sign_apk and support smartcard HSMs for app signing See merge request fdroid/fdroidserver!782
This commit is contained in:
commit
6258a939e6
@ -3045,13 +3045,16 @@ def sign_apk(unsigned_path, signed_path, keyalias):
|
||||
else:
|
||||
signature_algorithm = ['-sigalg', 'SHA256withRSA', '-digestalg', 'SHA-256']
|
||||
|
||||
p = FDroidPopen([config['jarsigner'], '-keystore', config['keystore'],
|
||||
'-storepass:env', 'FDROID_KEY_STORE_PASS',
|
||||
'-keypass:env', 'FDROID_KEY_PASS']
|
||||
+ signature_algorithm + [unsigned_path, keyalias],
|
||||
cmd = [config['jarsigner'], '-keystore', config['keystore'],
|
||||
'-storepass:env', 'FDROID_KEY_STORE_PASS']
|
||||
if config['keystore'] == 'NONE':
|
||||
cmd += config['smartcardoptions']
|
||||
else:
|
||||
cmd += '-keypass:env', 'FDROID_KEY_PASS'
|
||||
p = FDroidPopen(cmd + signature_algorithm + [unsigned_path, keyalias],
|
||||
envs={
|
||||
'FDROID_KEY_STORE_PASS': config['keystorepass'],
|
||||
'FDROID_KEY_PASS': config['keypass'], })
|
||||
'FDROID_KEY_PASS': config.get('keypass', "")})
|
||||
if p.returncode != 0:
|
||||
raise BuildException(_("Failed to sign application"), p.output)
|
||||
|
||||
@ -3064,7 +3067,7 @@ def verify_apks(signed_apk, unsigned_apk, tmp_dir):
|
||||
|
||||
One of the inputs is signed, the other is unsigned. The signature metadata
|
||||
is transferred from the signed to the unsigned apk, and then jarsigner is
|
||||
used to verify that the signature from the signed apk is also varlid for
|
||||
used to verify that the signature from the signed apk is also valid for
|
||||
the unsigned one. If the APK given as unsigned actually does have a
|
||||
signature, it will be stripped out and ignored.
|
||||
|
||||
@ -3342,26 +3345,33 @@ def genkeystore(localconfig):
|
||||
|
||||
env_vars = {'LC_ALL': 'C.UTF-8',
|
||||
'FDROID_KEY_STORE_PASS': localconfig['keystorepass'],
|
||||
'FDROID_KEY_PASS': localconfig['keypass']}
|
||||
p = FDroidPopen([config['keytool'], '-genkey',
|
||||
'-keystore', localconfig['keystore'],
|
||||
'-alias', localconfig['repo_keyalias'],
|
||||
'-keyalg', 'RSA', '-keysize', '4096',
|
||||
'-sigalg', 'SHA256withRSA',
|
||||
'-validity', '10000',
|
||||
'-storepass:env', 'FDROID_KEY_STORE_PASS',
|
||||
'-keypass:env', 'FDROID_KEY_PASS',
|
||||
'-dname', localconfig['keydname'],
|
||||
'-J-Duser.language=en'], envs=env_vars)
|
||||
'FDROID_KEY_PASS': localconfig.get('keypass', "")}
|
||||
|
||||
cmd = [config['keytool'], '-genkey',
|
||||
'-keystore', localconfig['keystore'],
|
||||
'-alias', localconfig['repo_keyalias'],
|
||||
'-keyalg', 'RSA', '-keysize', '4096',
|
||||
'-sigalg', 'SHA256withRSA',
|
||||
'-validity', '10000',
|
||||
'-storepass:env', 'FDROID_KEY_STORE_PASS',
|
||||
'-dname', localconfig['keydname'],
|
||||
'-J-Duser.language=en']
|
||||
if localconfig['keystore'] == "NONE":
|
||||
cmd += localconfig['smartcardoptions']
|
||||
else:
|
||||
cmd += '-keypass:env', 'FDROID_KEY_PASS'
|
||||
p = FDroidPopen(cmd, envs=env_vars)
|
||||
if p.returncode != 0:
|
||||
raise BuildException("Failed to generate key", p.output)
|
||||
os.chmod(localconfig['keystore'], 0o0600)
|
||||
if localconfig['keystore'] != "NONE":
|
||||
os.chmod(localconfig['keystore'], 0o0600)
|
||||
if not options.quiet:
|
||||
# now show the lovely key that was just generated
|
||||
p = FDroidPopen([config['keytool'], '-list', '-v',
|
||||
'-keystore', localconfig['keystore'],
|
||||
'-alias', localconfig['repo_keyalias'],
|
||||
'-storepass:env', 'FDROID_KEY_STORE_PASS', '-J-Duser.language=en'], envs=env_vars)
|
||||
'-storepass:env', 'FDROID_KEY_STORE_PASS', '-J-Duser.language=en']
|
||||
+ config['smartcardoptions'], envs=env_vars)
|
||||
logging.info(p.output.strip() + '\n\n')
|
||||
# get the public key
|
||||
p = FDroidPopenBytes([config['keytool'], '-exportcert',
|
||||
|
@ -215,6 +215,9 @@ def main():
|
||||
f.write('name = OpenSC\nlibrary = ')
|
||||
f.write(opensc_so)
|
||||
f.write('\n')
|
||||
logging.info("Repo setup using a smartcard HSM. Please edit keystorepass and repo_keyalias in config.py.")
|
||||
logging.info("If you want to generate a new repo signing key in the HSM you can do that with 'fdroid update "
|
||||
"--create-key'.")
|
||||
elif os.path.exists(keystore):
|
||||
to_set = ['keystorepass', 'keypass', 'repo_keyalias', 'keydname']
|
||||
if repo_keyalias:
|
||||
|
@ -77,12 +77,13 @@ def read_fingerprints_from_keystore():
|
||||
are managed by F-Droid, grouped by appid.
|
||||
"""
|
||||
env_vars = {'LC_ALL': 'C.UTF-8',
|
||||
'FDROID_KEY_STORE_PASS': config['keystorepass'],
|
||||
'FDROID_KEY_PASS': config['keypass']}
|
||||
p = FDroidPopen([config['keytool'], '-list',
|
||||
'-v', '-keystore', config['keystore'],
|
||||
'-storepass:env', 'FDROID_KEY_STORE_PASS'],
|
||||
envs=env_vars, output=False)
|
||||
'FDROID_KEY_STORE_PASS': config['keystorepass']}
|
||||
cmd = [config['keytool'], '-list',
|
||||
'-v', '-keystore', config['keystore'],
|
||||
'-storepass:env', 'FDROID_KEY_STORE_PASS']
|
||||
if config['keystore'] == 'NONE':
|
||||
cmd += config['smartcardoptions']
|
||||
p = FDroidPopen(cmd, envs=env_vars, output=False)
|
||||
if p.returncode != 0:
|
||||
raise FDroidException('could not read keystore {}'.format(config['keystore']))
|
||||
|
||||
@ -115,7 +116,7 @@ def sign_sig_key_fingerprint_list(jar_file):
|
||||
else: # smardcards never use -keypass
|
||||
cmd += '-keypass:env', 'FDROID_KEY_PASS'
|
||||
env_vars = {'FDROID_KEY_STORE_PASS': config['keystorepass'],
|
||||
'FDROID_KEY_PASS': config['keypass']}
|
||||
'FDROID_KEY_PASS': config.get('keypass', "")}
|
||||
p = common.FDroidPopen(cmd, envs=env_vars)
|
||||
if p.returncode != 0:
|
||||
raise FDroidException("Failed to sign '{}'!".format(jar_file))
|
||||
@ -196,7 +197,7 @@ def main():
|
||||
sys.exit(1)
|
||||
binaries_dir = os.path.join(unsigned_dir, 'binaries')
|
||||
|
||||
if not os.path.exists(config['keystore']):
|
||||
if not config['keystore'] == "NONE" and not os.path.exists(config['keystore']):
|
||||
logging.error("Config error - missing '{0}'".format(config['keystore']))
|
||||
sys.exit(1)
|
||||
|
||||
@ -319,7 +320,7 @@ def main():
|
||||
# characters are significant, so we'll use the first 8 from
|
||||
# the MD5 of the app's ID and hope there are no collisions.
|
||||
# If a collision does occur later, we're going to have to
|
||||
# come up with a new alogrithm, AND rename all existing keys
|
||||
# come up with a new algorithm, AND rename all existing keys
|
||||
# in the keystore!
|
||||
if not skipsigning:
|
||||
if appid in config['keyaliases']:
|
||||
@ -340,20 +341,27 @@ def main():
|
||||
# if not generate one...
|
||||
env_vars = {'LC_ALL': 'C.UTF-8',
|
||||
'FDROID_KEY_STORE_PASS': config['keystorepass'],
|
||||
'FDROID_KEY_PASS': config['keypass']}
|
||||
p = FDroidPopen([config['keytool'], '-list',
|
||||
'-alias', keyalias, '-keystore', config['keystore'],
|
||||
'-storepass:env', 'FDROID_KEY_STORE_PASS'], envs=env_vars)
|
||||
'FDROID_KEY_PASS': config.get('keypass', "")}
|
||||
cmd = [config['keytool'], '-list',
|
||||
'-alias', keyalias, '-keystore', config['keystore'],
|
||||
'-storepass:env', 'FDROID_KEY_STORE_PASS']
|
||||
if config['keystore'] == 'NONE':
|
||||
cmd += config['smartcardoptions']
|
||||
p = FDroidPopen(cmd, envs=env_vars)
|
||||
if p.returncode != 0:
|
||||
logging.info("Key does not exist - generating...")
|
||||
p = FDroidPopen([config['keytool'], '-genkey',
|
||||
'-keystore', config['keystore'],
|
||||
'-alias', keyalias,
|
||||
'-keyalg', 'RSA', '-keysize', '2048',
|
||||
'-validity', '10000',
|
||||
'-storepass:env', 'FDROID_KEY_STORE_PASS',
|
||||
'-keypass:env', 'FDROID_KEY_PASS',
|
||||
'-dname', config['keydname']], envs=env_vars)
|
||||
cmd = [config['keytool'], '-genkey',
|
||||
'-keystore', config['keystore'],
|
||||
'-alias', keyalias,
|
||||
'-keyalg', 'RSA', '-keysize', '2048',
|
||||
'-validity', '10000',
|
||||
'-storepass:env', 'FDROID_KEY_STORE_PASS',
|
||||
'-dname', config['keydname']]
|
||||
if config['keystore'] == 'NONE':
|
||||
cmd += config['smartcardoptions']
|
||||
else:
|
||||
cmd += '-keypass:env', 'FDROID_KEY_PASS'
|
||||
p = FDroidPopen(cmd, envs=env_vars)
|
||||
if p.returncode != 0:
|
||||
raise BuildException("Failed to generate key", p.output)
|
||||
if appid not in generated_keys:
|
||||
@ -367,23 +375,12 @@ def main():
|
||||
unsigned_dir,
|
||||
output_dir))
|
||||
|
||||
# TODO replace below with common.sign_apk() once it has proven stable
|
||||
# Sign the application...
|
||||
p = FDroidPopen([config['jarsigner'], '-keystore', config['keystore'],
|
||||
'-storepass:env', 'FDROID_KEY_STORE_PASS',
|
||||
'-keypass:env', 'FDROID_KEY_PASS', '-sigalg',
|
||||
'SHA1withRSA', '-digestalg', 'SHA1',
|
||||
apkfile, keyalias], envs=env_vars)
|
||||
if p.returncode != 0:
|
||||
raise BuildException(_("Failed to sign application"), p.output)
|
||||
# Sign and zipalign the application...
|
||||
common.sign_apk(apkfile, signed_apk_path, keyalias)
|
||||
if appid not in signed_apks:
|
||||
signed_apks[appid] = []
|
||||
signed_apks[appid].append(apkfile)
|
||||
|
||||
# Zipalign it...
|
||||
common._zipalign(apkfile, os.path.join(output_dir, apkfilename))
|
||||
os.remove(apkfile)
|
||||
|
||||
publish_source_tarball(apkfilename, unsigned_dir, output_dir)
|
||||
logging.info('Published ' + apkfilename)
|
||||
|
||||
|
@ -52,7 +52,7 @@ def sign_jar(jar):
|
||||
args += ['-keypass:env', 'FDROID_KEY_PASS']
|
||||
env_vars = {
|
||||
'FDROID_KEY_STORE_PASS': config['keystorepass'],
|
||||
'FDROID_KEY_PASS': config['keypass'],
|
||||
'FDROID_KEY_PASS': config.get('keypass', ""),
|
||||
}
|
||||
p = common.FDroidPopen(args, envs=env_vars)
|
||||
if p.returncode != 0:
|
||||
|
@ -2323,7 +2323,7 @@ def main():
|
||||
if 'keystorepass' not in config:
|
||||
config['keystorepass'] = password
|
||||
common.write_to_config(config, 'keystorepass', config['keystorepass'])
|
||||
if 'keypass' not in config:
|
||||
if 'keypass' not in config and not config['keystore'] == "NONE":
|
||||
config['keypass'] = password
|
||||
common.write_to_config(config, 'keypass', config['keypass'])
|
||||
common.genkeystore(config)
|
||||
|
Loading…
Reference in New Issue
Block a user