support repo signing with a key on a smartcard

This assumes that the smartcard is already setup with a signing key.  init
does not generate a key on the smartcard, and skips genkey() if things are
configured to use a smartcard.

This also does not touch APK signing because that is a much more elaborate
question, since each app is signed by its own key.
This commit is contained in:
Hans-Christoph Steiner 2014-04-04 00:05:22 -04:00
parent 9945045f1b
commit 3829d37d34
5 changed files with 59 additions and 7 deletions

View File

@ -0,0 +1,4 @@
name = OpenSC
description = SunPKCS11 w/ OpenSC Smart card Framework
library = /usr/lib/opensc-pkcs11.so
slotListIndex = 1

View File

@ -19,6 +19,7 @@
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import glob
import hashlib
import os
import re
@ -44,6 +45,16 @@ def write_to_config(key, value):
with open('config.py', 'w') as f:
f.writelines(data)
def disable_in_config(key, value):
'''write a key/value to the local config.py, then comment it out'''
with open('config.py', 'r') as f:
data = f.read()
pattern = '\n[\s#]*' + key + '\s*=\s*"[^"]*"'
repl = '\n#' + key + ' = "' + value + '"'
data = re.sub(pattern, repl, data)
with open('config.py', 'w') as f:
f.writelines(data)
def genpassword():
'''generate a random password for when generating keys'''
@ -196,7 +207,30 @@ def main():
if options.distinguished_name:
keydname = options.distinguished_name
write_to_config('keydname', keydname)
if not os.path.isfile(keystore):
if keystore == 'NONE': # we're using a smartcard
write_to_config('repo_keyalias', '1') # seems to be the default
disable_in_config('keypass', 'never used with smartcard')
write_to_config('smartcardoptions',
('-storetype PKCS11 -providerName SunPKCS11-OpenSC '
+ '-providerClass sun.security.pkcs11.SunPKCS11 '
+ '-providerArg opensc-fdroid.cfg'))
# find opensc-pkcs11.so
if not os.path.exists('opensc-fdroid.cfg'):
if os.path.exists('/usr/lib/opensc-pkcs11.so'):
opensc_so = '/usr/lib/opensc-pkcs11.so'
elif os.path.exists('/usr/lib64/opensc-pkcs11.so'):
opensc_so = '/usr/lib64/opensc-pkcs11.so'
else:
files = glob.glob('/usr/lib/' + os.uname()[4] + '-*-gnu/opensc-pkcs11.so')
if len(files) > 0:
opensc_so = files[0]
with open(os.path.join(examplesdir, 'opensc-fdroid.cfg'), 'r') as f:
opensc_fdroid = f.read()
opensc_fdroid = re.sub('^library.*', 'library = ' + opensc_so, opensc_fdroid,
flags=re.MULTILINE)
with open('opensc-fdroid.cfg', 'w') as f:
f.write(opensc_fdroid)
elif not os.path.exists(keystore):
# no existing or specified keystore, generate the whole thing
keystoredir = os.path.dirname(keystore)
if not os.path.exists(keystoredir):

View File

@ -796,12 +796,15 @@ def make_index(apps, apks, repodir, archive, categories):
sys.exit(1)
# Sign the index...
p = FDroidPopen(['jarsigner', '-keystore', config['keystore'],
'-storepass:file', config['keystorepassfile'],
'-keypass:file', config['keypassfile'],
'-digestalg', 'SHA1', '-sigalg', 'MD5withRSA',
os.path.join(repodir, 'index.jar') , config['repo_keyalias']]
+ config['smartcardoptions'])
args = ['jarsigner', '-keystore', config['keystore'],
'-storepass:file', config['keystorepassfile'],
'-digestalg', 'SHA1', '-sigalg', 'MD5withRSA',
os.path.join(repodir, 'index.jar'), config['repo_keyalias']]
if config['keystore'] == 'NONE':
args += config['smartcardoptions']
else: # smardcards never use -keypass
args += ['-keypass:file', config['keypassfile']]
p = FDroidPopen(args)
# TODO keypass should be sent via stdin
if p.returncode != 0:
logging.info("Failed to sign index")

View File

@ -23,6 +23,7 @@ setup(name='fdroidserver',
[ 'buildserver/config.buildserver.py',
'examples/config.py',
'examples/makebs.config.py',
'examples/opensc-fdroid.cfg',
'examples/fdroid-icon.png']),
('fdroidserver/getsig', ['fdroidserver/getsig/getsig.class'])
],

View File

@ -49,3 +49,13 @@ $fdroid update -c
$fdroid update
test -e repo/index.xml
test -e repo/index.jar
#------------------------------------------------------------------------------#
# setup a new repo from scratch with a HSM/smartcard
REPOROOT=`mktemp --directory --tmpdir=$WORKSPACE`
cd $REPOROOT
$fdroid init --keystore NONE
test -e opensc-fdroid.cfg
test ! -e NONE