def authorize_using_external_server(self, request): """ Access authorization using an external authorization server. The request is put in a JSON Web Token (JWT) that is signed and includes timestamps and information about sender and receiver. """ ip_addr = self.sec_conf['authorization']['server_ip'] port = self.sec_conf['authorization']['server_port'] # Alternative: specify node_id/dnQualifier instead in sec_conf and create a tunnel for the # runtime-to-runtime communication (see calvin_proto.py). Could also add node_id as "aud" (audience) in jwt payload. authorization_server_uri = "http://%s:%d" % (ip_addr, port) payload = { "iss": self.node.id, "iat": datetime.utcnow(), "exp": datetime.utcnow() + timedelta(seconds=60), "request": request } cert_conffile = _conf.get("security", "certificate_conf") domain = _conf.get("security", "certificate_domain") cert_conf = certificate.Config(cert_conffile, domain) node_name = self.node.attributes.get_node_name_as_str() private_key = certificate.get_private_key(cert_conf, node_name) # Create a JSON Web Token signed using the node's Elliptic Curve private key. jwt_request = jwt.encode(payload, private_key, algorithm='ES256') # cert_name is this node's certificate filename (without file extension) cert_name = certificate.get_own_cert_name(cert_conf, node_name) try: # Send request to authorization server. response = self.request_handler.get_authorization_decision(authorization_server_uri, jwt_request, cert_name) except Exception as e: _log.error("Security: authorization server error - %s" % str(e)) return ("indeterminate", []) try: # Get authorization server certificate from disk. # TODO: get certificate from DHT if it wasn't found on disk. certificate_authz_server = certificate.get_other_certificate(cert_conf, node_name, response["cert_name"]) public_key_authz_server = certificate.get_public_key(certificate_authz_server) authz_server_id = certificate_authz_server.get_subject().dnQualifier # Decode the JSON Web Token returned from the authorization server. # The signature is verified using the Elliptic Curve public key of the authorization server. # Exception raised if signature verification fails or if issuer and/or audience are incorrect. decoded = jwt.decode(response["jwt"], public_key_authz_server, algorithms=['ES256'], issuer=authz_server_id, audience=self.node.id) response = decoded['response'] return (response['decision'], response.get("obligations", [])) except Exception as e: _log.error("Security: JWT decoding error - %s" % str(e)) return ("indeterminate", [])
def decode_jwt(token, sender_cert_name, node_name, node_id, actor_id=None): """Decode JSON Web Token""" # Get authorization server certificate from disk. try: sender_certificate = certificate.get_certificate(node_name, sender_cert_name) except Exception: raise Exception("Certificate not found.") sender_public_key = certificate.get_public_key(sender_certificate) sender_node_id = sender_certificate.get_subject().dnQualifier # The signature is verified using the Elliptic Curve public key of the sender. # Exception raised if signature verification fails or if issuer and/or audience are incorrect. decoded = jwt.decode(token, sender_public_key, algorithms=['ES256'], issuer=sender_node_id, audience=node_id) if actor_id and decoded["sub"] != actor_id: raise # Exception raised if subject (actor_id) is incorrect. return decoded
def decode_jwt(token, sender_cert_name, node_name, node_id, actor_id=None): """Decode JSON Web Token""" # Get authorization server certificate from disk. try: sender_certificate = certificate.get_certificate( node_name, sender_cert_name) except Exception: raise Exception("Certificate not found.") sender_public_key = certificate.get_public_key(sender_certificate) sender_node_id = sender_certificate.get_subject().dnQualifier # The signature is verified using the Elliptic Curve public key of the sender. # Exception raised if signature verification fails or if issuer and/or audience are incorrect. decoded = jwt.decode(token, sender_public_key, algorithms=['ES256'], issuer=sender_node_id, audience=node_id) if actor_id and decoded["sub"] != actor_id: raise # Exception raised if subject (actor_id) is incorrect. return decoded
def get_ca_public_key(self): """Return the public key from certificate""" return certificate.get_public_key( self.configuration["CA_default"]["certificate"])
def get_cs_public_key(self): """Return the public key from certificate""" return certificate.get_public_key(self.certificate)
def get_ca_public_key(self): """Return the public key from certificate""" return certificate.get_public_key(self.configuration["CA_default"]["certificate"])