diff --git a/client-webserver/client.py b/client-webserver/client.py index a1f4c8743..d8a9367d8 100644 --- a/client-webserver/client.py +++ b/client-webserver/client.py @@ -2,6 +2,7 @@ from chocolate_protocol_pb2 import chocolatemessage from Crypto.Hash import SHA256 +import M2Crypto import urllib2, os, sys, time, random, CSR def sha256(m): @@ -52,5 +53,13 @@ while r.proceed.IsInitialized(): r = decode(do(k)) print r -for chall in r.challenges: +sni_todo = [] +for chall in r.challenge: print chall + if chall.type == r.DomainValidateSNI: + key = M2Crypto.RSA.load_key_string(open("key.pem").read()) + dvsni_nonce, dvsni_y, dvsni_ext = chall.data + dvsni_r = key.private_decrypt(dvsni_y, M2Crypto.RSA.pkcs1_oaep_padding) + sni_todo.append( (chall.name, dvsni_nonce, dvsni_r) ) + +print sni_todo diff --git a/server-ca/chocolate.py b/server-ca/chocolate.py index 9790defb6..781341779 100755 --- a/server-ca/chocolate.py +++ b/server-ca/chocolate.py @@ -4,7 +4,7 @@ import web, redis, time import CSR import hashlib import hmac -from Crypto.PublicKey import RSA +import M2Crypto from Crypto import Random from chocolate_protocol_pb2 import chocolatemessage from google.protobuf.message import DecodeError @@ -211,8 +211,11 @@ class session(object): if not all([safe("recipient", recipient), safe("csr", csr)]): self.die(r, r.BadRequest, uri="https://ca.example.com/failures/illegalcharacter") return - if timestamp > time.time() or time.time() - timestamp > 100: - self.die(r, r.BadRequest, uri="https://ca.example.com/failures/time") + if timestamp - time.time() > 5: + self.die(r, r.BadRequest, uri="https://ca.example.com/failures/future") + return + if time.time() - timestamp > 100: + self.die(r, r.BadRequest, uri="https://ca.example.com/failures/past") return if recipient != "ca.example.com": self.die(r, r.BadRequest, uri="https://ca.example.com/failures/recipient") @@ -300,7 +303,9 @@ class session(object): chall.succeeded = (c["satisfied"] == "True") # TODO: this contradicts comment in protocol about meaning of "succeeded" # Calculate y dvsni_r = c["dvsni:r"] - pubkey = M2Crypto.RSA.load_key_string(self.pubkey()) + bio = M2Crypto.BIO.MemoryBuffer() + bio.write(self.pubkey()) + pubkey = M2Crypto.RSA.load_pub_key_bio(bio) y = pubkey.public_encrypt(dvsni_r, M2Crypto.RSA.pkcs1_oaep_padding) # In dvsni, we send nonce, y, ext chall.data.append(c["dvsni:nonce"]) diff --git a/server-ca/daemon.py b/server-ca/daemon.py index 289a6c47d..5126a5868 100644 --- a/server-ca/daemon.py +++ b/server-ca/daemon.py @@ -26,7 +26,7 @@ # If the client never checks in, the daemon can keep advancing # the request's state, which may not be the right behavior. -import redis, time, CSR, sys +import redis, time, CSR, sys, signal r = redis.Redis() from sni_challenge.verify import verify_challenge @@ -34,6 +34,14 @@ from Crypto.Hash import SHA256, HMAC from Crypto import Random debug = "debug" in sys.argv +clean_shutdown = False + +def signal_handler(a, b): + global clean_shutdown + clean_shutdown = True + +signal.signal(signal.SIGTERM, signal_handler) +signal.signal(signal.SIGINT, signal_handler) def sha256(m): return SHA256.new(m).hexdigest() @@ -190,6 +198,7 @@ def issue(session): r.lpush("pending-issue", session) while True: + if clean_shutdown: break session = r.rpop("pending-makechallenge") if session: if debug: print "going to makechallenge for", session