From 5f2d07ce78e6443592f84a803fe2adced49ada39 Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Sun, 25 Jul 2010 15:16:30 -0400 Subject: Fix the interface of RSAKey.sign() to work as documented. Also, remove the (unused) thandy.formats.Key --- lib/thandy/formats.py | 51 ++++++++------------------------------------------- lib/thandy/keys.py | 12 ++++++++---- 2 files changed, 16 insertions(+), 47 deletions(-) diff --git a/lib/thandy/formats.py b/lib/thandy/formats.py index 0eb501b..d6f646a 100644 --- a/lib/thandy/formats.py +++ b/lib/thandy/formats.py @@ -295,7 +295,8 @@ def makeSignable(obj): def sign(signed, key): """Add an element to the signatures of 'signed', containing a new signature - of the "signed" part. + of the "signed" part using 'key'. Replaces all previous signatures + generated with 'key'. """ SIGNED_SCHEMA.checkMatch(signed) @@ -306,11 +307,13 @@ def sign(signed, key): keyid = key.getKeyID() signatures = [ s for s in signatures if s['keyid'] != keyid ] + newsignatures = key.sign(signable) + + for method, sig in newsignatures: + signatures.append({ 'keyid' : keyid, + 'method' : method, + 'sig' : sig }) - method, sig = key.sign(signable) - signatures.append({ 'keyid' : keyid, - 'method' : method, - 'sig' : sig }) signed['signatures'] = signatures def formatTime(t): @@ -512,44 +515,6 @@ PACKAGE_SCHEMA = S.Func(checkPackageFormatConsistency, PACKAGE_SCHEMA) ALL_ROLES = ('timestamp', 'mirrors', 'bundle', 'package', 'master') -class Key: - #XXXX UNUSED. - def __init__(self, key, roles=()): - self.key = key - self.roles = [] - for r,p in roles: - self.addRole(r,p) - - def addRole(self, role, path): - assert role in ALL_ROLES - self.roles.append((role, path)) - - def getRoles(self): - return self.roles - - @staticmethod - def fromJSon(obj): - # must match PUBKEY_SCHEMA - keytype = obj['_keytype'] - if keytype == 'rsa': - return Key(thandy.keys.RSAKey.fromJSon(obj)) - else: - return None - - def format(self): - return self.key.format() - - def getKeyID(self): - return self.key.getKeyID() - - def sign(self, obj=None, digest=None): - return self.key.sign(obj, digest=digest) - - def checkSignature(self, method, data, signature): - ok = self.key.checkSignature(method, data, signature) - # XXXX CACHE HERE. - return ok - class Keylist(KeyDB): def __init__(self): KeyDB.__init__(self) diff --git a/lib/thandy/keys.py b/lib/thandy/keys.py index 211150a..3385ddb 100644 --- a/lib/thandy/keys.py +++ b/lib/thandy/keys.py @@ -23,8 +23,12 @@ class PublicKey: self._roles = [] def format(self): raise NotImplemented() - def sign(self, data=None, digest=None): - # returns a list of method,signature tuples. + def sign(self, obj=None, digest=None): + """Sign either a JSon object provided in 'obj', or a digest provided + in 'digest'. Return a list of (method name, base64-encoded + signature) tuple. + + Requires that this is a private key.""" raise NotImplemented() def checkSignature(self, method, data, signature): # returns True, False, or raises UnknownMethod. @@ -125,7 +129,7 @@ class RSAKey(PublicKey): >>> k.getKeyID() == k1.getKeyID() True >>> s = { 'A B C' : "D", "E" : [ "F", "g", 99] } - >>> method, sig = k.sign(obj=s) + >>> method, sig = k.sign(obj=s)[0] >>> k.checkSignature(method, sig, obj=s) True >>> s2 = [ s ] @@ -207,7 +211,7 @@ class RSAKey(PublicKey): digest = thandy.formats.getDigest(obj) m = _pkcs1_padding(digest, (self.key.size()+1) // 8) sig = intToBase64(self.key.sign(m, "")[0]) - return (method, sig) + return [ (method, sig) ] def checkSignature(self, method, sig, obj=None, digest=None): assert _xor(obj == None, digest == None) -- cgit v1.2.3