From 14b2c99ab3948e4db6078ddf7af3589600f31ce0 Mon Sep 17 00:00:00 2001 From: j Date: Mon, 18 Jan 2016 19:36:21 +0530 Subject: [PATCH] sign release with OpenSSL.crypto.sign (last remaining use of ed25519) --- oml/commands.py | 31 ++++++++++++++++++++++--------- oml/nodes.py | 4 ++-- oml/settings.py | 18 +++++++++++++++++- oml/update.py | 33 +++++++++++++++++++++++++-------- oml/utils.py | 2 +- 5 files changed, 67 insertions(+), 21 deletions(-) diff --git a/oml/commands.py b/oml/commands.py index 272e1b9..8ce7a52 100644 --- a/oml/commands.py +++ b/oml/commands.py @@ -133,10 +133,13 @@ def command_release(*args): Release new version """ print('checking...') - import os - import json - import hashlib + import base64 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' @@ -144,14 +147,24 @@ def command_release(*args): with open(os.path.expanduser('~/.openmedialibrary_release.key'), 'rb') as fd: SIG_KEY=ed25519.SigningKey(fd.read()) 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): value = [] for module in sorted(release['modules']): value += ['%s/%s' % (release['modules'][module]['version'], release['modules'][module]['sha1'])] - value = '\n'.join(value) - sig = SIG_KEY.sign(value.encode(), encoding=SIG_ENCODING).decode() + value = '\n'.join(value).encode() + sig = SIG_KEY.sign(value, encoding=SIG_ENCODING).decode() 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): h = hashlib.sha1() @@ -188,10 +201,10 @@ def command_release(*args): 'version': VERSIONS[module], 'sha1': sha1sum(join('updates', '%s-%s.tar.bz2' % (module, VERSIONS[module]))) } for module in MODULES} - sign(release) - with open('updates/%s.json' % release_name, 'w') as fd: - json.dump(release, fd, indent=2, sort_keys=True) - print('signed latest release in updates/%s.json' % release_name) + if sign(release): + with open('updates/%s.json' % release_name, 'w') as fd: + json.dump(release, fd, indent=2, sort_keys=True) + print('signed latest release in updates/%s.json' % release_name) def command_shell(*args): ''' diff --git a/oml/nodes.py b/oml/nodes.py index 2d59198..3ee4d17 100644 --- a/oml/nodes.py +++ b/oml/nodes.py @@ -14,14 +14,12 @@ import os import time import ox -import ed25519 from tornado.ioloop import PeriodicCallback import settings import user.models from changelog import Changelog -import directory from websocket import trigger_event from localnodes import LocalNodes from tor_request import get_opener @@ -126,6 +124,8 @@ class Node(Thread): def migrate_id(self): + import directory + import ed25519 key = self.user_id.encode() vk = ed25519.VerifyingKey(key, encoding=ENCODING) try: diff --git a/oml/settings.py b/oml/settings.py index 4a5793b..f747f63 100644 --- a/oml/settings.py +++ b/oml/settings.py @@ -3,7 +3,6 @@ import json import os -import ed25519 from oml.pdict import pdict 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')) if os.path.exists(key_path): + import ed25519 with open(key_path, 'rb') as fd: sk = ed25519.SigningKey(fd.read()) vk = sk.get_verifying_key() @@ -72,6 +72,22 @@ else: USER_ID = get_user_id(ssl_key_path, ssl_cert_path) 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']: MINOR_VERSION = release['modules']['openmedialibrary']['version'] diff --git a/oml/update.py b/oml/update.py index 82db58e..471fdb4 100644 --- a/oml/update.py +++ b/oml/update.py @@ -3,6 +3,8 @@ from contextlib import closing +import base64 +import hashlib import json import os import tarfile @@ -13,7 +15,7 @@ import subprocess import sys import time -import ed25519 +import OpenSSL.crypto import ox from oxtornado import actions @@ -28,18 +30,33 @@ logger = logging.getLogger(__name__) ENCODING='base64' def verify(release): - vk = ed25519.VerifyingKey(settings.OML_UPDATE_KEY, encoding=ENCODING) + verified = False value = [] for module in sorted(release['modules']): value += [str('%s/%s' % (release['modules'][module]['version'], release['modules'][module]['sha1']))] value = '\n'.join(value) value = value.encode() - sig = release['signature'].encode() - try: - vk.verify(sig, value, encoding=ENCODING) - except ed25519.BadSignatureError: - return False - return True + for digest in ('sha512', 'sha256', 'sha1'): + if 'signature_%s'%digest in release: + tls_sig = base64.b64decode(release['signature_%s'%digest].encode()) + cert = OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_PEM, settings.OML_UPDATE_CERT) + try: + 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): request = urllib.request.Request(url, headers={ diff --git a/oml/utils.py b/oml/utils.py index 0144820..8a46611 100644 --- a/oml/utils.py +++ b/oml/utils.py @@ -16,7 +16,6 @@ import subprocess import base64 import ox -import ed25519 from OpenSSL.crypto import ( load_privatekey, load_certificate, dump_privatekey, dump_certificate, @@ -123,6 +122,7 @@ def valid(key, value, sig): ''' validate that value was signed by key ''' + import ed25519 if isinstance(sig, str): sig = sig.encode() if isinstance(value, str):