make `fdroid update` check that it can sign the repo, or exit with error
There is no good reason to run unsigned repos any more. It is trivially easy to create and use a signed repo, and having to support unsigned repos in the client makes some security-critical parts of the code a lot more complicated. refs #13 https://gitlab.com/fdroid/fdroidserver/issues/13 https://gitlab.com/fdroid/fdroidclient/issues/12
This commit is contained in:
parent
0d62c3093a
commit
86865faa62
|
@ -664,6 +664,36 @@ def scan_apks(apps, apkcache, repodir, knownapks):
|
|||
repo_pubkey_fingerprint = None
|
||||
|
||||
|
||||
# Generate a certificate fingerprint the same way keytool does it
|
||||
# (but with slightly different formatting)
|
||||
def cert_fingerprint(data):
|
||||
digest = hashlib.sha256(data).digest()
|
||||
ret = []
|
||||
ret.append(' '.join("%02X" % ord(b) for b in digest))
|
||||
return " ".join(ret)
|
||||
|
||||
|
||||
def extract_pubkey():
|
||||
global repo_pubkey_fingerprint
|
||||
if 'repo_pubkey' in config:
|
||||
pubkey = unhexlify(config['repo_pubkey'])
|
||||
else:
|
||||
p = FDroidPopen(['keytool', '-exportcert',
|
||||
'-alias', config['repo_keyalias'],
|
||||
'-keystore', config['keystore'],
|
||||
'-storepass:file', config['keystorepassfile']]
|
||||
+ config['smartcardoptions'], output=False)
|
||||
if p.returncode != 0 or len(p.output) < 20:
|
||||
msg = "Failed to get repo pubkey!"
|
||||
if config['keystore'] == 'NONE':
|
||||
msg += ' Is your crypto smartcard plugged in?'
|
||||
logging.critical(msg)
|
||||
sys.exit(1)
|
||||
pubkey = p.output
|
||||
repo_pubkey_fingerprint = cert_fingerprint(pubkey)
|
||||
return hexlify(pubkey)
|
||||
|
||||
|
||||
def make_index(apps, sortedids, apks, repodir, archive, categories):
|
||||
"""Make a repo index.
|
||||
|
||||
|
@ -711,38 +741,28 @@ def make_index(apps, sortedids, apks, repodir, archive, categories):
|
|||
repoel.setAttribute("version", "12")
|
||||
repoel.setAttribute("timestamp", str(int(time.time())))
|
||||
|
||||
if 'repo_keyalias' in config:
|
||||
|
||||
# Generate a certificate fingerprint the same way keytool does it
|
||||
# (but with slightly different formatting)
|
||||
def cert_fingerprint(data):
|
||||
digest = hashlib.sha256(data).digest()
|
||||
ret = []
|
||||
ret.append(' '.join("%02X" % ord(b) for b in digest))
|
||||
return " ".join(ret)
|
||||
|
||||
def extract_pubkey():
|
||||
global repo_pubkey_fingerprint
|
||||
if 'repo_pubkey' in config:
|
||||
pubkey = unhexlify(config['repo_pubkey'])
|
||||
else:
|
||||
p = FDroidPopen(['keytool', '-exportcert',
|
||||
'-alias', config['repo_keyalias'],
|
||||
'-keystore', config['keystore'],
|
||||
'-storepass:file', config['keystorepassfile']]
|
||||
+ config['smartcardoptions'], output=False)
|
||||
if p.returncode != 0:
|
||||
msg = "Failed to get repo pubkey!"
|
||||
if config['keystore'] == 'NONE':
|
||||
msg += ' Is your crypto smartcard plugged in?'
|
||||
logging.critical(msg)
|
||||
sys.exit(1)
|
||||
pubkey = p.output
|
||||
repo_pubkey_fingerprint = cert_fingerprint(pubkey)
|
||||
return hexlify(pubkey)
|
||||
|
||||
repoel.setAttribute("pubkey", extract_pubkey())
|
||||
nosigningkey = False
|
||||
if not 'repo_keyalias' in config:
|
||||
nosigningkey = True
|
||||
logging.critical("'repo_keyalias' not found in config.py!")
|
||||
if not 'keystore' in config:
|
||||
nosigningkey = True
|
||||
logging.critical("'keystore' not found in config.py!")
|
||||
if not 'keystorepass' in config:
|
||||
nosigningkey = True
|
||||
logging.critical("'keystorepass' not found in config.py!")
|
||||
if not 'keypass' in config:
|
||||
nosigningkey = True
|
||||
logging.critical("'keypass' not found in config.py!")
|
||||
if not os.path.exists(config['keystore']):
|
||||
nosigningkey = True
|
||||
logging.critical("'" + config['keystore'] + "' does not exist!")
|
||||
if nosigningkey:
|
||||
logging.warning("`fdroid update` requires a signing key, you can create one using:")
|
||||
logging.warning("\tfdroid update --create-key")
|
||||
sys.exit(1)
|
||||
|
||||
repoel.setAttribute("pubkey", extract_pubkey())
|
||||
root.appendChild(repoel)
|
||||
|
||||
for appid in sortedids:
|
||||
|
|
|
@ -325,6 +325,74 @@ $fdroid init --keystore NONE
|
|||
test -e opensc-fdroid.cfg
|
||||
test ! -e NONE
|
||||
|
||||
|
||||
#------------------------------------------------------------------------------#
|
||||
echo_header "setup a new repo with no keystore, add APK, and update"
|
||||
|
||||
REPOROOT=`create_test_dir`
|
||||
KEYSTORE=$REPOROOT/keystore.jks
|
||||
cd $REPOROOT
|
||||
touch config.py
|
||||
touch fdroid-icon.png
|
||||
mkdir repo/
|
||||
cp $WORKSPACE/tests/urzip.apk $REPOROOT/
|
||||
set +e
|
||||
$fdroid update --create-metadata
|
||||
if [ $? -eq 0 ]; then
|
||||
echo "This should have failed because this repo has no keystore!"
|
||||
exit 1
|
||||
else
|
||||
echo "`fdroid update` prompted to add keystore"
|
||||
fi
|
||||
set -e
|
||||
|
||||
# now set up fake, non-working keystore setup
|
||||
touch $KEYSTORE
|
||||
echo "keystore = \"$KEYSTORE\"" >> config.py
|
||||
echo 'repo_keyalias = "foo"' >> config.py
|
||||
echo 'keystorepass = "foo"' >> config.py
|
||||
echo 'keypass = "foo"' >> config.py
|
||||
set +e
|
||||
$fdroid update --create-metadata
|
||||
if [ $? -eq 0 ]; then
|
||||
echo "This should have failed because this repo has a bad/fake keystore!"
|
||||
exit 1
|
||||
else
|
||||
echo "`fdroid update` prompted to add keystore"
|
||||
fi
|
||||
set -e
|
||||
|
||||
|
||||
#------------------------------------------------------------------------------#
|
||||
echo_header "setup a new repo with keystore with APK, update, then without key"
|
||||
|
||||
REPOROOT=`create_test_dir`
|
||||
KEYSTORE=$REPOROOT/keystore.jks
|
||||
cd $REPOROOT
|
||||
$fdroid init --keystore $KEYSTORE
|
||||
test -e $KEYSTORE
|
||||
cp $WORKSPACE/tests/urzip.apk $REPOROOT/repo/
|
||||
$fdroid update --create-metadata
|
||||
test -e repo/index.xml
|
||||
test -e repo/index.jar
|
||||
grep -F '<application id=' repo/index.xml
|
||||
|
||||
# now set fake repo_keyalias
|
||||
sed -i 's,^ *repo_keyalias.*,repo_keyalias = "fake",' $REPOROOT/config.py
|
||||
set +e
|
||||
$fdroid update
|
||||
if [ $? -eq 0 ]; then
|
||||
echo "This should have failed because this repo has a bad repo_keyalias!"
|
||||
exit 1
|
||||
else
|
||||
echo "`fdroid update` prompted to add keystore"
|
||||
fi
|
||||
set -e
|
||||
|
||||
|
||||
#------------------------------------------------------------------------------#
|
||||
|
||||
# remove this to prevent git conflicts and complaining
|
||||
rm -rf $WORKSPACE/fdroidserver.egg-info/
|
||||
|
||||
echo SUCCESS
|
||||
|
|
Loading…
Reference in New Issue