summaryrefslogtreecommitdiff
path: root/wheel/signatures/__init__.py
diff options
context:
space:
mode:
Diffstat (limited to 'wheel/signatures/__init__.py')
-rw-r--r--wheel/signatures/__init__.py106
1 files changed, 0 insertions, 106 deletions
diff --git a/wheel/signatures/__init__.py b/wheel/signatures/__init__.py
deleted file mode 100644
index 3f21b50..0000000
--- a/wheel/signatures/__init__.py
+++ /dev/null
@@ -1,106 +0,0 @@
-"""
-Create and verify jws-js format Ed25519 signatures.
-"""
-
-__all__ = [ 'sign', 'verify' ]
-
-import json
-from ..util import urlsafe_b64decode, urlsafe_b64encode, native, binary
-
-ed25519ll = None
-
-ALG = "Ed25519"
-
-def get_ed25519ll():
- """Lazy import-and-test of ed25519 module"""
- global ed25519ll
-
- if not ed25519ll:
- try:
- import ed25519ll # fast (thousands / s)
- except (ImportError, OSError): # pragma nocover
- from . import ed25519py as ed25519ll # pure Python (hundreds / s)
- test()
-
- return ed25519ll
-
-def sign(payload, keypair):
- """Return a JWS-JS format signature given a JSON-serializable payload and
- an Ed25519 keypair."""
- get_ed25519ll()
- #
- header = {
- "alg": ALG,
- "jwk": {
- "kty": ALG, # alg -> kty in jwk-08.
- "vk": native(urlsafe_b64encode(keypair.vk))
- }
- }
-
- encoded_header = urlsafe_b64encode(binary(json.dumps(header, sort_keys=True)))
- encoded_payload = urlsafe_b64encode(binary(json.dumps(payload, sort_keys=True)))
- secured_input = b".".join((encoded_header, encoded_payload))
- sig_msg = ed25519ll.crypto_sign(secured_input, keypair.sk)
- signature = sig_msg[:ed25519ll.SIGNATUREBYTES]
- encoded_signature = urlsafe_b64encode(signature)
-
- return {"recipients":
- [{"header":native(encoded_header),
- "signature":native(encoded_signature)}],
- "payload": native(encoded_payload)}
-
-def assertTrue(condition, message=""):
- if not condition:
- raise ValueError(message)
-
-def verify(jwsjs):
- """Return (decoded headers, payload) if all signatures in jwsjs are
- consistent, else raise ValueError.
-
- Caller must decide whether the keys are actually trusted."""
- get_ed25519ll()
- # XXX forbid duplicate keys in JSON input using object_pairs_hook (2.7+)
- recipients = jwsjs["recipients"]
- encoded_payload = binary(jwsjs["payload"])
- headers = []
- for recipient in recipients:
- assertTrue(len(recipient) == 2, "Unknown recipient key {0}".format(recipient))
- h = binary(recipient["header"])
- s = binary(recipient["signature"])
- header = json.loads(native(urlsafe_b64decode(h)))
- assertTrue(header["alg"] == ALG,
- "Unexpected algorithm {0}".format(header["alg"]))
- if "alg" in header["jwk"] and not "kty" in header["jwk"]:
- header["jwk"]["kty"] = header["jwk"]["alg"] # b/w for JWK < -08
- assertTrue(header["jwk"]["kty"] == ALG, # true for Ed25519
- "Unexpected key type {0}".format(header["jwk"]["kty"]))
- vk = urlsafe_b64decode(binary(header["jwk"]["vk"]))
- secured_input = b".".join((h, encoded_payload))
- sig = urlsafe_b64decode(s)
- sig_msg = sig+secured_input
- verified_input = native(ed25519ll.crypto_sign_open(sig_msg, vk))
- verified_header, verified_payload = verified_input.split('.')
- verified_header = binary(verified_header)
- decoded_header = native(urlsafe_b64decode(verified_header))
- headers.append(json.loads(decoded_header))
-
- verified_payload = binary(verified_payload)
-
- # only return header, payload that have passed through the crypto library.
- payload = json.loads(native(urlsafe_b64decode(verified_payload)))
-
- return headers, payload
-
-def test():
- kp = ed25519ll.crypto_sign_keypair()
- payload = {'test': 'onstartup'}
- jwsjs = json.loads(json.dumps(sign(payload, kp)))
- verify(jwsjs)
- jwsjs['payload'] += 'x'
- try:
- verify(jwsjs)
- except ValueError:
- pass
- else: # pragma no cover
- raise RuntimeError("No error from bad wheel.signatures payload.")
-