sign release with OpenSSL.crypto.sign (last remaining use of ed25519)

This commit is contained in:
j 2016-01-18 19:36:21 +05:30
parent 5a920ca053
commit 14b2c99ab3
5 changed files with 67 additions and 21 deletions

View file

@ -133,10 +133,13 @@ def command_release(*args):
Release new version Release new version
""" """
print('checking...') print('checking...')
import os import base64
import json
import hashlib
import ed25519 import ed25519
import hashlib
import json
import OpenSSL.crypto
from OpenSSL.crypto import load_privatekey, FILETYPE_PEM
import os
release_name = args[0] if args else 'release' release_name = args[0] if args else 'release'
@ -144,14 +147,24 @@ def command_release(*args):
with open(os.path.expanduser('~/.openmedialibrary_release.key'), 'rb') as fd: with open(os.path.expanduser('~/.openmedialibrary_release.key'), 'rb') as fd:
SIG_KEY=ed25519.SigningKey(fd.read()) SIG_KEY=ed25519.SigningKey(fd.read())
SIG_ENCODING='base64' SIG_ENCODING='base64'
with open(os.path.expanduser('~/.openmedialibrary_tls_release.key'), 'rb') as fd:
tls_key = load_privatekey(FILETYPE_PEM, fd.read())
def sign(release): def sign(release):
value = [] value = []
for module in sorted(release['modules']): for module in sorted(release['modules']):
value += ['%s/%s' % (release['modules'][module]['version'], release['modules'][module]['sha1'])] value += ['%s/%s' % (release['modules'][module]['version'], release['modules'][module]['sha1'])]
value = '\n'.join(value) value = '\n'.join(value).encode()
sig = SIG_KEY.sign(value.encode(), encoding=SIG_ENCODING).decode() sig = SIG_KEY.sign(value, encoding=SIG_ENCODING).decode()
release['signature'] = sig release['signature'] = sig
digest = 'sha1'
tls_sig = OpenSSL.crypto.sign(tls_key, value, digest)
release['signature_%s'%digest] = base64.b64encode(tls_sig).decode()
import update
if not update.verify(release):
print('verifiying signature failed!')
return False
return True
def sha1sum(path): def sha1sum(path):
h = hashlib.sha1() h = hashlib.sha1()
@ -188,10 +201,10 @@ def command_release(*args):
'version': VERSIONS[module], 'version': VERSIONS[module],
'sha1': sha1sum(join('updates', '%s-%s.tar.bz2' % (module, VERSIONS[module]))) 'sha1': sha1sum(join('updates', '%s-%s.tar.bz2' % (module, VERSIONS[module])))
} for module in MODULES} } for module in MODULES}
sign(release) if sign(release):
with open('updates/%s.json' % release_name, 'w') as fd: with open('updates/%s.json' % release_name, 'w') as fd:
json.dump(release, fd, indent=2, sort_keys=True) json.dump(release, fd, indent=2, sort_keys=True)
print('signed latest release in updates/%s.json' % release_name) print('signed latest release in updates/%s.json' % release_name)
def command_shell(*args): def command_shell(*args):
''' '''

View file

@ -14,14 +14,12 @@ import os
import time import time
import ox import ox
import ed25519
from tornado.ioloop import PeriodicCallback from tornado.ioloop import PeriodicCallback
import settings import settings
import user.models import user.models
from changelog import Changelog from changelog import Changelog
import directory
from websocket import trigger_event from websocket import trigger_event
from localnodes import LocalNodes from localnodes import LocalNodes
from tor_request import get_opener from tor_request import get_opener
@ -126,6 +124,8 @@ class Node(Thread):
def migrate_id(self): def migrate_id(self):
import directory
import ed25519
key = self.user_id.encode() key = self.user_id.encode()
vk = ed25519.VerifyingKey(key, encoding=ENCODING) vk = ed25519.VerifyingKey(key, encoding=ENCODING)
try: try:

View file

@ -3,7 +3,6 @@
import json import json
import os import os
import ed25519
from oml.pdict import pdict from oml.pdict import pdict
from oml.utils import get_user_id from oml.utils import get_user_id
@ -60,6 +59,7 @@ for key in server_defaults:
release = pdict(os.path.join(data_path, 'release.json')) release = pdict(os.path.join(data_path, 'release.json'))
if os.path.exists(key_path): if os.path.exists(key_path):
import ed25519
with open(key_path, 'rb') as fd: with open(key_path, 'rb') as fd:
sk = ed25519.SigningKey(fd.read()) sk = ed25519.SigningKey(fd.read())
vk = sk.get_verifying_key() vk = sk.get_verifying_key()
@ -72,6 +72,22 @@ else:
USER_ID = get_user_id(ssl_key_path, ssl_cert_path) USER_ID = get_user_id(ssl_key_path, ssl_cert_path)
OML_UPDATE_KEY='K55EZpPYbP3X+3mA66cztlw1sSaUMqGwfTDKQyP2qOU' OML_UPDATE_KEY='K55EZpPYbP3X+3mA66cztlw1sSaUMqGwfTDKQyP2qOU'
OML_UPDATE_CERT='''-----BEGIN CERTIFICATE-----
MIICgzCCAeygAwIBAgIBATANBgkqhkiG9w0BAQsFADAbMRkwFwYDVQQDDBBqc2pt
Z2J4ZjJvZGN6NGNxMB4XDTE1MTEyMzIwMzY1NFoXDTE1MTEyNDIwMzY1NFowGzEZ
MBcGA1UEAwwQanNqbWdieGYyb2RjejRjcTCBnzANBgkqhkiG9w0BAQEFAAOBjQAw
gYkCgYEAuUGGJPqtGaunUSWnnW6FO9WtMZUQkhjewlvZqFE8uQVcgeXVVmarpwjc
E/xFPYtDF5083jJs0UfCcJLpvWT5Y4pW8OCMmQl2JCxBiWsPTIYFtEizPbiZtMBs
xlEBmZRyB1mO/jSZ2ECmKf6yn2CJ4lY67Jlxy5/I963GZ9ZcHdECAwEAAaOB1jCB
0zASBgNVHRMBAf8ECDAGAQH/AgEAMBQGCWCGSAGG+EIBAQEB/wQEAwICBDB7BgNV
HSUBAf8EcTBvBggrBgEFBQcDAQYIKwYBBQUHAwIGCCsGAQUFBwMEBggrBgEFBQcD
CAYKKwYBBAGCNwIBFQYKKwYBBAGCNwIBFgYKKwYBBAGCNwoDAQYKKwYBBAGCNwoD
AwYKKwYBBAGCNwoDBAYJYIZIAYb4QgQBMAsGA1UdDwQEAwIBBjAdBgNVHQ4EFgQU
TJLDBuXThizwUMavAjjcm1mPu74wDQYJKoZIhvcNAQELBQADgYEAEyn9zfdrv7w9
GV47SOE+jJFhrSHsKGf0mKC1JDOJz1l9J1IYSnM7s8BcTBPpum2CJtc6braThH46
qvg7wm/8HUkrHouawZFudwTCGQEuUpe5AEQHGiBkBWiRwR9MIkfqE3aesrhDswb6
vZVVahubX7tZ0O1zUuCpn6E0uzh1aqg=
-----END CERTIFICATE-----'''
if 'modules' in release and 'openmedialibrary' in release['modules']: if 'modules' in release and 'openmedialibrary' in release['modules']:
MINOR_VERSION = release['modules']['openmedialibrary']['version'] MINOR_VERSION = release['modules']['openmedialibrary']['version']

View file

@ -3,6 +3,8 @@
from contextlib import closing from contextlib import closing
import base64
import hashlib
import json import json
import os import os
import tarfile import tarfile
@ -13,7 +15,7 @@ import subprocess
import sys import sys
import time import time
import ed25519 import OpenSSL.crypto
import ox import ox
from oxtornado import actions from oxtornado import actions
@ -28,18 +30,33 @@ logger = logging.getLogger(__name__)
ENCODING='base64' ENCODING='base64'
def verify(release): def verify(release):
vk = ed25519.VerifyingKey(settings.OML_UPDATE_KEY, encoding=ENCODING) verified = False
value = [] value = []
for module in sorted(release['modules']): for module in sorted(release['modules']):
value += [str('%s/%s' % (release['modules'][module]['version'], release['modules'][module]['sha1']))] value += [str('%s/%s' % (release['modules'][module]['version'], release['modules'][module]['sha1']))]
value = '\n'.join(value) value = '\n'.join(value)
value = value.encode() value = value.encode()
sig = release['signature'].encode() for digest in ('sha512', 'sha256', 'sha1'):
try: if 'signature_%s'%digest in release:
vk.verify(sig, value, encoding=ENCODING) tls_sig = base64.b64decode(release['signature_%s'%digest].encode())
except ed25519.BadSignatureError: cert = OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_PEM, settings.OML_UPDATE_CERT)
return False try:
return True OpenSSL.crypto.verify(cert, tls_sig, value, digest)
verified = True
except OpenSSL.crypto.Error:
print('invalid tls signature')
verified = False
break
if 'signature' in release and not verified:
import ed25519
vk = ed25519.VerifyingKey(settings.OML_UPDATE_KEY, encoding=ENCODING)
sig = release['signature'].encode()
try:
vk.verify(sig, value, encoding=ENCODING)
verified = True
except ed25519.BadSignatureError:
verified = False
return verified
def get(url, filename=None): def get(url, filename=None):
request = urllib.request.Request(url, headers={ request = urllib.request.Request(url, headers={

View file

@ -16,7 +16,6 @@ import subprocess
import base64 import base64
import ox import ox
import ed25519
from OpenSSL.crypto import ( from OpenSSL.crypto import (
load_privatekey, load_certificate, load_privatekey, load_certificate,
dump_privatekey, dump_certificate, dump_privatekey, dump_certificate,
@ -123,6 +122,7 @@ def valid(key, value, sig):
''' '''
validate that value was signed by key validate that value was signed by key
''' '''
import ed25519
if isinstance(sig, str): if isinstance(sig, str):
sig = sig.encode() sig = sig.encode()
if isinstance(value, str): if isinstance(value, str):