def get_keypair(config = None): if not config: config = SfaConfig() hierarchy = Hierarchy() key_dir= hierarchy.basedir data_dir = config.data_path keyfile =data_dir + os.sep + "server.key" certfile = data_dir + os.sep + "server.cert" # check if files already exist if os.path.exists(keyfile) and os.path.exists(certfile): return (keyfile, certfile) # create temp keypair server key and certificate (_, tmp_keyfile) = tempfile.mkstemp(suffix='.pkey', prefix='tmpkey', dir='/tmp') (_, tmp_certfile) = tempfile.mkstemp(suffix='.cert', prefix='tmpcert', dir='/tmp') tmp_key = Keypair(create=True) tmp_key.save_to_file(tmp_keyfile) tmp_cert = Certificate(subject='subject') tmp_cert.set_issuer(key=tmp_key, subject='subject') tmp_cert.set_pubkey(tmp_key) tmp_cert.save_to_file(tmp_certfile, save_parents=True) # request real pkey from registry api = ComponentAPI(key_file=tmp_keyfile, cert_file=tmp_certfile) registry = api.get_registry() registry.get_key() key = Keypair(filename=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) return (keyfile, certfile)
def init_person_key(self, person, iotlab_key): """ Returns a tuple pubkey and pkey. :param person Person's data. :type person: dict :param iotlab_key: SSH public key, from LDAP user's data. RSA type supported. :type iotlab_key: string :rtype: (string, Keypair) """ pubkey = None if person['pkey']: # randomly pick first key in set pubkey = iotlab_key try: pkey = convert_public_key(pubkey) except TypeError: #key not good. create another pkey self.logger.warn("IotlabImporter: \ unable to convert public \ key for %s" % person['hrn']) pkey = Keypair(create=True) else: # the user has no keys. #Creating a random keypair for the user's gid self.logger.warn("IotlabImporter: person %s does not have a \ public key" % (person['hrn'])) pkey = Keypair(create=True) return (pubkey, pkey)
def clean(self): """Check that the cert file is signed by the key file and is trusted.""" logger.debug("cleaned_data %s" % self.cleaned_data) if self.files: self.key = Keypair(string=self.files["key_file"].read()) self.cert = GID(string=self.files["cert_file"].read()) cert_pubkey = self.cert.get_pubkey().get_pubkey_string() if cert_pubkey != self.key.get_pubkey_string(): raise forms.ValidationError( "Error: The certificate was not signed " "by the uploaded key. Please use a key " "that matches the certificate.") try: certs = [GID(filename=f) for f in get_trusted_cert_filenames()] self.cert.verify_chain(certs) except Exception as e: logger.error(traceback.format_exc()) raise forms.ValidationError( "Could not verify that the uploaded certificate is " "trusted. This could be because none of the certificate's " "ancestors have been installed as trusted. The error was: " "%s" % e) return self.cleaned_data
def get_key_from_incoming_ip (self, api): dbsession=api.dbsession() # verify that the callers's ip address exist in the db and is an interface # for a node in the db (ip, port) = api.remote_addr interfaces = api.driver.shell.GetInterfaces({'ip': ip}, ['node_id']) if not interfaces: raise NonExistingRecord("no such ip %(ip)s" % locals()) nodes = api.driver.shell.GetNodes([interfaces[0]['node_id']], ['node_id', 'hostname']) if not nodes: raise NonExistingRecord("no such node using ip %(ip)s" % locals()) node = nodes[0] # look up the sfa record record=dbsession.query(RegRecord).filter_by(type='node',pointer=node['node_id']).first() if not record: raise RecordNotFound("node with pointer %s"%node['node_id']) # generate a new keypair and gid uuid = create_uuid() pkey = Keypair(create=True) urn = hrn_to_urn(record.hrn, record.type) gid_object = api.auth.hierarchy.create_gid(urn, uuid, pkey) gid = gid_object.save_to_string(save_parents=True) record.gid = gid # update the record dbsession.commit() # attempt the scp the key # and gid onto the node # this will only work for planetlab based components (kfd, key_filename) = tempfile.mkstemp() (gfd, gid_filename) = tempfile.mkstemp() pkey.save_to_file(key_filename) gid_object.save_to_file(gid_filename, save_parents=True) host = node['hostname'] key_dest="/etc/sfa/node.key" gid_dest="/etc/sfa/node.gid" scp = "/usr/bin/scp" #identity = "/etc/planetlab/root_ssh_key.rsa" identity = "/etc/sfa/root_ssh_key" scp_options=" -i %(identity)s " % locals() scp_options+="-o StrictHostKeyChecking=no " % locals() scp_key_command="%(scp)s %(scp_options)s %(key_filename)s root@%(host)s:%(key_dest)s" %\ locals() scp_gid_command="%(scp)s %(scp_options)s %(gid_filename)s root@%(host)s:%(gid_dest)s" %\ locals() all_commands = [scp_key_command, scp_gid_command] for command in all_commands: (status, output) = commands.getstatusoutput(command) if status: raise Exception, output for filename in [key_filename, gid_filename]: os.unlink(filename) return 1
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 import_users(self, existing_hrns, existing_records): # Get all users users = self.shell.auth_manager.users.list() users_dict = {} keys_filename = self.config.config_path + os.sep + 'person_keys.py' old_user_keys = load_keys(keys_filename) user_keys = {} for user in users: auth_hrn = self.config.SFA_INTERFACE_HRN if user.tenantId is not None: tenant = self.shell.auth_manager.tenants.find(id=user.tenantId) auth_hrn = OSXrn(name=tenant.name, auth=self.config.SFA_INTERFACE_HRN, type='authority').get_hrn() hrn = OSXrn(name=user.name, auth=auth_hrn, type='user').get_hrn() users_dict[hrn] = user old_keys = old_user_keys.get(hrn, []) keyname = OSXrn(xrn=hrn, type='user').get_slicename() keys = [ k.public_key for k in self.shell.nova_manager.keypairs.findall(name=keyname) ] user_keys[hrn] = keys update_record = False if old_keys != keys: update_record = True if hrn not in existing_hrns or \ (hrn, 'user') not in existing_records or update_record: urn = OSXrn(xrn=hrn, type='user').get_urn() if keys: try: pkey = convert_public_key(keys[0]) except: self.logger.log_exc( 'unable to convert public key for %s' % hrn) pkey = Keypair(create=True) else: self.logger.warn( "OpenstackImporter: person %s does not have a PL public key" % hrn) pkey = Keypair(create=True) user_gid = self.auth_hierarchy.create_gid(urn, create_uuid(), pkey, email=user.email) user_record = RegUser() user_record.type = 'user' user_record.hrn = hrn user_record.gid = user_gid user_record.authority = get_authority(hrn) global_dbsession.add(user_record) global_dbsession.commit() self.logger.info("OpenstackImporter: imported person %s" % user_record) return users_dict, user_keys
def testSaveLoadFile(self): k = Keypair() k.create() k.save_to_file("test.key") k2 = Keypair() k2.load_from_file("test.key") self.assertEqual(k.as_pem(), k2.as_pem())
class UploadCertForm(forms.Form): """Form to upload a certificate and its corresponding key.""" key_file = forms.FileField( help_text="Select the file that contains the key for the "\ "certificate to upload.") cert_file = forms.FileField( help_text="Select the file that contains the "\ "certificate to upload. The certificate must be signed "\ "with the uploaded key.") clean_key_file = _clean_x_file_factory("key") clean_cert_file = _clean_x_file_factory("cert") def clean(self): """Check that the cert file is signed by the key file and is trusted.""" logger.debug("cleaned_data %s" % self.cleaned_data) if self.files: self.key = Keypair(string=self.files["key_file"].read()) self.cert = GID(string=self.files["cert_file"].read()) cert_pubkey = self.cert.get_pubkey().get_pubkey_string() if cert_pubkey != self.key.get_pubkey_string(): raise forms.ValidationError( "Error: The certificate was not signed " "by the uploaded key. Please use a key " "that matches the certificate.") try: certs = [GID(filename=f) for f in get_trusted_cert_filenames()] self.cert.verify_chain(certs) except Exception as e: logger.error(traceback.format_exc()) raise forms.ValidationError( "Could not verify that the uploaded certificate is " "trusted. This could be because none of the certificate's " "ancestors have been installed as trusted. The error was: " "%s" % e ) return self.cleaned_data def save(self, user): """Write the key and cert into files. @param user: the user to save the cert and key for. @type user: C{django.contrib.auth.models.User} """ key_fname = get_user_key_fname(user) cert_fname = get_user_cert_fname(user) self.key.save_to_file(key_fname) self.cert.save_to_file(cert_fname)
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)
class UploadCertForm(forms.Form): """Form to upload a certificate and its corresponding key.""" key_file = forms.FileField( help_text="Select the file that contains the key for the "\ "certificate to upload.") cert_file = forms.FileField( help_text="Select the file that contains the "\ "certificate to upload. The certificate must be signed "\ "with the uploaded key.") clean_key_file = _clean_x_file_factory("key") clean_cert_file = _clean_x_file_factory("cert") def clean(self): """Check that the cert file is signed by the key file and is trusted.""" logger.debug("cleaned_data %s" % self.cleaned_data) if self.files: self.key = Keypair(string=self.files["key_file"].read()) self.cert = GID(string=self.files["cert_file"].read()) cert_pubkey = self.cert.get_pubkey().get_pubkey_string() if cert_pubkey != self.key.get_pubkey_string(): raise forms.ValidationError( "Error: The certificate was not signed " "by the uploaded key. Please use a key " "that matches the certificate.") try: certs = [GID(filename=f) for f in get_trusted_cert_filenames()] self.cert.verify_chain(certs) except Exception as e: logger.error(traceback.format_exc()) raise forms.ValidationError( "Could not verify that the uploaded certificate is " "trusted. This could be because none of the certificate's " "ancestors have been installed as trusted. The error was: " "%s" % e) return self.cleaned_data def save(self, user): """Write the key and cert into files. @param user: the user to save the cert and key for. @type user: C{django.contrib.auth.models.User} """ key_fname = get_user_key_fname(user) cert_fname = get_user_cert_fname(user) self.key.save_to_file(key_fname) self.cert.save_to_file(cert_fname)
def create_cert(urn, issuer_key=None, issuer_cert=None, ca=False, public_key=None, lifeDays=1825, email=None): '''Create a new certificate and return it and the associated keys. If issuer cert and key are given, they sign the certificate. Otherwise it is a self-signed certificate. If ca then mark this as a CA certificate (can sign other certs). lifeDays is the lifetime of the supplied cert - default is 1825 (5 years). Certificate URN must be supplied. CN of the cert will be dotted notation authority.type.name from the URN. ''' # Note the below throws a ValueError if it wasnt a valid URN c_urn = URN(urn=urn) dotted = '%s.%s.%s' % (c_urn.getAuthority(), c_urn.getType(), c_urn.getName()) subject = dict() subject['CN'] = dotted[:64] if email: subject['emailAddress'] = email newgid = GID(create=True, subject=subject, urn=urn, lifeDays=lifeDays) if public_key is None: # create a new key pair keys = Keypair(create=True) else: # use the specified public key file keys = Keypair() keys.load_pubkey_from_file(public_key) newgid.set_pubkey(keys) newgid.set_is_ca(ca) if issuer_key and issuer_cert: # the given issuer will issue this cert if isinstance(issuer_key,str): issuer_key = Keypair(filename=issuer_key) if isinstance(issuer_cert,str): issuer_cert = GID(filename=issuer_cert) newgid.set_issuer(issuer_key, cert=issuer_cert) newgid.set_parent(issuer_cert) else: # create a self-signed cert newgid.set_issuer(keys, subject=dotted) newgid.encode() newgid.sign() return newgid, keys
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 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(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 clean(self): """Check that the cert file is signed by the key file and is trusted.""" logger.debug("cleaned_data %s" % self.cleaned_data) if self.files: self.key = Keypair(string=self.files["key_file"].read()) self.cert = GID(string=self.files["cert_file"].read()) cert_pubkey = self.cert.get_pubkey().get_pubkey_string() if cert_pubkey != self.key.get_pubkey_string(): raise forms.ValidationError( "Error: The certificate was not signed " "by the uploaded key. Please use a key " "that matches the certificate.") try: certs = [GID(filename=f) for f in get_trusted_cert_filenames()] self.cert.verify_chain(certs) except Exception as e: logger.error(traceback.format_exc()) raise forms.ValidationError( "Could not verify that the uploaded certificate is " "trusted. This could be because none of the certificate's " "ancestors have been installed as trusted. The error was: " "%s" % e ) return self.cleaned_data
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 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 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 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_sign_verify(self): k = Keypair() k.create() data = "this is a test" sig = k.sign_string(data) print k.verify_string(data, sig)
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_person_key(person, plc_keys): pubkey = None if person['key_ids']: # randomly pick first key in set pubkey = plc_keys[0] try: pkey = convert_public_key(pubkey['key']) except: self.logger.warn( 'PlImporter: unable to convert public key for %s' % person_hrn) pkey = Keypair(create=True) else: # the user has no keys. Creating a random keypair for the user's gid self.logger.warn( "PlImporter: person %s does not have a PL public key" % person_hrn) pkey = Keypair(create=True) return (pubkey, pkey)
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 init_user_key (user): pubkey = None pkey = None if user['keys']: # randomly pick first key in set for key in user['keys']: pubkey = key try: pkey = convert_public_key(pubkey) break except: continue if not pkey: self.logger.warn('DummyImporter: unable to convert public key for %s' % user_hrn) pkey = Keypair(create=True) else: # the user has no keys. Creating a random keypair for the user's gid self.logger.warn("DummyImporter: user %s does not have a NITOS public key"%user_hrn) pkey = Keypair(create=True) return (pubkey, pkey)
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 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 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_cert(urn, issuer_key=None, issuer_cert=None, intermediate=False): '''Create a new certificate and return it and the associated keys. If issuer cert and key are given, they sign the certificate. Otherwise it is a self-signed certificate. If intermediate then mark this as an intermediate CA certificate (can sign). Certificate URN must be supplied. CN of the cert will be dotted notation authority.type.name from the URN. ''' # Note the below throws a ValueError if it wasnt a valid URN c_urn = URN(urn=urn) dotted = '%s.%s.%s' % (c_urn.getAuthority(), c_urn.getType(), c_urn.getName()) newgid = GID(create=True, subject=dotted[:64], urn=urn) keys = Keypair(create=True) newgid.set_pubkey(keys) if intermediate: # This cert will be able to sign certificates newgid.set_intermediate_ca(intermediate) if issuer_key and issuer_cert: # the given issuer will issue this cert if isinstance(issuer_key, str): issuer_key = Keypair(filename=issuer_key) if isinstance(issuer_cert, str): issuer_cert = GID(filename=issuer_cert) newgid.set_issuer(issuer_key, cert=issuer_cert) newgid.set_parent(issuer_cert) else: # create a self-signed cert newgid.set_issuer(keys, subject=dotted) newgid.encode() newgid.sign() return newgid, keys
def create_cert(urn, issuer_key=None, issuer_cert=None, ca=False, public_key=None, lifeDays=1825, email=None): '''Create a new certificate and return it and the associated keys. If issuer cert and key are given, they sign the certificate. Otherwise it is a self-signed certificate. If ca then mark this as a CA certificate (can sign other certs). lifeDays is the lifetime of the supplied cert - default is 1825 (5 years). Certificate URN must be supplied. CN of the cert will be dotted notation authority.type.name from the URN. ''' # Note the below throws a ValueError if it wasnt a valid URN c_urn = URN(urn=urn) dotted = '%s.%s.%s' % (c_urn.getAuthority(), c_urn.getType(), c_urn.getName()) subject = dict() subject['CN'] = dotted[:64] if email: subject['emailAddress'] = email newgid = GID(create=True, subject=subject, urn=urn, lifeDays=lifeDays) if public_key is None: # create a new key pair keys = Keypair(create=True) else: # use the specified public key file keys = Keypair() keys.load_pubkey_from_file(public_key) newgid.set_pubkey(keys) newgid.set_is_ca(ca) if issuer_key and issuer_cert: # the given issuer will issue this cert if isinstance(issuer_key, str): issuer_key = Keypair(filename=issuer_key) if isinstance(issuer_cert, str): issuer_cert = GID(filename=issuer_cert) newgid.set_issuer(issuer_key, cert=issuer_cert) newgid.set_parent(issuer_cert) else: # create a self-signed cert newgid.set_issuer(keys, subject=dotted) newgid.encode() newgid.sign() return newgid, keys
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 import_slice(self, slice_hrn, slice_record, user_record): """ Create RegSlice record according to the slice hrn if the slice does not exist yet.Creates a relationship with the user record associated with the slice. Commit the record to the database. :param slice_hrn: Human readable name of the slice. :type slice_hrn: string :param slice_record: record of the slice found in the DB, if any. :type slice_record: RegSlice or None :param user_record: user record found in the DB if any. :type user_record: RegUser .. todo::Update the record if a slice record already exists. """ if not slice_record: pkey = Keypair(create=True) urn = hrn_to_urn(slice_hrn, 'slice') slice_gid = \ self.auth_hierarchy.create_gid(urn, create_uuid(), pkey) slice_record = RegSlice(hrn=slice_hrn, gid=slice_gid, pointer='-1', authority=get_authority(slice_hrn)) try: slice_record.just_created() global_dbsession.add(slice_record) global_dbsession.commit() self.update_just_added_records_dict(slice_record) except SQLAlchemyError: self.logger.log_exc("IotlabImporter: failed to import slice") #No slice update upon import in iotlab else: # xxx update the record ... self.logger.warning("Iotlab Slice update not implemented") # record current users affiliated with the slice slice_record.reg_researchers = [user_record] try: global_dbsession.commit() slice_record.stale = False except SQLAlchemyError: self.logger.log_exc("IotlabImporter: failed to update slice")
def import_tenants(self, existing_hrns, existing_records): # Get all tenants # A tenant can represent an organizational group (site) or a # slice. If a tenant's authorty/parent matches the root authority it is # considered a group/site. All other tenants are considered slices. tenants = self.shell.auth_manager.tenants.list() tenants_dict = {} for tenant in tenants: hrn = self.config.SFA_INTERFACE_HRN + '.' + tenant.name tenants_dict[hrn] = tenant authority_hrn = OSXrn(xrn=hrn, type='authority').get_authority_hrn() if hrn in existing_hrns: continue if authority_hrn == self.config.SFA_INTERFACE_HRN: # import group/site record = RegAuthority() urn = OSXrn(xrn=hrn, type='authority').get_urn() if not self.auth_hierarchy.auth_exists(urn): self.auth_hierarchy.create_auth(urn) auth_info = self.auth_hierarchy.get_auth_info(urn) gid = auth_info.get_gid_object() record.type = 'authority' record.hrn = hrn record.gid = gid record.authority = get_authority(hrn) global_dbsession.add(record) global_dbsession.commit() self.logger.info("OpenstackImporter: imported authority: %s" % record) else: record = RegSlice() urn = OSXrn(xrn=hrn, type='slice').get_urn() pkey = Keypair(create=True) gid = self.auth_hierarchy.create_gid(urn, create_uuid(), pkey) record.type = 'slice' record.hrn = hrn record.gid = gid record.authority = get_authority(hrn) global_dbsession.add(record) global_dbsession.commit() self.logger.info("OpenstackImporter: imported slice: %s" % record) return tenants_dict
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 init_server_key(server_key_file, server_cert_file, config, hierarchy): hrn = config.SFA_INTERFACE_HRN.lower() # check if the server's private key exists. If it doesnt, # get the right one from the authorities directory. If it cant be # found in the authorities directory, generate a random one if not os.path.exists(server_key_file): hrn = config.SFA_INTERFACE_HRN.lower() hrn_parts = hrn.split(".") rel_key_path = hrn pkey_filename = hrn + ".pkey" # sub authority's have "." in their hrn. This must # be converted to os.path separator if len(hrn_parts) > 0: rel_key_path = hrn.replace(".", os.sep) pkey_filename = hrn_parts[-1] + ".pkey" key_file = os.sep.join([hierarchy.basedir, rel_key_path, pkey_filename]) if not os.path.exists(key_file): # if it doesnt exist then this is probably a fresh interface # with no records. Generate a random keypair for now logger.debug("server's public key not found in %s" % key_file) logger.debug("generating a random server key pair") key = Keypair(create=True) key.save_to_file(server_key_file) init_server_cert(hrn, key, server_cert_file, self_signed=True) else: # the pkey was found in the authorites directory. lets # copy it to where the server key should be and generate # the cert key = Keypair(filename=key_file) key.save_to_file(server_key_file) init_server_cert(hrn, key, server_cert_file) # If private key exists and cert doesnt, recreate cert if (os.path.exists(server_key_file)) and (not os.path.exists(server_cert_file)): key = Keypair(filename=server_key_file) init_server_cert(hrn, key, server_cert_file)
def testSaveAndLoadString(self): gid = GID(subject="test") u = uuid.uuid4().int hrn = "test.hrn" gid.set_uuid(u) gid.set_hrn(hrn) # create an issuer and sign the certificate issuerKey = Keypair(create=True) issuerSubject = "testissuer" gid.set_issuer(issuerKey, issuerSubject) gid.sign() certstr = gid.save_to_string() #print certstr gid2 = GID(string=certstr) self.assertEqual(gid.get_hrn(), hrn) self.assertEqual(gid.get_uuid(), u)
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_pkey_object(self): return Keypair(filename = self.privkey_filename)
def test_get_m2_pkey(self): k = Keypair() k.create() m2 = k.get_m2_pkey() self.assert_(m2 != None)
def test_get_openssl_pkey(self): k = Keypair() k.create() pk = k.get_openssl_pkey() self.assert_(pk != None)
def import_nodes(self, site_node_ids, nodes_by_id, testbed_shell): """ Creates appropriate hostnames and RegNode records for each node in site_node_ids, based on the information given by the dict nodes_by_id that was made from data from OAR. Saves the records to the DB. :param site_node_ids: site's node ids :type site_node_ids: list of integers :param nodes_by_id: dictionary , key is the node id, value is the a dict with node information. :type nodes_by_id: dictionary :param testbed_shell: IotlabDriver object, used to have access to testbed_shell attributes. :type testbed_shell: IotlabDriver :returns: None :rtype: None """ for node_id in site_node_ids: try: node = nodes_by_id[node_id] except KeyError: self.logger.warning("IotlabImporter: cannot find node_id %s \ - ignored" % (node_id)) continue escaped_hrn = \ self.hostname_to_hrn_escaped(testbed_shell.root_auth, node['hostname']) self.logger.info("IOTLABIMPORTER node %s " % (node)) hrn = node['hrn'] # xxx this sounds suspicious if len(hrn) > 64: hrn = hrn[:64] node_record = self.find_record_by_type_hrn('node', hrn) if not node_record: pkey = Keypair(create=True) urn = hrn_to_urn(escaped_hrn, 'node') node_gid = \ self.auth_hierarchy.create_gid(urn, create_uuid(), pkey) def testbed_get_authority(hrn): """ Gets the authority part in the hrn. :param hrn: hrn whose authority we are looking for. :type hrn: string :returns: splits the hrn using the '.' separator and returns the authority part of the hrn. :rtype: string """ return hrn.split(".")[0] node_record = RegNode(hrn=hrn, gid=node_gid, pointer='-1', authority=testbed_get_authority(hrn)) try: node_record.just_created() global_dbsession.add(node_record) global_dbsession.commit() self.logger.info("IotlabImporter: imported node: %s" % node_record) self.update_just_added_records_dict(node_record) except SQLAlchemyError: self.logger.log_exc( "IotlabImporter: failed to import node") else: #TODO: xxx update the record ... pass node_record.stale = False
def testCreate(self): k = Keypair() k.create()
def call(self): # verify that the callers's ip address exist in the db and is an inteface # for a node in the db (ip, port) = self.api.remote_addr interfaces = self.api.plshell.GetInterfaces(self.api.plauth, {'ip': ip}, ['node_id']) if not interfaces: raise NonExistingRecord("no such ip %(ip)s" % locals()) nodes = self.api.plshell.GetNodes(self.api.plauth, [interfaces[0]['node_id']], ['node_id', 'hostname']) if not nodes: raise NonExistingRecord("no such node using ip %(ip)s" % locals()) node = nodes[0] # look up the sfa record table = SfaTable() records = table.findObjects({'type': 'node', 'pointer': node['node_id']}) if not records: raise RecordNotFound("pointer:" + str(node['node_id'])) record = records[0] # generate a new keypair and gid uuid = create_uuid() pkey = Keypair(create=True) urn = hrn_to_urn(record['hrn'], record['type']) gid_object = self.api.auth.hierarchy.create_gid(urn, uuid, pkey) gid = gid_object.save_to_string(save_parents=True) record['gid'] = gid record.set_gid(gid) # update the record table.update(record) # attempt the scp the key # and gid onto the node # this will only work for planetlab based components (kfd, key_filename) = tempfile.mkstemp() (gfd, gid_filename) = tempfile.mkstemp() pkey.save_to_file(key_filename) gid_object.save_to_file(gid_filename, save_parents=True) host = node['hostname'] key_dest="/etc/sfa/node.key" gid_dest="/etc/sfa/node.gid" scp = "/usr/bin/scp" #identity = "/etc/planetlab/root_ssh_key.rsa" identity = "/etc/sfa/root_ssh_key" scp_options=" -i %(identity)s " % locals() scp_options+="-o StrictHostKeyChecking=no " % locals() scp_key_command="%(scp)s %(scp_options)s %(key_filename)s root@%(host)s:%(key_dest)s" %\ locals() scp_gid_command="%(scp)s %(scp_options)s %(gid_filename)s root@%(host)s:%(gid_dest)s" %\ locals() all_commands = [scp_key_command, scp_gid_command] for command in all_commands: (status, output) = commands.getstatusoutput(command) if status: raise Exception, output for filename in [key_filename, gid_filename]: os.unlink(filename) return 1
def run (self, options): config = Config () interface_hrn = config.SFA_INTERFACE_HRN root_auth = config.SFA_REGISTRY_ROOT_AUTH shell = DummyShell (config) ######## retrieve all existing SFA objects all_records = global_dbsession.query(RegRecord).all() # create hash by (type,hrn) # we essentially use this to know if a given record is already known to SFA self.records_by_type_hrn = \ dict ( [ ( (record.type, record.hrn) , record ) for record in all_records ] ) # create hash by (type,pointer) self.records_by_type_pointer = \ dict ( [ ( (record.type, record.pointer) , record ) for record in all_records if record.pointer != -1] ) # initialize record.stale to True by default, then mark stale=False on the ones that are in use for record in all_records: record.stale=True # DEBUG #all_records = global_dbsession.query(RegRecord).all() #for record in all_records: print record ######## retrieve Dummy TB data # Get all plc sites # retrieve only required stuf sites = [shell.GetTestbedInfo()] print "sites: " + sites # create a hash of sites by login_base # sites_by_login_base = dict ( [ ( site['login_base'], site ) for site in sites ] ) # Get all dummy TB users users = shell.GetUsers() # create a hash of users by user_id users_by_id = dict ( [ ( user['user_id'], user) for user in users ] ) # Get all dummy TB public keys keys = [] for user in users: if 'keys' in user: keys.extend(user['keys']) # create a dict user_id -> [ keys ] keys_by_person_id = {} for user in users: if 'keys' in user: keys_by_person_id[user['user_id']] = user['keys'] # Get all dummy TB nodes nodes = shell.GetNodes() # create hash by node_id nodes_by_id = dict ( [ ( node['node_id'], node, ) for node in nodes ] ) # Get all dummy TB slices slices = shell.GetSlices() # create hash by slice_id slices_by_id = dict ( [ (slice['slice_id'], slice ) for slice in slices ] ) # start importing print " STARTING FOR SITES" for site in sites: site_hrn = _get_site_hrn(interface_hrn, site) # import if hrn is not in list of existing hrns or if the hrn exists # but its not a site record site_record=self.locate_by_type_hrn ('authority', site_hrn) print site_hrn print site_record if not site_record: try: print "TRY TO CREATE SITE RECORD" urn = hrn_to_urn(site_hrn, 'authority') if not self.auth_hierarchy.auth_exists(urn): print "create auth "+urn self.auth_hierarchy.create_auth(urn) auth_info = self.auth_hierarchy.get_auth_info(urn) site_record = RegAuthority(hrn=site_hrn, gid=auth_info.get_gid_object(), pointer= -1, authority=get_authority(site_hrn)) site_record.just_created() print "urn: "+urn print "auth_info: " + auth_info print site_record global_dbsession.add(site_record) global_dbsession.commit() self.logger.info("DummyImporter: imported authority (site) : %s" % site_record) self.remember_record (site_record) except: # if the site import fails then there is no point in trying to import the # site's child records (node, slices, persons), so skip them. self.logger.log_exc("DummyImporter: failed to import site. Skipping child records") continue else: # xxx update the record ... pass site_record.stale=False # import node records for node in nodes: site_auth = get_authority(site_hrn) site_name = site['name'] node_hrn = hostname_to_hrn(site_auth, site_name, node['hostname']) # xxx this sounds suspicious if len(node_hrn) > 64: node_hrn = node_hrn[:64] node_record = self.locate_by_type_hrn ( 'node', node_hrn ) if not node_record: try: pkey = Keypair(create=True) urn = hrn_to_urn(node_hrn, 'node') node_gid = self.auth_hierarchy.create_gid(urn, create_uuid(), pkey) node_record = RegNode (hrn=node_hrn, gid=node_gid, pointer =node['node_id'], authority=get_authority(node_hrn)) node_record.just_created() global_dbsession.add(node_record) global_dbsession.commit() self.logger.info("DummyImporter: imported node: %s" % node_record) self.remember_record (node_record) except: self.logger.log_exc("DummyImporter: failed to import node") else: # xxx update the record ... pass node_record.stale=False all_records = global_dbsession.query(RegRecord).all() for record in all_records: print record site_pis=[] # import users for user in users: user_hrn = email_to_hrn(site_hrn, user['email']) # xxx suspicious again if len(user_hrn) > 64: user_hrn = user_hrn[:64] user_urn = hrn_to_urn(user_hrn, 'user') user_record = self.locate_by_type_hrn ( 'user', user_hrn) # return a tuple pubkey (a dummy TB key object) and pkey (a Keypair object) def init_user_key (user): pubkey = None pkey = None if user['keys']: # randomly pick first key in set for key in user['keys']: pubkey = key try: pkey = convert_public_key(pubkey) break except: continue if not pkey: self.logger.warn('DummyImporter: unable to convert public key for %s' % user_hrn) pkey = Keypair(create=True) else: # the user has no keys. Creating a random keypair for the user's gid self.logger.warn("DummyImporter: user %s does not have a NITOS public key"%user_hrn) pkey = Keypair(create=True) return (pubkey, pkey) # new user try: if not user_record: (pubkey,pkey) = init_user_key (user) user_gid = self.auth_hierarchy.create_gid(user_urn, create_uuid(), pkey) user_gid.set_email(user['email']) user_record = RegUser (hrn=user_hrn, gid=user_gid, pointer=user['user_id'], authority=get_authority(user_hrn), email=user['email']) if pubkey: user_record.reg_keys=[RegKey (pubkey)] else: self.logger.warning("No key found for user %s"%user_record) user_record.just_created() global_dbsession.add (user_record) global_dbsession.commit() self.logger.info("DummyImporter: imported person: %s" % user_record) self.remember_record ( user_record ) else: # update the record ? # if user's primary key has changed then we need to update the # users gid by forcing an update here sfa_keys = user_record.reg_keys def key_in_list (key,sfa_keys): for reg_key in sfa_keys: if reg_key.key==key: return True return False # is there a new key in Dummy TB ? new_keys=False for key in user['keys']: if not key_in_list (key,sfa_keys): new_keys = True if new_keys: (pubkey,pkey) = init_user_key (user) user_gid = self.auth_hierarchy.create_gid(user_urn, create_uuid(), pkey) if not pubkey: user_record.reg_keys=[] else: user_record.reg_keys=[ RegKey (pubkey)] self.logger.info("DummyImporter: updated person: %s" % user_record) user_record.email = user['email'] global_dbsession.commit() user_record.stale=False except: self.logger.log_exc("DummyImporter: failed to import user %d %s"%(user['user_id'],user['email'])) # import slices for slice in slices: slice_hrn = slicename_to_hrn(site_hrn, slice['slice_name']) slice_record = self.locate_by_type_hrn ('slice', slice_hrn) if not slice_record: try: pkey = Keypair(create=True) urn = hrn_to_urn(slice_hrn, 'slice') slice_gid = self.auth_hierarchy.create_gid(urn, create_uuid(), pkey) slice_record = RegSlice (hrn=slice_hrn, gid=slice_gid, pointer=slice['slice_id'], authority=get_authority(slice_hrn)) slice_record.just_created() global_dbsession.add(slice_record) global_dbsession.commit() self.logger.info("DummyImporter: imported slice: %s" % slice_record) self.remember_record ( slice_record ) except: self.logger.log_exc("DummyImporter: failed to import slice") else: # xxx update the record ... self.logger.warning ("Slice update not yet implemented") pass # record current users affiliated with the slice slice_record.reg_researchers = \ [ self.locate_by_type_pointer ('user',user_id) for user_id in slice['user_ids'] ] global_dbsession.commit() slice_record.stale=False ### remove stale records # special records must be preserved system_hrns = [interface_hrn, root_auth, interface_hrn + '.slicemanager'] for record in all_records: if record.hrn in system_hrns: record.stale=False if record.peer_authority: record.stale=False for record in all_records: try: stale=record.stale except: stale=True self.logger.warning("stale not found with %s"%record) if stale: self.logger.info("DummyImporter: deleting stale record: %s" % record) global_dbsession.delete(record) global_dbsession.commit()
class Hierarchy: ## # Create the hierarchy object. # # @param basedir the base directory to store the hierarchy in def __init__(self, basedir = None): self.config = Config() if not basedir: basedir = os.path.join(self.config.SFA_DATA_DIR, "authorities") self.basedir = basedir ## # Given a hrn, return the filenames of the GID, private key # files. # # @param xrn the human readable name of the authority (urn will be convertd to hrn) def get_auth_filenames(self, xrn): hrn, type = urn_to_hrn(xrn) if '\\' in hrn: hrn = hrn.replace('\\', '') leaf = hrn else: leaf = get_leaf(hrn) parent_hrn = get_authority(hrn) directory = os.path.join(self.basedir, hrn.replace(".", "/")) gid_filename = os.path.join(directory, leaf+".gid") privkey_filename = os.path.join(directory, leaf+".pkey") return (directory, gid_filename, privkey_filename) ## # Check to see if an authority exists. An authority exists if it's disk # files exist. # # @param the human readable name of the authority to check def auth_exists(self, xrn): hrn, type = urn_to_hrn(xrn) (directory, gid_filename, privkey_filename) = \ self.get_auth_filenames(hrn) return os.path.exists(gid_filename) and os.path.exists(privkey_filename) ## # Create an authority. A private key for the authority and the associated # GID are created and signed by the parent authority. # # @param xrn the human readable name of the authority to create (urn will be converted to hrn) # @param create_parents if true, also create the parents if they do not exist def create_auth(self, xrn, create_parents=False): hrn, type = urn_to_hrn(str(xrn)) logger.debug("Hierarchy: creating authority: %s"% hrn) # create the parent authority if necessary parent_hrn = get_authority(hrn) parent_urn = hrn_to_urn(parent_hrn, 'authority') if (parent_hrn) and (not self.auth_exists(parent_urn)) and (create_parents): self.create_auth(parent_urn, create_parents) (directory, gid_filename, privkey_filename,) = \ self.get_auth_filenames(hrn) # create the directory to hold the files try: os.makedirs(directory) # if the path already exists then pass except OSError, (errno, strerr): if errno == 17: pass if os.path.exists(privkey_filename): logger.debug("using existing key %r for authority %r"%(privkey_filename,hrn)) pkey = Keypair(filename = privkey_filename) else: pkey = Keypair(create = True) pkey.save_to_file(privkey_filename) gid = self.create_gid(xrn, create_uuid(), pkey) gid.save_to_file(gid_filename, save_parents=True)