def test_sign(self): data = "Hello World!" for algorithm, hash_method in ( ("rsa-sha1", hashlib.sha1,), ("rsa-sha256", hashlib.sha256,), ): stream = MemoryStream(data) headers = Headers() headers.addRawHeader("Originator", "mailto:[email protected]") headers.addRawHeader("Recipient", "mailto:[email protected]") headers.setHeader("Content-Type", MimeType("text", "calendar", **{"component": "VEVENT", "charset": "utf-8"})) request = DKIMRequest("POST", "/", headers, stream, "example.com", "dkim", self.private_keyfile, algorithm, ("Originator", "Recipient", "Content-Type",), True, True, True, 3600) result = (yield request.sign()) # Manually create what should be the correct thing to sign and make sure signatures match bodyhash = base64.b64encode(hash_method(DKIMUtils.canonicalizeBody(data)).digest()) sign_this = """originator:mailto:[email protected] recipient:mailto:[email protected] content-type:%s ischedule-version:1.0 ischedule-message-id:%s dkim-signature:v=1; d=example.com; s=dkim; t=%s; x=%s; a=%s; q=private-exchange:http/well-known:dns/txt; c=ischedule-relaxed/simple; h=Originator:Recipient:Content-Type:iSchedule-Version:iSchedule-Message-ID; bh=%s; b=""".replace("\n", "\r\n") % (headers.getRawHeaders("Content-Type")[0], request.message_id, request.time, request.expire, algorithm, bodyhash) key = RSA.importKey(open(self.private_keyfile).read()) signature = DKIMUtils.sign(sign_this, key, DKIMUtils.hash_func(algorithm)) self.assertEqual(result, signature) # Make sure header is updated in the request updated_header = "v=1; d=example.com; s=dkim; t=%s; x=%s; a=%s; q=private-exchange:http/well-known:dns/txt; c=ischedule-relaxed/simple; h=Originator:Recipient:Content-Type:iSchedule-Version:iSchedule-Message-ID; bh=%s; b=%s" % (request.time, request.expire, algorithm, bodyhash, signature,) self.assertEqual(request.headers.getRawHeaders("DKIM-Signature")[0], updated_header) # Try to verify result using public key pubkey = RSA.importKey(open(self.public_keyfile).read()) self.assertEqual(DKIMUtils.verify(sign_this, result, pubkey, DKIMUtils.hash_func(algorithm)), None)
def test_generateSignature(self): data = "Hello World!" for algorithm, hash_method in ( ("rsa-sha1", hashlib.sha1,), ("rsa-sha256", hashlib.sha256,), ): stream = MemoryStream(data) headers = Headers() headers.addRawHeader("Originator", "mailto:[email protected]") headers.addRawHeader("Recipient", "mailto:[email protected]") headers.setHeader("Content-Type", MimeType("text", "calendar", **{"component": "VEVENT", "charset": "utf-8"})) request = DKIMRequest("POST", "/", headers, stream, "example.com", "dkim", self.private_keyfile, algorithm, ("Originator", "Recipient", "Content-Type",), True, True, True, 3600) # Manually create what should be the correct thing to sign bodyhash = base64.b64encode(hash_method(data).digest()) sign_this = """originator:mailto:[email protected] recipient:mailto:[email protected] content-type:%s ischedule-version:1.0 dkim-signature:v=1; d=example.com; s=dkim; t=%s; x=%s; a=%s; q=dns/txt:http/well-known; c=ischedule-relaxed/simple; h=Originator:Recipient; bh=%s; b=""".replace("\n", "\r\n") % (headers.getRawHeaders("Content-Type")[0], str(int(time.time())), str(int(time.time() + 3600)), algorithm, bodyhash) result = request.generateSignature(sign_this) key = RSA.importKey(open(self.private_keyfile).read()) signature = DKIMUtils.sign(sign_this, key, DKIMUtils.hash_func(algorithm)) self.assertEqual(result, signature)
def test_body_hash(self): data = "Hello World!" for algorithm, hash_method in ( ( "rsa-sha1", hashlib.sha1, ), ( "rsa-sha256", hashlib.sha256, ), ): stream = str(data) headers = Headers() headers.addRawHeader("Originator", "mailto:[email protected]") headers.addRawHeader("Recipient", "mailto:[email protected]") headers.setHeader( "Content-Type", MimeType("text", "calendar", **{ "component": "VEVENT", "charset": "utf-8" })) request = DKIMRequest("POST", "/", headers, stream, "example.com", "dkim", "/tmp/key", algorithm, ( "Originator", "Recipient", "Content-Type", ), True, True, True, 3600) hash = base64.b64encode( hash_method(DKIMUtils.canonicalizeBody(data)).digest()) result = (yield request.bodyHash()) self.assertEqual(result, hash)
def _processRequest(self): """ Process the request by sending it to the relevant server. @return: the HTTP response. @rtype: L{Response} """ ssl, host, port, _ignore_path = self.server.details() path = "/" + config.Servers.ConduitName headers = Headers() headers.setHeader("Host", utf8String(host + ":{}".format(port))) if self.streamType: # For attachments we put the base64-encoded JSON data into a header headers.setHeader("Content-Type", self.streamType) headers.addRawHeader("XPOD", base64.b64encode(self.data)) else: headers.setHeader("Content-Type", MimeType("application", "json", params={"charset": "utf-8", })) headers.setHeader("User-Agent", "CalendarServer/{}".format(version)) headers.addRawHeader(*self.server.secretHeader()) from twisted.internet import reactor f = Factory() f.protocol = HTTPClientProtocol ep = GAIEndpoint(reactor, host, port, _configuredClientContextFactory() if ssl else None) proto = (yield ep.connect(f)) request = ClientRequest("POST", path, headers, self.stream if self.stream is not None else self.data) if accountingEnabledForCategory("xPod"): self.loggedRequest = yield self.logRequest(request) response = (yield proto.submitRequest(request)) returnValue(response)
def test_body_hash(self): data = "Hello World!" for algorithm, hash_method in ( ("rsa-sha1", hashlib.sha1,), ("rsa-sha256", hashlib.sha256,), ): stream = str(data) headers = Headers() headers.addRawHeader("Originator", "mailto:[email protected]") headers.addRawHeader("Recipient", "mailto:[email protected]") headers.setHeader("Content-Type", MimeType("text", "calendar", **{"component": "VEVENT", "charset": "utf-8"})) request = DKIMRequest("POST", "/", headers, stream, "example.com", "dkim", "/tmp/key", algorithm, ("Originator", "Recipient", "Content-Type",), True, True, True, 3600) hash = base64.b64encode(hash_method(DKIMUtils.canonicalizeBody(data)).digest()) result = (yield request.bodyHash()) self.assertEqual(result, hash)
def _processRequest(self): """ Process the request by sending it to the relevant server. @return: the HTTP response. @rtype: L{Response} """ ssl, host, port, _ignore_path = self.server.details() path = "/" + config.Servers.ConduitName headers = Headers() headers.setHeader("Host", utf8String(host + ":{}".format(port))) if self.streamType: # For attachments we put the base64-encoded JSON data into a header headers.setHeader("Content-Type", self.streamType) headers.addRawHeader("XPOD", base64.b64encode(self.data)) else: headers.setHeader( "Content-Type", MimeType("application", "json", params={ "charset": "utf-8", })) headers.setHeader("User-Agent", "CalendarServer/{}".format(version)) headers.addRawHeader(*self.server.secretHeader()) from twisted.internet import reactor f = Factory() f.protocol = HTTPClientProtocol ep = GAIEndpoint( reactor, host, port, _configuredClientContextFactory(host) if ssl else None) proto = (yield ep.connect(f)) request = ClientRequest( "POST", path, headers, self.stream if self.stream is not None else self.data) if accountingEnabledForCategory("xPod"): self.loggedRequest = yield self.logRequest(request) response = (yield proto.submitRequest(request)) returnValue(response)