def do_handshake(sess): key = opts.getKeyPair() certs = opts.getChain(key) opts.store.close() if not certs: print "failed to get certificate chain" return 0 msg = ttls.newClientHello() sess.setClientRandom(msg.rand) sess.send_sexp(msg) sendCert = 0 serverKey = None svr = ttls.eval(sess.read_sexp()) sess.setServerRandom(svr.rand) while 1: # still need to verify that these arrive in the right order msg = ttls.eval(sess.read_sexp()) if isinstance(msg, ttls.ServerHelloDone): break if isinstance(msg, ttls.CertificateRequest): # server needs our certificate sendCert = 1 if isinstance(msg, ttls.Certificate): if not msg.verify(): # send error message msg = ttls.Error("bad server certificate chain") sess.send_sexp(msg) raise msg serverPrin = msg.getPrincipal() sess.setServerKey(opts.lookupKey(serverPrin)) if sendCert: msg = ttls.newCertificate(certs) sess.send_sexp(msg) secret = ttls.newPreMasterSecret() sess.setPreMasterSecret(secret) msg = ttls.newClientKeyExchange(sess, secret) sess.send_sexp(msg) # in real TLS, wouldn't need CV for DH keys sig = key.priv.sign(sess.getMessages()) msg = ttls.CertificateVerify(sig) sess.send_sexp(msg) # there is no change-cipher-spec message here, because we # always use the same cipher sess.makeMasterSecret() msg = ttls.newFinished(sess.makeVerifyData()) sess.send_sexp(msg) msg = ttls.eval(sess.read_sexp()) if not sess.checkVerifyData(msg.verify): msg = ttls.Error("bad verify_data") sess.send_sexp(msg) raise msg return 1
def do_handshake(self): cli = ttls.eval(self.sess.read_sexp()) if not isinstance(cli, ttls.ClientHello): raise ProtocolError, "expected client-hello" self.sess.setClientRandom(cli.rand) svr = ttls.newServerHello() self.sess.setServerRandom(svr.rand) self.sess.send_sexp(svr) msg = ttls.newCertificate(self.server.certs) self.sess.send_sexp(msg) msg = ttls.CertificateRequest() self.sess.send_sexp(msg) msg = ttls.ServerHelloDone() self.sess.send_sexp(msg) # since we sent a CertReq message, we must get one back msg = ttls.eval(self.sess.read_sexp()) if not isinstance(msg, ttls.Certificate): raise ProtocolError, "expected certificate message" cliPrin = msg.getPrincipal() self.sess.setClientKey(self.server.opts.lookupKey(cliPrin)) # get the client-key exchange # XXX don't forget about the Bleichenbacher attack: if # something goes wrong with the PreMasterSecret, use invent a # new one instead of raising an error msg = ttls.eval(self.sess.read_sexp()) secret = msg.decryptPreMasterSecret(self.server.key.priv) self.sess.setPreMasterSecret(secret.rand) # get the cert-verify message buf = self.sess.getMessages() msg = ttls.eval(self.sess.read_sexp()) if not self.sess.verifyClient(buf, msg.sig): raise ProtocolError, "bad certificate-verify message" # there is no change-cipher-spec message here, because we # always use the same cipher self.sess.makeMasterSecret() msg = ttls.eval(self.sess.read_sexp()) if not self.sess.checkVerifyData(msg.verify): raise ProtocolError, "bad verify_data" msg = ttls.newFinished(self.sess.makeVerifyData()) self.sess.send_sexp(msg)