diff --git a/fetcher.py b/fetcher.py index 3e03ebf..9a0dcf0 100755 --- a/fetcher.py +++ b/fetcher.py @@ -1,9 +1,9 @@ #!/usr/bin/python3 -# coding=utf8 import argparse import json import hashlib +from OpenSSL import crypto import socket import struct import urllib.request @@ -15,6 +15,11 @@ parser.add_argument( dest='base_url', action='store', required=True) +parser.add_argument( + '--ca-cert', + dest='ca_cert', + action='store', + required=True) parser.add_argument( '--image-type', dest='image_type', @@ -27,13 +32,24 @@ class Fetcher(object): _MAX_BP = 10000 - def __init__(self, base_url, image_type): + def __init__(self, base_url, image_type, ca_cert): self._base_url = base_url self._image_type = image_type + with open(ca_cert, 'r') as fh: + self._ca_cert = crypto.load_certificate(crypto.FILETYPE_PEM, fh.read()) + + def _Unwrap(self, wrapped): + cert = crypto.load_certificate(crypto.FILETYPE_PEM, wrapped['cert']) + crypto.verify( + cert, + wrapped['sig'].encode('ascii'), + wrapped['inner'].encode('ascii'), + 'sha256') def _GetManifest(self): url = '%s/%s.manifest.json' % (self._base_url, self._image_type) - return json.loads(urllib.request.urlopen(url).read().decode('utf8')) + resp = urllib.request.urlopen(url).read().decode('utf8') + return self._Unwrap(json.loads(resp)) def _ChooseImage(self, manifest): hostname = socket.gethostname() @@ -47,9 +63,9 @@ class Fetcher(object): def Fetch(self): manifest = self._GetManifest() - image = self._ChooseImage(manifest) - print(image) + #image = self._ChooseImage(manifest) + #print(image) -fetcher = Fetcher(FLAGS.base_url, FLAGS.image_type) +fetcher = Fetcher(FLAGS.base_url, FLAGS.image_type, FLAGS.ca_cert) fetcher.Fetch() diff --git a/wrapfile.py b/wrapfile.py new file mode 100755 index 0000000..ba251b7 --- /dev/null +++ b/wrapfile.py @@ -0,0 +1,54 @@ +#!/usr/bin/python3 + +import argparse +import codecs +import json +from OpenSSL import crypto +import sys + + +parser = argparse.ArgumentParser(description='iconograph wrapfile') +parser.add_argument( + '--cert', + dest='cert', + action='store', + required=True) +parser.add_argument( + '--key', + dest='key', + action='store', + required=True) +parser.add_argument( + '--other-cert', + dest='other_certs', + action='store', + nargs='*') +FLAGS = parser.parse_args() + + +class Wrapper(object): + + def __init__(self, key, cert, other_certs): + with open(key, 'r') as fh: + self._key = crypto.load_privatekey(crypto.FILETYPE_PEM, fh.read()) + with open(cert, 'r') as fh: + self._cert_str = fh.read() + self._cert = crypto.load_certificate(crypto.FILETYPE_PEM, self._cert_str) + self._other_cert_strs = [] + for path in (other_certs or []): + with open(path, 'r') as fh: + self._other_cert_strs.append(fh.read()) + + def Wrap(self, instr): + inbytes = instr.encode('utf8') + return { + 'cert': self._cert_str, + 'other_certs': self._other_cert_strs, + 'sig': codecs.encode(crypto.sign(self._key, inbytes, 'sha256'), 'hex').decode('ascii'), + 'inner': instr, + } + + +wrapper = Wrapper(FLAGS.key, FLAGS.cert, FLAGS.other_certs) +wrapped = wrapper.Wrap(sys.stdin.read()) +json.dump(wrapped, sys.stdout, sort_keys=True, indent=4)