mirror of
https://gitlab.com/fdroid/fdroidserver.git
synced 2024-10-05 18:50:09 +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:
|
else:
|
||||||
signature_algorithm = ['-sigalg', 'SHA256withRSA', '-digestalg', 'SHA-256']
|
signature_algorithm = ['-sigalg', 'SHA256withRSA', '-digestalg', 'SHA-256']
|
||||||
|
|
||||||
p = FDroidPopen([config['jarsigner'], '-keystore', config['keystore'],
|
cmd = [config['jarsigner'], '-keystore', config['keystore'],
|
||||||
'-storepass:env', 'FDROID_KEY_STORE_PASS',
|
'-storepass:env', 'FDROID_KEY_STORE_PASS']
|
||||||
'-keypass:env', 'FDROID_KEY_PASS']
|
if config['keystore'] == 'NONE':
|
||||||
+ signature_algorithm + [unsigned_path, keyalias],
|
cmd += config['smartcardoptions']
|
||||||
|
else:
|
||||||
|
cmd += '-keypass:env', 'FDROID_KEY_PASS'
|
||||||
|
p = FDroidPopen(cmd + signature_algorithm + [unsigned_path, keyalias],
|
||||||
envs={
|
envs={
|
||||||
'FDROID_KEY_STORE_PASS': config['keystorepass'],
|
'FDROID_KEY_STORE_PASS': config['keystorepass'],
|
||||||
'FDROID_KEY_PASS': config['keypass'], })
|
'FDROID_KEY_PASS': config.get('keypass', "")})
|
||||||
if p.returncode != 0:
|
if p.returncode != 0:
|
||||||
raise BuildException(_("Failed to sign application"), p.output)
|
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
|
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
|
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
|
the unsigned one. If the APK given as unsigned actually does have a
|
||||||
signature, it will be stripped out and ignored.
|
signature, it will be stripped out and ignored.
|
||||||
|
|
||||||
@ -3342,26 +3345,33 @@ def genkeystore(localconfig):
|
|||||||
|
|
||||||
env_vars = {'LC_ALL': 'C.UTF-8',
|
env_vars = {'LC_ALL': 'C.UTF-8',
|
||||||
'FDROID_KEY_STORE_PASS': localconfig['keystorepass'],
|
'FDROID_KEY_STORE_PASS': localconfig['keystorepass'],
|
||||||
'FDROID_KEY_PASS': localconfig['keypass']}
|
'FDROID_KEY_PASS': localconfig.get('keypass', "")}
|
||||||
p = FDroidPopen([config['keytool'], '-genkey',
|
|
||||||
'-keystore', localconfig['keystore'],
|
cmd = [config['keytool'], '-genkey',
|
||||||
'-alias', localconfig['repo_keyalias'],
|
'-keystore', localconfig['keystore'],
|
||||||
'-keyalg', 'RSA', '-keysize', '4096',
|
'-alias', localconfig['repo_keyalias'],
|
||||||
'-sigalg', 'SHA256withRSA',
|
'-keyalg', 'RSA', '-keysize', '4096',
|
||||||
'-validity', '10000',
|
'-sigalg', 'SHA256withRSA',
|
||||||
'-storepass:env', 'FDROID_KEY_STORE_PASS',
|
'-validity', '10000',
|
||||||
'-keypass:env', 'FDROID_KEY_PASS',
|
'-storepass:env', 'FDROID_KEY_STORE_PASS',
|
||||||
'-dname', localconfig['keydname'],
|
'-dname', localconfig['keydname'],
|
||||||
'-J-Duser.language=en'], envs=env_vars)
|
'-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:
|
if p.returncode != 0:
|
||||||
raise BuildException("Failed to generate key", p.output)
|
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:
|
if not options.quiet:
|
||||||
# now show the lovely key that was just generated
|
# now show the lovely key that was just generated
|
||||||
p = FDroidPopen([config['keytool'], '-list', '-v',
|
p = FDroidPopen([config['keytool'], '-list', '-v',
|
||||||
'-keystore', localconfig['keystore'],
|
'-keystore', localconfig['keystore'],
|
||||||
'-alias', localconfig['repo_keyalias'],
|
'-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')
|
logging.info(p.output.strip() + '\n\n')
|
||||||
# get the public key
|
# get the public key
|
||||||
p = FDroidPopenBytes([config['keytool'], '-exportcert',
|
p = FDroidPopenBytes([config['keytool'], '-exportcert',
|
||||||
|
@ -215,6 +215,9 @@ def main():
|
|||||||
f.write('name = OpenSC\nlibrary = ')
|
f.write('name = OpenSC\nlibrary = ')
|
||||||
f.write(opensc_so)
|
f.write(opensc_so)
|
||||||
f.write('\n')
|
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):
|
elif os.path.exists(keystore):
|
||||||
to_set = ['keystorepass', 'keypass', 'repo_keyalias', 'keydname']
|
to_set = ['keystorepass', 'keypass', 'repo_keyalias', 'keydname']
|
||||||
if repo_keyalias:
|
if repo_keyalias:
|
||||||
|
@ -77,12 +77,13 @@ def read_fingerprints_from_keystore():
|
|||||||
are managed by F-Droid, grouped by appid.
|
are managed by F-Droid, grouped by appid.
|
||||||
"""
|
"""
|
||||||
env_vars = {'LC_ALL': 'C.UTF-8',
|
env_vars = {'LC_ALL': 'C.UTF-8',
|
||||||
'FDROID_KEY_STORE_PASS': config['keystorepass'],
|
'FDROID_KEY_STORE_PASS': config['keystorepass']}
|
||||||
'FDROID_KEY_PASS': config['keypass']}
|
cmd = [config['keytool'], '-list',
|
||||||
p = FDroidPopen([config['keytool'], '-list',
|
'-v', '-keystore', config['keystore'],
|
||||||
'-v', '-keystore', config['keystore'],
|
'-storepass:env', 'FDROID_KEY_STORE_PASS']
|
||||||
'-storepass:env', 'FDROID_KEY_STORE_PASS'],
|
if config['keystore'] == 'NONE':
|
||||||
envs=env_vars, output=False)
|
cmd += config['smartcardoptions']
|
||||||
|
p = FDroidPopen(cmd, envs=env_vars, output=False)
|
||||||
if p.returncode != 0:
|
if p.returncode != 0:
|
||||||
raise FDroidException('could not read keystore {}'.format(config['keystore']))
|
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
|
else: # smardcards never use -keypass
|
||||||
cmd += '-keypass:env', 'FDROID_KEY_PASS'
|
cmd += '-keypass:env', 'FDROID_KEY_PASS'
|
||||||
env_vars = {'FDROID_KEY_STORE_PASS': config['keystorepass'],
|
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)
|
p = common.FDroidPopen(cmd, envs=env_vars)
|
||||||
if p.returncode != 0:
|
if p.returncode != 0:
|
||||||
raise FDroidException("Failed to sign '{}'!".format(jar_file))
|
raise FDroidException("Failed to sign '{}'!".format(jar_file))
|
||||||
@ -196,7 +197,7 @@ def main():
|
|||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
binaries_dir = os.path.join(unsigned_dir, 'binaries')
|
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']))
|
logging.error("Config error - missing '{0}'".format(config['keystore']))
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
@ -319,7 +320,7 @@ def main():
|
|||||||
# characters are significant, so we'll use the first 8 from
|
# characters are significant, so we'll use the first 8 from
|
||||||
# the MD5 of the app's ID and hope there are no collisions.
|
# 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
|
# 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!
|
# in the keystore!
|
||||||
if not skipsigning:
|
if not skipsigning:
|
||||||
if appid in config['keyaliases']:
|
if appid in config['keyaliases']:
|
||||||
@ -340,20 +341,27 @@ def main():
|
|||||||
# if not generate one...
|
# if not generate one...
|
||||||
env_vars = {'LC_ALL': 'C.UTF-8',
|
env_vars = {'LC_ALL': 'C.UTF-8',
|
||||||
'FDROID_KEY_STORE_PASS': config['keystorepass'],
|
'FDROID_KEY_STORE_PASS': config['keystorepass'],
|
||||||
'FDROID_KEY_PASS': config['keypass']}
|
'FDROID_KEY_PASS': config.get('keypass', "")}
|
||||||
p = FDroidPopen([config['keytool'], '-list',
|
cmd = [config['keytool'], '-list',
|
||||||
'-alias', keyalias, '-keystore', config['keystore'],
|
'-alias', keyalias, '-keystore', config['keystore'],
|
||||||
'-storepass:env', 'FDROID_KEY_STORE_PASS'], envs=env_vars)
|
'-storepass:env', 'FDROID_KEY_STORE_PASS']
|
||||||
|
if config['keystore'] == 'NONE':
|
||||||
|
cmd += config['smartcardoptions']
|
||||||
|
p = FDroidPopen(cmd, envs=env_vars)
|
||||||
if p.returncode != 0:
|
if p.returncode != 0:
|
||||||
logging.info("Key does not exist - generating...")
|
logging.info("Key does not exist - generating...")
|
||||||
p = FDroidPopen([config['keytool'], '-genkey',
|
cmd = [config['keytool'], '-genkey',
|
||||||
'-keystore', config['keystore'],
|
'-keystore', config['keystore'],
|
||||||
'-alias', keyalias,
|
'-alias', keyalias,
|
||||||
'-keyalg', 'RSA', '-keysize', '2048',
|
'-keyalg', 'RSA', '-keysize', '2048',
|
||||||
'-validity', '10000',
|
'-validity', '10000',
|
||||||
'-storepass:env', 'FDROID_KEY_STORE_PASS',
|
'-storepass:env', 'FDROID_KEY_STORE_PASS',
|
||||||
'-keypass:env', 'FDROID_KEY_PASS',
|
'-dname', config['keydname']]
|
||||||
'-dname', config['keydname']], envs=env_vars)
|
if config['keystore'] == 'NONE':
|
||||||
|
cmd += config['smartcardoptions']
|
||||||
|
else:
|
||||||
|
cmd += '-keypass:env', 'FDROID_KEY_PASS'
|
||||||
|
p = FDroidPopen(cmd, envs=env_vars)
|
||||||
if p.returncode != 0:
|
if p.returncode != 0:
|
||||||
raise BuildException("Failed to generate key", p.output)
|
raise BuildException("Failed to generate key", p.output)
|
||||||
if appid not in generated_keys:
|
if appid not in generated_keys:
|
||||||
@ -367,23 +375,12 @@ def main():
|
|||||||
unsigned_dir,
|
unsigned_dir,
|
||||||
output_dir))
|
output_dir))
|
||||||
|
|
||||||
# TODO replace below with common.sign_apk() once it has proven stable
|
# Sign and zipalign the application...
|
||||||
# Sign the application...
|
common.sign_apk(apkfile, signed_apk_path, keyalias)
|
||||||
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)
|
|
||||||
if appid not in signed_apks:
|
if appid not in signed_apks:
|
||||||
signed_apks[appid] = []
|
signed_apks[appid] = []
|
||||||
signed_apks[appid].append(apkfile)
|
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)
|
publish_source_tarball(apkfilename, unsigned_dir, output_dir)
|
||||||
logging.info('Published ' + apkfilename)
|
logging.info('Published ' + apkfilename)
|
||||||
|
|
||||||
|
@ -52,7 +52,7 @@ def sign_jar(jar):
|
|||||||
args += ['-keypass:env', 'FDROID_KEY_PASS']
|
args += ['-keypass:env', 'FDROID_KEY_PASS']
|
||||||
env_vars = {
|
env_vars = {
|
||||||
'FDROID_KEY_STORE_PASS': config['keystorepass'],
|
'FDROID_KEY_STORE_PASS': config['keystorepass'],
|
||||||
'FDROID_KEY_PASS': config['keypass'],
|
'FDROID_KEY_PASS': config.get('keypass', ""),
|
||||||
}
|
}
|
||||||
p = common.FDroidPopen(args, envs=env_vars)
|
p = common.FDroidPopen(args, envs=env_vars)
|
||||||
if p.returncode != 0:
|
if p.returncode != 0:
|
||||||
|
@ -2323,7 +2323,7 @@ def main():
|
|||||||
if 'keystorepass' not in config:
|
if 'keystorepass' not in config:
|
||||||
config['keystorepass'] = password
|
config['keystorepass'] = password
|
||||||
common.write_to_config(config, 'keystorepass', config['keystorepass'])
|
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
|
config['keypass'] = password
|
||||||
common.write_to_config(config, 'keypass', config['keypass'])
|
common.write_to_config(config, 'keypass', config['keypass'])
|
||||||
common.genkeystore(config)
|
common.genkeystore(config)
|
||||||
|
Loading…
Reference in New Issue
Block a user