def GetSelfCredential(certificate, xnr, type): if type: hrn = urn_to_hrn(xrn)[0] else: hrn, type = urn_to_hrn(xrn) origin_hrn = Certificate(string=cert).get_subject() ### authenticate the gid # import here so we can load this module at build-time for sfa2wsdl #from sfa.storage.alchemy import dbsession from sfa.storage.model import RegRecord # xxx-local - the current code runs Resolve, which would forward to # another registry if needed # I wonder if this is truly the intention, or shouldn't we instead # only look in the local db ? records = self.api.manager.Resolve(self.api, xrn, type, details=False) if not records: raise RecordNotFound(hrn) record_obj = RegRecord (dict=records[0]) # xxx-local the local-only version would read #record_obj = dbsession.query(RegRecord).filter_by(hrn=hrn).first() #if not record_obj: raise RecordNotFound(hrn) gid = record_obj.get_gid_object() gid_str = gid.save_to_string(save_parents=True) self.api.auth.authenticateGid(gid_str, [cert, type, hrn]) # authenticate the certificate against the gid in the db certificate = Certificate(string=cert) if not certificate.is_pubkey(gid.get_pubkey()): for (obj,name) in [ (certificate,"CERT"), (gid,"GID"), ]: if hasattr (obj,'filename'): raise ConnectionKeyGIDMismatch(gid.get_subject()) return self.api.manager.GetCredential(self.api, xrn, type)
def testSaveAndLoadString(self): cert = Certificate(subject="test") cert.add_extension("subjectAltName", 0, "URI:http://foovalue") # create an issuer and sign the certificate issuerKey = Keypair(create=True) issuerSubject = "testissuer" cert.set_issuer(issuerKey, issuerSubject) cert.sign() certstr = cert.save_to_string() #print certstr cert2 = Certificate() cert2.load_from_string(certstr) # read back the subject and make sure it is correct subj = cert2.get_subject() self.assertEqual(subj, "test") # read back the issuer and make sure it is correct issuerName = cert2.get_issuer() self.assertEqual(issuerName, "testissuer") # read back the extension and make sure it is correct self.assertEqual(cert2.get_extension("subjectAltName"), "URI:http://foovalue")
def testLongExtension(self): cert = Certificate(subject="test") # should produce something around 256 KB veryLongString = "URI:http://" shortString = "" for i in range(1, 80): shortString = shortString + "abcdefghijklmnopqrstuvwxyz012345" for i in range(1, 100): veryLongString = veryLongString + shortString + str(i) cert.add_extension("subjectAltName", 0, veryLongString) # create an issuer and sign the certificate issuerKey = Keypair(create=True) issuerSubject = "testissuer" cert.set_issuer(issuerKey, issuerSubject) cert.sign() certstr = cert.save_to_string() cert2 = Certificate() cert2.load_from_string(certstr) val = cert2.get_extension("subjectAltName") self.assertEqual(val, veryLongString)
def testVerify(self): cert = Certificate(subject="test") # create an issuer and sign the certificate issuerKey = Keypair(create=True) issuerSubject = "testissuer" cert.set_issuer(issuerKey, issuerSubject) cert.sign() result = cert.verify(issuerKey) self.assert_(result) # create another key issuerKey2 = Keypair(create=True) issuerSubject2 = "wrongissuer" # and make sure it doesn't verify result = cert.verify(issuerKey2) self.assert_(not result) # load the cert from a string, and verify again cert2 = Certificate(string = cert.save_to_string()) result = cert2.verify(issuerKey) self.assert_(result) result = cert2.verify(issuerKey2) self.assert_(not result)
def testSetData(self): cert = Certificate(subject="test") data = "this is a test" cert.set_data(data) self.assertEqual(cert.get_data(), data) # try something a bit more complicated, like an xmlrpc encoding of # some parameters cert = Certificate(subject="test") data = xmlrpclib.dumps((1, "foo", ["a", "b"], {"c": "d", "e": "f"}, True)) cert.set_data(data) self.assertEqual(cert.get_data(), data)
def determine_sfa_filekind(fn): if fn.endswith('.gid'): return 'gid' elif fn.endswith('.cert'): return 'certificate' elif fn.endswith('cred'): return 'credential' try: cred=Credential(filename=fn) return 'credential' except: pass try: gid=GID(filename=fn) if gid.uuid: return 'gid' except: pass try: cert = Certificate(filename = fn) return 'certificate' except: pass # to be completed # if "gidCaller" in dict: # return "credential" # # if "uuid" in dict: # return "gid" return "unknown"
def getCredential(self): """ Get our credential from a remote registry """ path = self.config.SFA_DATA_DIR config_dir = self.config.config_path cred_filename = path + os.sep + 'node.cred' try: credential = Credential(filename=cred_filename) return credential.save_to_string(save_parents=True) except IOError: node_pkey_file = config_dir + os.sep + "node.key" node_gid_file = config_dir + os.sep + "node.gid" cert_filename = path + os.sep + 'server.cert' if not os.path.exists(node_pkey_file) or \ not os.path.exists(node_gid_file): self.get_node_key() # get node's hrn gid = GID(filename=node_gid_file) hrn = gid.get_hrn() # get credential from registry cert_str = Certificate(filename=cert_filename).save_to_string( save_parents=True) registry = self.get_registry() cred = registry.GetSelfCredential(cert_str, hrn, 'node') # xxx credfile is undefined Credential(string=cred).save_to_file(credfile, save_parents=True) return cred
def do_POST(self): """Handles the HTTPS POST request. It was copied out from SimpleXMLRPCServer.py and modified to shutdown the socket cleanly. """ try: peer_cert = Certificate() peer_cert.load_from_pyopenssl_x509( self.connection.get_peer_certificate()) generic = Generic.the_flavour() self.api = generic.make_api(peer_cert=peer_cert, interface=self.server.interface, key_file=self.server.key_file, cert_file=self.server.cert_file, cache=self.cache) #logger.info("SecureXMLRpcRequestHandler.do_POST:") #logger.info("interface=%s"%self.server.interface) #logger.info("key_file=%s"%self.server.key_file) #logger.info("api=%s"%self.api) #logger.info("server=%s"%self.server) #logger.info("handler=%s"%self) # get arguments request = self.rfile.read(int(self.headers["content-length"])) remote_addr = (remote_ip, remote_port) = self.connection.getpeername() self.api.remote_addr = remote_addr response = self.api.handle(remote_addr, request, self.server.method_map) except Exception, fault: # This should only happen if the module is buggy # internal error, report as HTTP server error logger.log_exc("server.do_POST") response = self.api.prepare_response(fault)
def testSign(self): cert = Certificate(subject="test") # create an issuer and sign the certificate issuerKey = Keypair(create=True) issuerSubject = "testissuer" cert.set_issuer(issuerKey, issuerSubject) cert.sign()
def test_parents(self): cert_root = Certificate(subject="root") key_root = Keypair(create=True) cert_root.set_pubkey(key_root) cert_root.set_issuer(key_root, "root") cert_root.sign() cert1 = Certificate(subject="one") key1 = Keypair(create=True) cert1.set_pubkey(key1) cert1.set_issuer(key_root, "root") cert1.sign() cert2 = Certificate(subject="two") key2 = Keypair(create=True) cert2.set_pubkey(key2) cert2.set_issuer(key1, cert=cert1) cert2.set_parent(cert1) cert2.sign() cert3 = Certificate(subject="three") key3 = Keypair(create=True) cert3.set_pubkey(key3) cert3.set_issuer(key2, cert=cert2) cert3.set_parent(cert2) cert3.sign() self.assert_(cert1.verify(key_root)) self.assert_(cert2.is_signed_by_cert(cert1)) self.assert_(cert3.is_signed_by_cert(cert2)) cert3.verify_chain([cert_root]) # now save the chain to a string and load it into a new certificate str_chain = cert3.save_to_string(save_parents=True) cert4 = Certificate(string = str_chain) # verify the newly loaded chain still verifies cert4.verify_chain([cert_root]) # verify the parentage self.assertEqual(cert4.get_parent().get_subject(), "two") self.assertEqual(cert4.get_parent().get_parent().get_subject(), "one")
def __init__(self, ip, port, key_file, cert_file, interface): threading.Thread.__init__(self) self.key = Keypair(filename=key_file) self.cert = Certificate(filename=cert_file) #self.server = SecureXMLRPCServer((ip, port), SecureXMLRpcRequestHandler, key_file, cert_file) self.server = ThreadedServer( (ip, int(port)), SecureXMLRpcRequestHandler, key_file, cert_file) self.server.interface = interface self.trusted_cert_list = None self.register_functions() logger.info("Starting SfaServer, interface=%s" % interface)
def CreateGid(self, api, xrn, cert): # get the authority authority = Xrn(xrn=xrn).get_authority_hrn() auth_info = api.auth.get_auth_info(authority) if not cert: pkey = Keypair(create=True) else: certificate = Certificate(string=cert) pkey = certificate.get_pubkey() gid = api.auth.hierarchy.create_gid(xrn, create_uuid(), pkey) return gid.save_to_string(save_parents=True)
def self_signed_cert_produce(self, output): self.assert_private_key() private_key_filename = self.private_key_filename() keypair = Keypair(filename=private_key_filename) self_signed = Certificate(subject=self.hrn) self_signed.set_pubkey(keypair) self_signed.set_issuer(keypair, self.hrn) self_signed.sign() self_signed.save_to_file(output) #self.logger.debug("SfaClientBootstrap: Created self-signed certificate for %s in %s"%\ #(self.hrn,output)) return output
def create_server_keypair(keyfile=None, certfile=None, hrn="component", verbose=False): """ create the server key/cert pair in the right place """ key = Keypair(filename=keyfile) key.save_to_file(keyfile) cert = Certificate(subject=hrn) cert.set_issuer(key=key, subject=hrn) cert.set_pubkey(key) cert.sign() cert.save_to_file(certfile, save_parents=True)
def test_is_signed_by(self): cert1 = Certificate(subject="one") key1 = Keypair() key1.create() cert1.set_pubkey(key1) # create an issuer and sign the certificate issuerKey = Keypair(create=True) issuerSubject = "testissuer" cert1.set_issuer(issuerKey, issuerSubject) cert1.sign() cert2 = Certificate(subject="two") key2 = Keypair(create=True) cert2.set_pubkey(key2) cert2.set_issuer(key1, cert=cert1) # cert2 is signed by cert1 self.assert_(cert2.is_signed_by_cert(cert1)) # cert1 is not signed by cert2 self.assert_(not cert1.is_signed_by_cert(cert2))
def get_node_key(self): # this call requires no authentication, # so we can generate a random keypair here subject = "component" (kfd, keyfile) = tempfile.mkstemp() (cfd, certfile) = tempfile.mkstemp() key = Keypair(create=True) key.save_to_file(keyfile) cert = Certificate(subject=subject) cert.set_issuer(key=key, subject=subject) cert.set_pubkey(key) cert.sign() cert.save_to_file(certfile) registry = self.get_registry() # the registry will scp the key onto the node registry.get_key_from_incoming_ip()
def get_node_key(registry=None, verbose=False): # this call requires no authentication, # so we can generate a random keypair here subject = "component" (kfd, keyfile) = tempfile.mkstemp() (cfd, certfile) = tempfile.mkstemp() key = Keypair(create=True) key.save_to_file(keyfile) cert = Certificate(subject=subject) cert.set_issuer(key=key, subject=subject) cert.set_pubkey(key) cert.sign() cert.save_to_file(certfile) registry = server_proxy(url=registry, keyfile=keyfile, certfile=certfile) registry.get_key_from_incoming_ip()
def GetCredential(registry=None, force=False, verbose=False): config = Config() hierarchy = Hierarchy() key_dir = hierarchy.basedir data_dir = config.data_path config_dir = config.config_path credfile = data_dir + os.sep + 'node.cred' # check for existing credential if not force and os.path.exists(credfile): if verbose: print "Loading Credential from %(credfile)s " % locals() cred = Credential(filename=credfile).save_to_string(save_parents=True) else: if verbose: print "Getting credential from registry" # make sure node private key exists node_pkey_file = config_dir + os.sep + "node.key" node_gid_file = config_dir + os.sep + "node.gid" if not os.path.exists(node_pkey_file) or \ not os.path.exists(node_gid_file): get_node_key(registry=registry, verbose=verbose) gid = GID(filename=node_gid_file) hrn = gid.get_hrn() # create server key and certificate keyfile = data_dir + os.sep + "server.key" certfile = data_dir + os.sep + "server.cert" key = Keypair(filename=node_pkey_file) key.save_to_file(keyfile) create_server_keypair(keyfile, certfile, hrn, verbose) # get credential from registry registry = server_proxy(url=registry, keyfile=keyfile, certfile=certfile) cert = Certificate(filename=certfile) cert_str = cert.save_to_string(save_parents=True) cred = registry.GetSelfCredential(cert_str, 'node', hrn) Credential(string=cred).save_to_file(credfile, save_parents=True) return cred
def __init__(self, encoding="utf-8", methods='sfa.methods', config="/etc/sfa/sfa_config", peer_cert=None, interface=None, key_file=None, cert_file=None, cache=None): XmlrpcApi.__init__(self, encoding) # we may be just be documenting the API if config is None: return # Load configuration self.config = Config(config) self.credential = None self.auth = Auth(peer_cert) self.interface = interface self.hrn = self.config.SFA_INTERFACE_HRN self.key_file = key_file self.key = Keypair(filename=self.key_file) self.cert_file = cert_file self.cert = Certificate(filename=self.cert_file) self.cache = cache if self.cache is None: self.cache = Cache() # load registries from sfa.server.registry import Registries self.registries = Registries() # load aggregates from sfa.server.aggregate import Aggregates self.aggregates = Aggregates() # filled later on by generic/Generic self.manager = None self._dbsession = None
def handle_input (filename, options): kind = determine_sfa_filekind(filename) # dump methods current do 'print' so let's go this road for now if kind=="certificate": cert=Certificate (filename=filename) print '--------------------',filename,'IS A',kind cert.dump(show_extensions=options.show_extensions) verify_input_object (cert, kind, options) elif kind=="credential": cred = Credential(filename = filename) print '--------------------',filename,'IS A',kind cred.dump(dump_parents = options.dump_parents, show_xml=options.show_xml) if options.extract_gids: print '--------------------',filename,'embedded GIDs' extract_gids(cred, extract_parents = options.dump_parents) verify_input_object (cred, kind, options) elif kind=="gid": gid = GID(filename = filename) print '--------------------',filename,'IS A',kind gid.dump(dump_parents = options.dump_parents) verify_input_object (gid, kind, options) else: print "%s: unknown filekind '%s'"% (filename,kind)
def authenticateCert(self, certStr, requestHash): cert = Certificate(string=certStr) # xxx should be validateCred ?? self.validateCred(cert)
def testCreate(self): cert = Certificate() cert.create()
def call(self, cert, xrn, type): """ GetSelfCredential a degenerate version of GetCredential used by a client to get his initial credential when de doesnt have one. This is the same as GetCredential(..., cred = None, ...) The registry ensures that the client is the principal that is named by (type, name) by comparing the public key in the record's GID to the private key used to encrypt the client side of the HTTPS connection. Thus it is impossible for one principal to retrieve another principal's credential without having the appropriate private key. @param type type of object (user | slice | sa | ma | node) @param hrn human readable name of authority to list @return string representation of a credential object """ if type: hrn = urn_to_hrn(xrn)[0] else: hrn, type = urn_to_hrn(xrn) self.api.auth.verify_object_belongs_to_me(hrn) origin_hrn = Certificate(string=cert).get_subject() self.api.logger.info( "interface: %s\tcaller-hrn: %s\ttarget-hrn: %s\tmethod-name: %s" % (self.api.interface, origin_hrn, hrn, self.name)) ### authenticate the gid # import here so we can load this module at build-time for sfa2wsdl #from sfa.storage.alchemy import dbsession from sfa.storage.model import RegRecord # xxx-local - the current code runs Resolve, which would forward to # another registry if needed # I wonder if this is truly the intention, or shouldn't we instead # only look in the local db ? records = self.api.manager.Resolve(self.api, xrn, type, details=False) if not records: raise RecordNotFound(hrn) record_obj = RegRecord(dict=records[0]) # xxx-local the local-only version would read #record_obj = dbsession.query(RegRecord).filter_by(hrn=hrn).first() #if not record_obj: raise RecordNotFound(hrn) gid = record_obj.get_gid_object() gid_str = gid.save_to_string(save_parents=True) self.api.auth.authenticateGid(gid_str, [cert, type, hrn]) # authenticate the certificate against the gid in the db certificate = Certificate(string=cert) if not certificate.is_pubkey(gid.get_pubkey()): for (obj, name) in [ (certificate, "CERT"), (gid, "GID"), ]: self.api.logger.debug( "ConnectionKeyGIDMismatch, %s pubkey: %s" % (name, obj.get_pubkey().get_pubkey_string())) self.api.logger.debug("ConnectionKeyGIDMismatch, %s dump: %s" % (name, obj.dump_string())) if hasattr(obj, 'filename'): self.api.logger.debug( "ConnectionKeyGIDMismatch, %s filename: %s" % (name, obj.filename)) raise ConnectionKeyGIDMismatch(gid.get_subject()) return self.api.manager.GetCredential(self.api, xrn, type)
def testAddExtension(self): cert = Certificate(subject="test") cert.add_extension("subjectAltName", 0, "URI:http://foovalue") self.assertEqual(cert.get_extension("subjectAltName"), "URI:http://foovalue")
def testSetAndGetSubject(self): cert = Certificate() cert.create() cert.set_subject("test") subj = cert.get_subject() self.assertEqual(subj, "test")