예제 #1
0
def _create_CA_and_rehash(domain_name, credentials_testdir, NBR_OF_RUNTIMES):
    from calvin.utilities import certificate
    from calvin.utilities import certificate_authority
    runtimesdir = os.path.join(credentials_testdir, "runtimes")
    runtimes_truststore = os.path.join(runtimesdir, "truststore_for_transport")
    print "Trying to create a new test domain configuration."
    ca = certificate_authority.CA(domain=domain_name,
                                  commonName="testdomain CA",
                                  security_dir=credentials_testdir)

    print "Copy CA cert into truststore of runtimes folder"
    ca.export_ca_cert(runtimes_truststore)
    certificate.c_rehash(type=certificate.TRUSTSTORE_TRANSPORT,
                         security_dir=credentials_testdir)
    runtimes = []
    for i in range(NBR_OF_RUNTIMES):
        runtimes.append({})
    #Define the runtime attributes
    _runtime_attributes(domain_name, runtimes)
    _get_node_names(runtimes)
    for i in range(NBR_OF_RUNTIMES):
        node_name = runtimes[i]["node_name"]
        if "testNode0" in node_name:
            ca.add_new_authentication_server(node_name)
            ca.add_new_authorization_server(node_name)
    return runtimes, ca
예제 #2
0
def manage_ca_create(args):
    if not args.domain:
        raise Exception("No domain supplied")
    certificate_authority.CA(domain=args.domain,
                             commonName=args.domain + " CA",
                             security_dir=args.dir,
                             force=args.force)
예제 #3
0
def manage_ca_export(args):
    if not args.domain:
        raise Exception("No domain supplied")
    if not args.path:
        raise Exception("No out path supplied")
    ca = certificate_authority.CA(domain=args.domain, security_dir=args.dir, readonly=True)
    out_file = ca.export_ca_cert(args.path)
    print "exported to:" + out_file
예제 #4
0
def manage_ca_sign_csr(args):
    if args.domain and args.CSR:
        if not args.domain:
            raise Exception("No domain supplied")
        if not args.CSR:
            raise Exception("supply CSR path")
        exist = os.path.isfile(args.CSR)
        if not exist:
            raise Exception("The CSR path supplied is not an existing file")
        ca = certificate_authority.CA(domain=args.domain, security_dir=args.dir, force=args.force)
        ca.sign_csr(args.CSR)
예제 #5
0
def manage_ca_get_enrollment_password(args):
    if args.domain and args.node_name:
        if not args.domain:
            raise Exception("No domain supplied")
        if not args.node_name:
            raise Exception("supply node name")
        ca = certificate_authority.CA(domain=args.domain,
                                      security_dir=args.dir,
                                      force=args.force)
        enrollment_password = ca.cert_enrollment_add_new_runtime(
            args.node_name)
        print "enrollment_password_start<{}>enrollment_password_stop".format(
            enrollment_password)
예제 #6
0
def manage_ca_sign_csr(args):
    if not args.domain:
        raise Exception("No domain supplied")
    if not args.CSR:
        raise exception("supply path to CSR")
    exist = os.path.isfile(args.CSR)
    if not exist:
        raise Exception("The CSR path supplied is not an existing file")
    ca = certificate_authority.CA(domain=args.domain,
                                  security_dir=args.dir,
                                  force=args.force)
    cert_path = ca.sign_csr(args.CSR)
    print "signed_cert_path_start<{}>signed_cert_path_stop".format(cert_path)
예제 #7
0
def manage_ca_sign_csr(args):
    if not args.domain:
        raise Exception("No domain supplied")
    if not args.CSR:
        raise exception("supply path to encrypted csr")
    exist = os.path.isfile(args.CSR)
    if not exist:
        raise Exception("The CSR path supplied is not an existing file")
    ca = certificate_authority.CA(domain=args.domain,
                                  security_dir=args.dir,
                                  force=args.force)
    csr = ca.decrypt_encrypted_csr(encrypted_enrollment_request_path=args.CSR)
    csr_path = ca.store_csr_with_enrollment_password(csr)
    cert_path = ca.sign_csr(csr_path)
    print "signed_cert_path_start<{}>signed_cert_path_stop".format(cert_path)
예제 #8
0
 def __init__(self, name, csrdata=None):
     """Hold Ca state."""
     self.name = name
     self.state = STATE.NEW
     self.conf = calvinconfig.get()
     self.ca = None
     self.cafile = ""
     self.csrdata = "" if csrdata is None else csrdata
     self.csrfile = ""
     self.certfile = ""
     self.signed_cert = None
     self.is_ca = self.conf.get("security", "certificate_authority")
     self.domain = self.conf.get("security", "security_domain_name")
     if self.is_ca == "True":
         try:
             self.ca = certificate_authority.CA(self.domain)
         except (Exception), err:
             _log.error("CA could not be started, err={}".format(err))
             raise Exception("CA could not be started")
예제 #9
0
def manage_runtime_do_it_all(args):
    if not args.attr:
        raise Exception("No runtime attributes supplied")
    if not args.domain:
        raise Exception("No domain name supplied")
    attr = json.loads(args.attr)
    if not all(k in attr['indexed_public']['node_name']
               for k in ("organization", "name")):
        raise Exception("please supply name and organization of runtime")

    ca = certificate_authority.CA(domain=args.domain,
                                  commonName=args.domain + " CA",
                                  security_dir=args.dir)
    ca_cert_path = ca.export_ca_cert("/tmp")
    certificate.store_trusted_root_cert(ca_cert_path,
                                        certificate.TRUSTSTORE_TRANSPORT,
                                        security_dir=args.dir)
    os.remove(ca_cert_path)
    attributes = AttributeResolver(attr)
    node_name = attributes.get_node_name_as_str()
    nodeid = calvinuuid.uuid("NODE")
    enrollment_password = ca.cert_enrollment_add_new_runtime(node_name)
    rt_cred = runtime_credentials.RuntimeCredentials(
        node_name,
        domain=args.domain,
        security_dir=args.dir,
        nodeid=nodeid,
        enrollment_password=enrollment_password)
    ca_cert = rt_cred.get_truststore(
        type=certificate.TRUSTSTORE_TRANSPORT)[0][0]
    #Encrypt CSR with CAs public key (to protect enrollment password)
    rsa_encrypted_csr_path = rt_cred.get_encrypted_csr_path()
    #Decrypt encrypted CSR with CAs private key
    csr = ca.decrypt_encrypted_csr(
        encrypted_enrollment_request_path=rsa_encrypted_csr_path)
    csr_path = ca.store_csr_with_enrollment_password(csr)
    cert_path = ca.sign_csr(csr_path)
    print "\ncertificate stored at: {}\n".format(
        rt_cred.store_own_cert(certpath=cert_path, security_dir=args.dir))
예제 #10
0
    def discover(self):
        """
        CA service state traverser.
        Note.
        Runnign multiple instances of CA may cause problems
        as signing CSR's require serial numbers to be generated
        in serial (hence the name).
        """
        try:
            if self.state == STATE.NEW:
                self.verify_configuration()

            if self.state == STATE.CONFIGURED:
                self.cafile = self.find_ca()

            if self.state == STATE.LISTENING:
                self.receive_csr()

            if self.state == STATE.CSR_RECEIVED:
                self.validate_csr(self.csrdata)

            if self.state == STATE.CSR_ACCEPTED:
                self.csrfile = self.store_csr(self.csrdata)

            if self.state == STATE.CSR_STORED:
                self.certfile = self.sign_csr(self.csrfile)

            if self.state == STATE.CERTIFICATE_GENERATED:
                self.signed_cert = self.transmit_cert(self.certfile)

        except CaNotFound:
            _log.error("CA does not exist")
            self.ca = certificate_authority.CA(domain=self.domain)
            self.state = STATE.CONFIGURED
            self.discover()
            _log.error("ca.fatal_error")
            return
예제 #11
0
    def setup(self, request):
        from calvin.Tools.csruntime import csruntime
        from conftest import _config_pytest
        import fileinput
        global rt
        global request_handler
        try:
            shutil.rmtree(credentials_testdir)
        except Exception as err:
            print "Failed to remove old tesdir, err={}".format(err)
            pass
        try:
            os.makedirs(credentials_testdir)
            os.makedirs(runtimesdir)
            os.makedirs(runtimes_truststore)
            os.makedirs(runtimes_truststore_signing_path)
            os.makedirs(actor_store_path)
            os.makedirs(os.path.join(actor_store_path, "test"))
            shutil.copy(
                os.path.join(orig_actor_store_path, "test", "__init__.py"),
                os.path.join(actor_store_path, "test", "__init__.py"))
            os.makedirs(os.path.join(actor_store_path, "std"))
            shutil.copy(
                os.path.join(orig_actor_store_path, "std", "__init__.py"),
                os.path.join(actor_store_path, "std", "__init__.py"))
            shutil.copytree(orig_application_store_path,
                            application_store_path)
            filelist = [
                f for f in os.listdir(application_store_path)
                if f.endswith(".sign.93d58fef")
            ]
            for f in filelist:
                os.remove(os.path.join(application_store_path, f))
            shutil.copytree(
                os.path.join(security_testdir, "identity_provider"),
                identity_provider_path)
        except Exception as err:
            _log.error(
                "Failed to create test folder structure, err={}".format(err))
            print "Failed to create test folder structure, err={}".format(err)
            raise

        print "Trying to create a new test application/actor signer."
        cs = code_signer.CS(organization="testsigner",
                            commonName="signer",
                            security_dir=credentials_testdir)

        #Create signed version of CountTimer actor
        orig_actor_CountTimer_path = os.path.join(orig_actor_store_path, "std",
                                                  "CountTimer.py")
        actor_CountTimer_path = os.path.join(actor_store_path, "std",
                                             "CountTimer.py")
        shutil.copy(orig_actor_CountTimer_path, actor_CountTimer_path)
        #        cs.sign_file(actor_CountTimer_path)

        #Create unsigned version of CountTimer actor
        actor_CountTimerUnsigned_path = actor_CountTimer_path.replace(
            ".py", "Unsigned.py")
        shutil.copy(actor_CountTimer_path, actor_CountTimerUnsigned_path)
        replace_text_in_file(actor_CountTimerUnsigned_path, "CountTimer",
                             "CountTimerUnsigned")

        #Create signed version of Sum actor
        orig_actor_Sum_path = os.path.join(orig_actor_store_path, "std",
                                           "Sum.py")
        actor_Sum_path = os.path.join(actor_store_path, "std", "Sum.py")
        shutil.copy(orig_actor_Sum_path, actor_Sum_path)
        #        cs.sign_file(actor_Sum_path)

        #Create unsigned version of Sum actor
        actor_SumUnsigned_path = actor_Sum_path.replace(".py", "Unsigned.py")
        shutil.copy(actor_Sum_path, actor_SumUnsigned_path)
        replace_text_in_file(actor_SumUnsigned_path, "Sum", "SumUnsigned")

        #Create incorrectly signed version of Sum actor
        #        actor_SumFake_path = actor_Sum_path.replace(".py", "Fake.py")
        #        shutil.copy(actor_Sum_path, actor_SumFake_path)
        #        #Change the class name to SumFake
        #        replace_text_in_file(actor_SumFake_path, "Sum", "SumFake")
        #        cs.sign_file(actor_SumFake_path)
        #        #Now append to the signed file so the signature verification fails
        #        with open(actor_SumFake_path, "a") as fd:
        #                fd.write(" ")

        #Create signed version of Sink actor
        orig_actor_Sink_path = os.path.join(orig_actor_store_path, "test",
                                            "Sink.py")
        actor_Sink_path = os.path.join(actor_store_path, "test", "Sink.py")
        shutil.copy(orig_actor_Sink_path, actor_Sink_path)
        #        cs.sign_file(actor_Sink_path)

        #Create unsigned version of Sink actor
        actor_SinkUnsigned_path = actor_Sink_path.replace(".py", "Unsigned.py")
        shutil.copy(actor_Sink_path, actor_SinkUnsigned_path)
        replace_text_in_file(actor_SinkUnsigned_path, "Sink", "SinkUnsigned")

        #Sign applications
        #        cs.sign_file(os.path.join(application_store_path, "test_security1_correctly_signed.calvin"))
        #        cs.sign_file(os.path.join(application_store_path, "test_security1_correctlySignedApp_incorrectlySignedActor.calvin"))
        #        cs.sign_file(os.path.join(application_store_path, "test_security1_incorrectly_signed.calvin"))
        #        #Now append to the signed file so the signature verification fails
        #        with open(os.path.join(application_store_path, "test_security1_incorrectly_signed.calvin"), "a") as fd:
        #                fd.write(" ")

        #        print "Export Code Signers certificate to the truststore for code signing"
        #        out_file = cs.export_cs_cert(runtimes_truststore_signing_path)

        print "Trying to create a new test domain configuration."
        ca = certificate_authority.CA(domain=domain_name,
                                      commonName="testdomain CA",
                                      security_dir=credentials_testdir)
        #
        print "Copy CA cert into truststore of runtimes folder"
        ca.export_ca_cert(runtimes_truststore)
        #Define the runtime attributes
        rt0_attributes = {
            'indexed_public': {
                'owner': {
                    'organization': domain_name,
                    'personOrGroup': 'testOwner1'
                },
                'node_name': {
                    'organization': 'org.testexample',
                    'name': 'CA'
                },
                'address': {
                    'country': 'SE',
                    'locality': 'testCity',
                    'street': 'testStreet',
                    'streetNumber': 1
                }
            }
        }
        rt1_attributes = {
            'indexed_public': {
                'owner': {
                    'organization': domain_name,
                    'personOrGroup': 'testOwner1'
                },
                'node_name': {
                    'organization': 'org.testexample',
                    'name': 'testNode1'
                },
                'address': {
                    'country': 'SE',
                    'locality': 'testCity',
                    'street': 'testStreet',
                    'streetNumber': 1
                }
            }
        }
        rt2_attributes = {
            'indexed_public': {
                'owner': {
                    'organization': domain_name,
                    'personOrGroup': 'testOwner1'
                },
                'node_name': {
                    'organization': 'org.testexample',
                    'name': 'testNode2'
                },
                'address': {
                    'country': 'SE',
                    'locality': 'testCity',
                    'street': 'otherStreet',
                    'streetNumber': 1
                }
            }
        }
        rt3_attributes = {
            'indexed_public': {
                'owner': {
                    'organization': domain_name,
                    'personOrGroup': 'testOwner1'
                },
                'node_name': {
                    'organization': 'org.testexample',
                    'name': 'testNode3'
                },
                'address': {
                    'country': 'SE',
                    'locality': 'testCity',
                    'street': 'testStreet',
                    'streetNumber': 1
                }
            }
        }
        rt4_attributes = {
            'indexed_public': {
                'owner': {
                    'organization': domain_name,
                    'personOrGroup': 'testOwner1'
                },
                'node_name': {
                    'organization': 'org.testexample',
                    'name': 'testNode4'
                },
                'address': {
                    'country': 'SE',
                    'locality': 'testCity',
                    'street': 'testStreet',
                    'streetNumber': 1
                }
            }
        }
        rt5_attributes = {
            'indexed_public': {
                'owner': {
                    'organization': domain_name,
                    'personOrGroup': 'testOwner1'
                },
                'node_name': {
                    'organization': 'org.testexample',
                    'name': 'testNode5'
                },
                'address': {
                    'country': 'SE',
                    'locality': 'testCity',
                    'street': 'testStreet',
                    'streetNumber': 1
                }
            }
        }
        rt_attributes = []
        rt_attributes.append(deepcopy(rt0_attributes))
        rt_attributes.append(deepcopy(rt1_attributes))
        rt_attributes.append(deepcopy(rt2_attributes))
        rt_attributes.append(deepcopy(rt3_attributes))
        rt_attributes.append(deepcopy(rt4_attributes))
        rt_attributes.append(deepcopy(rt5_attributes))
        rt_attributes_cpy = deepcopy(rt_attributes)
        runtimes = []
        #Initiate Requesthandler with trusted CA cert
        truststore_dir = certificate.get_truststore_path(
            type=certificate.TRUSTSTORE_TRANSPORT,
            security_dir=credentials_testdir)
        #   The following is less than optimal if multiple CA certs exist
        ca_cert_path = os.path.join(truststore_dir,
                                    os.listdir(truststore_dir)[0])
        request_handler = RequestHandler(verify=ca_cert_path)
        #Generate credentials, create CSR, sign with CA and import cert for all runtimes
        enrollment_passwords = []
        for rt_attribute in rt_attributes:
            attributes = AttributeResolver(rt_attribute)
            node_name = attributes.get_node_name_as_str()
            nodeid = calvinuuid.uuid("")
            enrollment_password = ca.cert_enrollment_add_new_runtime(node_name)
            enrollment_passwords.append(enrollment_password)
            runtime = runtime_credentials.RuntimeCredentials(
                node_name,
                domain=domain_name,
                security_dir=credentials_testdir,
                nodeid=nodeid,
                enrollment_password=enrollment_password)
            runtimes.append(runtime)
            ca_cert = runtime.get_truststore(
                type=certificate.TRUSTSTORE_TRANSPORT)[0][0]
            csr_path = os.path.join(runtime.runtime_dir, node_name + ".csr")
            #Encrypt CSR with CAs public key (to protect enrollment password)
            rsa_encrypted_csr = runtime.cert_enrollment_encrypt_csr(
                csr_path, ca_cert)
            #Decrypt encrypted CSR with CAs private key
            csr = ca.decrypt_encrypted_csr(
                encrypted_enrollment_request=rsa_encrypted_csr)
            csr_path = ca.store_csr_with_enrollment_password(csr)
            cert_path = ca.sign_csr(csr_path)
            runtime.store_own_cert(certpath=cert_path,
                                   security_dir=credentials_testdir)
        #Let's hash passwords in users.json file (the runtimes will try to do this
        # but they will all try to do it at the same time, so it will be overwritten
        # multiple times and the first test will always fail)
#        self.arp = FileAuthenticationRetrievalPoint(identity_provider_path)
#        self.arp.check_stored_users_db_for_unhashed_passwords()

#The policy allows access to control interface for everyone, for more advanced rules
# it might be appropriate to run set_credentials for request_handler, e.g.,
#  request_handler.set_credentials({domain_name:{"user": "******", "password": "******"}})

        rt_conf = copy.deepcopy(_conf)
        #        rt_conf.set('security', 'runtime_to_runtime_security', "tls")
        #        rt_conf.set('security', 'control_interface_security', "tls")
        rt_conf.set('security', 'domain_name', domain_name)
        #        rt_conf.set('security', 'certificate_authority_control_uri',"https://%s:5020" % hostname )
        rt_conf.set('security', 'security_dir', credentials_testdir)
        rt_conf.set('global', 'actor_paths', [actor_store_path])
        rt_conf.set('global', 'storage_type', "securedht")

        # Runtime 0: local authentication, signature verification, local authorization.
        # Primarily acts as Certificate Authority for the domain
        rt0_conf = copy.deepcopy(rt_conf)
        #        rt0_conf.set('security','enrollment_password',enrollment_passwords[0])
        #The csruntime certificate requests assumes TLS for the control interface
        #        rt0_conf.set('security', 'control_interface_security', "tls")
        #        rt0_conf.set('security','certificate_authority','True')
        #        rt0_conf.set("security", "security_conf", {
        #                        "comment": "Certificate Authority",
        #                        "authentication": {
        #                            "procedure": "local",
        #                            "identity_provider_path": identity_provider_path
        #                        },
        #                        "authorization": {
        #                            "procedure": "local",
        #                            "policy_storage_path": policy_storage_path
        #                        }
        #                    })
        rt0_conf.save("/tmp/calvin5000.conf")

        # Runtime 1: local authentication, signature verification, local authorization.
        rt1_conf = copy.deepcopy(rt_conf)
        #        rt1_conf.set('security','enrollment_password',enrollment_passwords[1])
        #        rt1_conf.set("security", "security_conf", {
        #                        "comment": "Local authentication, local authorization",
        #                        "authentication": {
        #                            "procedure": "local",
        #                            "identity_provider_path": identity_provider_path
        #                        },
        #                        "authorization": {
        #                            "procedure": "local",
        #                            "policy_storage_path": policy_storage_path
        #                        }
        #                    })
        rt1_conf.save("/tmp/calvin5001.conf")

        # Runtime 2: local authentication, signature verification, local authorization.
        # Can also act as authorization server for other runtimes.
        # Other street compared to the other runtimes
        rt2_conf = copy.deepcopy(rt_conf)
        #        rt2_conf.set('security','enrollment_password',enrollment_passwords[2])
        #        rt2_conf.set("security", "security_conf", {
        #                        "comment": "Local authentication, local authorization",
        #                        "authentication": {
        #                            "procedure": "local",
        #                            "identity_provider_path": identity_provider_path
        #                        },
        #                        "authorization": {
        #                            "procedure": "local",
        #                            "policy_storage_path": policy_storage_path,
        #                            "accept_external_requests": True
        #                        }
        #                    })
        rt2_conf.save("/tmp/calvin5002.conf")

        # Runtime 3: external authentication (RADIUS), signature verification, local authorization.
        rt3_conf = copy.deepcopy(rt_conf)
        #        rt3_conf.set('security','enrollment_password',enrollment_passwords[3])
        #        rt3_conf.set("security", "security_conf", {
        #                        "comment": "RADIUS authentication, local authorization",
        #                        "authentication": {
        #                            "procedure": "radius",
        #                            "server_ip": "localhost",
        #                            "secret": "elxghyc5lz1_passwd"
        #                        },
        #                        "authorization": {
        #                            "procedure": "local",
        #                            "policy_storage_path": policy_storage_path
        #                        }
        #                    })
        rt3_conf.save("/tmp/calvin5003.conf")

        # Runtime 4: local authentication, signature verification, external authorization (runtime 2).
        rt4_conf = copy.deepcopy(rt_conf)
        #        rt4_conf.set('security','enrollment_password',enrollment_passwords[4])
        #        rt4_conf.set("security", "security_conf", {
        #                        "comment": "Local authentication, external authorization",
        #                        "authentication": {
        #                            "procedure": "local",
        #                            "identity_provider_path": identity_provider_path
        #                        },
        #                        "authorization": {
        #                            "procedure": "external"
        #                        }
        #                    })
        rt4_conf.save("/tmp/calvin5004.conf")

        # Runtime 5: external authentication (runtime 1), signature verification, local authorization.
        rt5_conf = copy.deepcopy(rt_conf)
        #        rt5_conf.set('global','storage_type','proxy')
        #        rt5_conf.set('global','storage_proxy',"calvinip://%s:5000" % ip_addr )
        #        rt5_conf.set('security','enrollment_password',enrollment_passwords[5])
        #        rt5_conf.set("security", "security_conf", {
        #                        "comment": "Local authentication, external authorization",
        #                        "authentication": {
        #                            "procedure": "external",
        #                            "server_uuid": runtimes[1].node_id
        #                        },
        #                        "authorization": {
        #                            "procedure": "local",
        #                            "policy_storage_path": policy_storage_path
        #                        }
        #                    })
        rt5_conf.save("/tmp/calvin5005.conf")

        #Start all runtimes
        for i in range(len(rt_attributes_cpy)):
            _log.info("Starting runtime {}".format(i))
            try:
                logfile = _config_pytest.getoption("logfile") + "500{}".format(
                    i)
                outfile = os.path.join(
                    os.path.dirname(logfile),
                    os.path.basename(logfile).replace("log", "out"))
                if outfile == logfile:
                    outfile = None
            except:
                logfile = None
                outfile = None
            csruntime(hostname,
                      port=5000 + i,
                      controlport=5020 + i,
                      attr=rt_attributes_cpy[i],
                      loglevel=_config_pytest.getoption("loglevel"),
                      logfile=logfile,
                      outfile=outfile,
                      configfile="/tmp/calvin500{}.conf".format(i))
            #            rt.append(RT("https://{}:502{}".format(hostname, i)))
            rt.append(RT("http://{}:502{}".format(hostname, i)))
            # Wait to be sure that all runtimes has started
            time.sleep(1)
        time.sleep(10)

        request.addfinalizer(self.teardown)
예제 #12
0
homefolder = get_home()
domain = "sec-dht-security-test"
testdir = os.path.join(homefolder, ".calvin", "sec_dht_security_test")
configdir = os.path.join(testdir, domain)
runtimesdir = os.path.join(testdir, "runtimes")
runtimes_truststore = os.path.join(runtimesdir, "truststore_for_transport")
try:
    shutil.rmtree(testdir)
except:
    print "Failed to remove old tesdir"
    pass

print "Creating new domain."
testca = certificate_authority.CA(domain="test",
                                  commonName="sec-dht-test-security-CA",
                                  security_dir=testdir)
print "Created new domain."

print "Import CA cert into truststore."
testca.export_ca_cert(runtimes_truststore)

print "Generate runtime credentials and sign their certificates"
for i in range(1, 5):
    for j in range(0, 6):
        name = "node{}:{}".format(i, j)
        enrollment_password = testca.cert_enrollment_add_new_runtime(name)
        nodeid = calvinuuid.uuid("NODE")
        rt_cred = runtime_credentials.RuntimeCredentials(
            name,
            domain="test",
예제 #13
0
def runtime_certificate(rt_attributes):
    import copy
    import requests
    import sys
    from calvin.requests.request_handler import RequestHandler
    from calvin.utilities.attribute_resolver import AttributeResolver
    from calvin.utilities import calvinconfig
    from calvin.utilities import calvinuuid
    from calvin.utilities import runtime_credentials
    from calvin.utilities import certificate
    from calvin.utilities import certificate_authority
    from calvin.runtime.south.plugins.storage.twistedimpl.dht.service_discovery_ssdp import parse_http_response
    global _conf
    global _log
    _conf = calvinconfig.get()
    if not _conf.get_section("security"):
        #If the security section is empty, no securty features are enabled and certificates aren't needed
        _log.debug("No runtime security enabled")
    else:
        _log.debug(
            "Some security features are enabled, let's make sure certificates are in place"
        )
        _ca_conf = _conf.get("security", "certificate_authority")
        security_dir = _conf.get("security", "security_dir")
        storage_type = _conf.get("global", "storage_type")
        if _ca_conf:
            try:
                ca_ctrl_uri = _ca_conf[
                    "ca_control_uri"] if "ca_control_uri" in _ca_conf else None
                domain_name = _ca_conf[
                    "domain_name"] if "domain_name" in _ca_conf else None
                is_ca = _ca_conf["is_ca"] if "is_ca" in _ca_conf else None
                enrollment_password = _ca_conf[
                    "enrollment_password"] if "enrollment_password" in _ca_conf else None
            except Exception as err:
                _log.error(
                    "runtime_certificate: Failed to parse security configuration in calvin.conf, err={}"
                    .format(err))
                raise
            #AttributeResolver tranforms the attributes, so make a deepcopy instead
            rt_attributes_cpy = copy.deepcopy(rt_attributes)
            attributes = AttributeResolver(rt_attributes_cpy)
            node_name = attributes.get_node_name_as_str()
            nodeid = calvinuuid.uuid("")
            runtime = runtime_credentials.RuntimeCredentials(
                node_name,
                domain_name,
                security_dir=security_dir,
                nodeid=nodeid,
                enrollment_password=enrollment_password)
            certpath, cert, certstr = runtime.get_own_cert()
            if not cert:
                csr_path = os.path.join(runtime.runtime_dir,
                                        node_name + ".csr")
                if is_ca == "True":
                    _log.debug(
                        "No runtime certificate, but node is a CA, just sign csr, domain={}"
                        .format(domain_name))
                    ca = certificate_authority.CA(domain=domain_name,
                                                  security_dir=security_dir)
                    cert_path = ca.sign_csr(csr_path, is_ca=True)
                    runtime.store_own_cert(certpath=cert_path,
                                           security_dir=security_dir)

                else:
                    _log.debug(
                        "No runtime certicificate can be found, send CSR to CA"
                    )
                    truststore_dir = certificate.get_truststore_path(
                        type=certificate.TRUSTSTORE_TRANSPORT,
                        security_dir=security_dir)
                    request_handler = RequestHandler(verify=truststore_dir)
                    ca_control_uris = []
                    #TODO: add support for multiple CA control uris
                    if ca_ctrl_uri:
                        _log.debug(
                            "CA control_uri in config={}".format(ca_ctrl_uri))
                        ca_control_uris.append(ca_ctrl_uri)
                    elif storage_type in ["dht", "securedht"]:
                        _log.debug("Find CA via SSDP")
                        responses = discover()
                        if not responses:
                            _log.error("No responses received")
                        for response in responses:
                            cmd, headers = parse_http_response(response)
                            if 'location' in headers:
                                ca_control_uri, ca_node_id = headers[
                                    'location'].split('/node/')
                                ca_control_uri = ca_control_uri.replace(
                                    "http", "https")
                                ca_control_uris.append(ca_control_uri)
                                _log.debug(
                                    "CA control_uri={}, node_id={}".format(
                                        ca_control_uri, ca_node_id))
                    else:
                        _log.error(
                            "There is no runtime certificate. For automatic certificate enrollment using proxy storage,"
                            "the CA control uri must be configured in the calvin configuration "
                        )
                        raise Exception(
                            "There is no runtime certificate. For automatic certificate enrollment using proxy storage,"
                            "the CA control uri must be configured in the calvin configuration "
                        )
                    cert_available = False
                    # Loop through all CA:s that responded until hopefully one signs our CSR
                    # Potential improvement would be to have domain name in response and only try
                    # appropriate CAs
                    i = 0
                    while not cert_available and i < len(ca_control_uris):
                        certstr = None
                        #Repeatedly (maximum 10 attempts) send CSR to CA until a certificate is returned (this to remove the requirement of the CA
                        #node to be be the first node to start)
                        rsa_encrypted_csr = runtime.get_encrypted_csr()
                        j = 0
                        while not certstr and j < 10:
                            try:
                                certstr = request_handler.sign_csr_request(
                                    ca_control_uris[i],
                                    rsa_encrypted_csr)['certificate']
                            except requests.exceptions.RequestException as err:
                                time_to_sleep = 1 + j * j * j
                                _log.debug(
                                    "RequestException, CSR not accepted or CA not up and running yet, sleep {} seconds and try again, err={}"
                                    .format(time_to_sleep, err))
                                time.sleep(time_to_sleep)
                                j = j + 1
                                pass
                            else:
                                cert_available = True
                        i = i + 1
                    #TODO: check that everything is ok with signed cert, e.g., check that the CA domain
                    # matches the expected and that the CA cert is trusted
                    runtime.store_own_cert(certstring=certstr,
                                           security_dir=security_dir)
            else:
                _log.debug("Runtime certificate available")
예제 #14
0
    def setup(self, request):
        from calvin.Tools.csruntime import csruntime
        from conftest import _config_pytest
        import fileinput
        global hostname
        global rt
        global rt_attributes
        global request_handler
        try:
            ipv6_hostname = socket.gethostbyaddr('::1')
        except Exception as err:
            print(
                "Failed to resolve the IPv6 localhost hostname, please update the corresponding entry in the /etc/hosts file, e.g.,:\n"
                "\t::1              <hostname>.localdomain <hostname>.local <hostname> localhost"
            )
            raise
        try:
            ipv6_hostname = socket.gethostbyaddr('::ffff:127.0.0.1')
        except Exception as err:
            print(
                "Failed to resolve ::ffff:127.0.0.1, please add the following line (with your hostname) to  /etc/hosts :\n"
                "::ffff:127.0.0.1:           <hostname>.localdomain <hostname>.local <hostname>"
            )
            raise
        try:
            hostname = socket.gethostname()
            ip_addr = socket.gethostbyname(hostname)
            fqdn = socket.getfqdn(hostname)
            print("\n\tip_addr={}"
                  "\n\thostname={}"
                  "\n\tfqdn={}".format(ip_addr, hostname, fqdn))
        except Exception as err:
            print(
                "Failed to resolve the hostname, ip_addr or the FQDN of the runtime, err={}"
                .format(err))
            raise

        try:
            shutil.rmtree(credentials_testdir)
        except Exception as err:
            print "Failed to remove old tesdir, err={}".format(err)
            pass
        try:
            os.makedirs(credentials_testdir)
            os.makedirs(runtimesdir)
            os.makedirs(runtimes_truststore)
        except Exception as err:
            _log.error(
                "Failed to create test folder structure, err={}".format(err))
            print "Failed to create test folder structure, err={}".format(err)
            raise

        _log.info(
            "Trying to create a new test domain configuration. Create many CAs to ensure runtime can handle several CA certificates"
        )
        try:
            ca1 = certificate_authority.CA(domain=domain_name + " 1",
                                           commonName="testdomainCA1",
                                           security_dir=credentials_testdir)
            ca2 = certificate_authority.CA(domain=domain_name + " 2",
                                           commonName="testdomainCA2",
                                           security_dir=credentials_testdir)
            ca3 = certificate_authority.CA(domain=domain_name + " 3",
                                           commonName="testdomainCA3",
                                           security_dir=credentials_testdir)
        except Exception as err:
            _log.error("Failed to create CA, err={}".format(err))

        _log.info("Copy CA cert into truststore of runtimes folder")
        ca1.export_ca_cert(runtimes_truststore)
        ca2.export_ca_cert(runtimes_truststore)
        ca3.export_ca_cert(runtimes_truststore)

        actor_store_path, application_store_path = helpers.sign_files_for_security_tests(
            credentials_testdir)
        runtimes = helpers.create_CA_and_generate_runtime_certs(
            domain_name, credentials_testdir, NBR_OF_RUNTIMES)
        #Initiate Requesthandler with trusted CA cert
        truststore_dir = certificate.get_truststore_path(
            type=certificate.TRUSTSTORE_TRANSPORT,
            security_dir=credentials_testdir)
        request_handler = RequestHandler(verify=truststore_dir)

        rt_conf = copy.deepcopy(_conf)
        rt_conf.set('security', 'runtime_to_runtime_security', "tls")
        rt_conf.set('security', 'control_interface_security', "tls")
        rt_conf.set('security', 'security_dir', credentials_testdir)
        rt0_conf = copy.deepcopy(rt_conf)

        # Runtime 0: local authentication, signature verification, local authorization.
        # Primarily acts as Certificate Authority for the domain
        rt0_conf.set('global', 'storage_type', 'local')
        rt0_conf.set('security', 'certificate_authority', {
            'domain_name': domain_name,
            'is_ca': 'True'
        })
        rt0_conf.save("/tmp/calvin5000.conf")

        # Runtime 1: local authentication, signature verification, local authorization.
        rt_conf.set('global', 'storage_type', 'proxy')
        rt_conf.set('global', 'storage_proxy', "calvinip://%s:5000" % hostname)
        rt_conf.set('security', 'certificate_authority', {
            'domain_name': domain_name,
            'is_ca': 'False'
        })

        for i in range(1, NBR_OF_RUNTIMES):
            rt_conf.save("/tmp/calvin500{}.conf".format(i))

        rt = helpers.start_all_runtimes(runtimes,
                                        hostname,
                                        request_handler,
                                        tls=True)
        request.addfinalizer(self.teardown)
예제 #15
0
    def setup(self, request):
        from calvin.Tools.csruntime import csruntime
        from conftest import _config_pytest
        import fileinput
        global hostname
        global rt
        global rt_attributes
        global request_handler
        try:
            ipv6_hostname = socket.gethostbyaddr('::1')
        except Exception as err:
            print(
                "Failed to resolve the IPv6 localhost hostname, please update the corresponding entry in the /etc/hosts file, e.g.,:\n"
                "\t::1              <hostname>.localdomain <hostname>.local <hostname> localhost"
            )
            raise
        try:
            ipv6_hostname = socket.gethostbyaddr('::ffff:127.0.0.1')
        except Exception as err:
            print(
                "Failed to resolve ::ffff:127.0.0.1, please add the following line (with your hostname) to  /etc/hosts :\n"
                "::ffff:127.0.0.1:           <hostname>.localdomain <hostname>.local <hostname>"
            )
            raise
        try:
            hostname = socket.gethostname()
            ip_addr = socket.gethostbyname(hostname)
            fqdn = socket.getfqdn(hostname)
            print("\n\tip_addr={}"
                  "\n\thostname={}"
                  "\n\tfqdn={}".format(ip_addr, hostname, fqdn))
        except Exception as err:
            print(
                "Failed to resolve the hostname, ip_addr or the FQDN of the runtime, err={}"
                .format(err))
            raise

        try:
            shutil.rmtree(credentials_testdir)
        except Exception as err:
            print "Failed to remove old tesdir, err={}".format(err)
            pass
        try:
            os.mkdir(credentials_testdir)
            os.mkdir(runtimesdir)
            os.mkdir(runtimes_truststore)
        except Exception as err:
            _log.error(
                "Failed to create test folder structure, err={}".format(err))
            print "Failed to create test folder structure, err={}".format(err)
            raise

        _log.info("Trying to create a new test domain configuration.")
        try:
            ca = certificate_authority.CA(domain=domain_name,
                                          commonName="testdomain CA",
                                          security_dir=credentials_testdir)
        except Exception as err:
            _log.error("Failed to create CA, err={}".format(err))

        _log.info("Copy CA cert into truststore of runtimes folder")
        ca.export_ca_cert(runtimes_truststore)
        node_names = []
        rt_attributes = []
        for i in range(6):
            node_name = {
                'organization': 'org.testexample',
                'name': 'testNode{}'.format(i)
            }
            owner = {'organization': domain_name, 'personOrGroup': 'testOwner'}
            address = {
                'country': 'SE',
                'locality': 'testCity',
                'street': 'testStreet',
                'streetNumber': 1
            }
            rt_attribute = {
                'indexed_public': {
                    'owner': owner,
                    'node_name': node_name,
                    'address': address
                }
            }
            rt_attributes.append(rt_attribute)
        rt_attributes_cpy = deepcopy(rt_attributes)
        runtimes = []
        #Initiate Requesthandler with trusted CA cert
        truststore_dir = certificate.get_truststore_path(
            type=certificate.TRUSTSTORE_TRANSPORT,
            security_dir=credentials_testdir)
        #   The following is less than optimal if multiple CA certs exist
        ca_cert_path = os.path.join(truststore_dir,
                                    os.listdir(truststore_dir)[0])
        request_handler = RequestHandler(verify=ca_cert_path)

        #Generate credentials, create CSR, sign with CA and import cert for all runtimes
        enrollment_passwords = []
        for rt_attribute in rt_attributes_cpy:
            _log.info("rt_attribute={}".format(rt_attribute))
            attributes = AttributeResolver(rt_attribute)
            node_name = attributes.get_node_name_as_str()
            nodeid = calvinuuid.uuid("")
            enrollment_password = ca.cert_enrollment_add_new_runtime(node_name)
            enrollment_passwords.append(enrollment_password)
            runtime = runtime_credentials.RuntimeCredentials(
                node_name,
                domain=domain_name,
                security_dir=credentials_testdir,
                nodeid=nodeid,
                enrollment_password=enrollment_password)
            runtimes.append(runtime)
            ca_cert = runtime.get_truststore(
                type=certificate.TRUSTSTORE_TRANSPORT)[0][0]
            csr_path = os.path.join(runtime.runtime_dir, node_name + ".csr")
            #Encrypt CSR with CAs public key (to protect enrollment password)
            rsa_encrypted_csr = runtime.cert_enrollment_encrypt_csr(
                csr_path, ca_cert)
            #Decrypt encrypted CSR with CAs private key
            csr = ca.decrypt_encrypted_csr(
                encrypted_enrollment_request=rsa_encrypted_csr)
            csr_path = ca.store_csr_with_enrollment_password(csr)
            cert_path = ca.sign_csr(csr_path)
            runtime.store_own_cert(certpath=cert_path,
                                   security_dir=credentials_testdir)

        rt_conf = copy.deepcopy(_conf)
        rt_conf.set('security', 'runtime_to_runtime_security', "tls")
        rt_conf.set('security', 'control_interface_security', "tls")
        rt_conf.set('security', 'domain_name', domain_name)
        rt_conf.set('security', 'security_dir', credentials_testdir)
        rt0_conf = copy.deepcopy(rt_conf)
        rt_conf.set('global', 'storage_type', 'proxy')
        rt_conf.set('global', 'storage_proxy', "calvinip://%s:5000" % hostname)

        # Runtime 0: local authentication, signature verification, local authorization.
        # Primarily acts as Certificate Authority for the domain
        rt0_conf.set('global', 'storage_type', 'local')
        rt0_conf.save("/tmp/calvin5000.conf")

        # Runtime 1: local authentication, signature verification, local authorization.
        rt1_conf = copy.deepcopy(rt_conf)
        rt1_conf.save("/tmp/calvin5001.conf")

        # Runtime 2: local authentication, signature verification, local authorization.
        # Can also act as authorization server for other runtimes.
        # Other street compared to the other runtimes
        rt2_conf = copy.deepcopy(rt_conf)
        rt2_conf.save("/tmp/calvin5002.conf")

        # Runtime 3: external authentication (RADIUS), signature verification, local authorization.
        rt3_conf = copy.deepcopy(rt_conf)
        rt3_conf.save("/tmp/calvin5003.conf")

        # Runtime 4: local authentication, signature verification, external authorization (runtime 2).
        rt4_conf = copy.deepcopy(rt_conf)
        rt4_conf.save("/tmp/calvin5004.conf")

        # Runtime 5: external authentication (runtime 1), signature verification, local authorization.
        rt5_conf = copy.deepcopy(rt_conf)
        rt5_conf.save("/tmp/calvin5005.conf")

        #Start all runtimes
        for i in range(len(rt_attributes)):
            _log.info("Starting runtime {}".format(i))
            try:
                logfile = _config_pytest.getoption("logfile") + "500{}".format(
                    i)
                outfile = os.path.join(
                    os.path.dirname(logfile),
                    os.path.basename(logfile).replace("log", "out"))
                if outfile == logfile:
                    outfile = None
            except:
                logfile = None
                outfile = None
            csruntime(hostname,
                      port=5000 + i,
                      controlport=5020 + i,
                      attr=rt_attributes[i],
                      loglevel=_config_pytest.getoption("loglevel"),
                      logfile=logfile,
                      outfile=outfile,
                      configfile="/tmp/calvin500{}.conf".format(i))
            rt.append(RT("https://{}:502{}".format(hostname, i)))
            # Wait to be sure that all runtimes has started
            time.sleep(1)
        time.sleep(2)

        request.addfinalizer(self.teardown)
예제 #16
0
    def setup(self, request):
        from calvin.Tools.csruntime import csruntime
        from conftest import _config_pytest
        homefolder = get_home()
        domain = "rttest"
        testdir = os.path.join(homefolder, ".calvin", "sec_dht_test")
        configdir = os.path.join(testdir, domain)
        runtimesdir = os.path.join(testdir, "runtimes")
        runtimes_truststore = os.path.join(runtimesdir,
                                           "truststore_for_transport")
        try:
            shutil.rmtree(testdir)
        except:
            print "Failed to remove old tesdir"
            pass
        try:
            os.mkdir(testdir)
            os.mkdir(configdir)
            os.mkdir(runtimesdir)
            os.mkdir(runtimes_truststore)
        except:
            print "Failed to create test folder structure"
            pass

        print "Trying to create a new test domain configuration."
        ca = certificate_authority.CA(domain=domain,
                                      commonName="sec-dht-test-CA",
                                      security_dir=testdir)
        print "Reading configuration successfull."

        print "Copy CA cert into truststore of runtimes folder"
        ca.export_ca_cert(runtimes_truststore)

        ca_original_backup = os.path.join(homefolder, ".calvin",
                                          "sec_dht_test_backup", domain)
        try:
            shutil.rmtree(ca_original_backup)
        except:
            pass
        # copy other setup and remove private directory and openssl.conf file
#        shutil.copytree(configdir, ca_original_backup)
#        shutil.rmtree(os.path.join(configdir, "private"))
#        configfile=os.path.join(configdir, "openssl.conf")
#        os.remove(configfile)
#        print "Trying to create a second test domain configuration."
#        testconfig = certificate_authority.CA(domain=domain, security_dir=testdir)

        global rt1
        global rt2
        global rt3
        global test_script_dir
        rt_conf = copy.deepcopy(_conf)
        rt_conf.set('global', 'storage_type', 'securedht')
        rt_conf.add_section('security')
        rt_conf.set('security', "runtimes_path", runtimesdir)
        rt_conf.set('security', "security_domain_name", domain)
        rt_conf.set('security', "security_path", testdir)
        rt_conf.save("/tmp/calvin1.conf")
        rt_conf2 = copy.deepcopy(rt_conf)
        rt_conf2.set('global', 'actor_paths',
                     [absolute_filename('test_store')])
        rt_conf2.set('global', 'capabilities_blacklist',
                     ['calvinsys.events.timer'])
        rt_conf2.save("/tmp/calvin2.conf")
        rt_ca_conf = copy.deepcopy(rt_conf)
        rt_ca_conf.set('security', "certificate_authority", "True")
        rt_ca_conf.save("/tmp/calvin_ca.conf")
        try:
            logfile = _config_pytest.getoption("logfile") + "5000"
            outfile = os.path.join(
                os.path.dirname(logfile),
                os.path.basename(logfile).replace("log", "out"))
            if outfile == logfile:
                outfile = None
        except:
            logfile = None
            outfile = None
        csruntime(ip_addr,
                  port=5000,
                  controlport=5003,
                  attr={
                      'indexed_public': {
                          'owner': {
                              'organization': 'org.testexample',
                              'personOrGroup': 'testOwner1'
                          },
                          'node_name': {
                              'name': 'node0'
                          },
                          'address': {
                              'country': 'SE',
                              'locality': 'testCity',
                              'street': 'testStreet',
                              'streetNumber': 1
                          }
                      }
                  },
                  loglevel=_config_pytest.getoption("loglevel"),
                  logfile=logfile,
                  outfile=outfile,
                  configfile="/tmp/calvin_ca.conf")
        rt1 = RT("http://%s:5003" % ip_addr)
        try:
            logfile = _config_pytest.getoption("logfile") + "5001"
            outfile = os.path.join(
                os.path.dirname(logfile),
                os.path.basename(logfile).replace("log", "out"))
            if outfile == logfile:
                outfile = None
        except:
            logfile = None
            outfile = None
        csruntime(ip_addr,
                  port=5001,
                  controlport=5004,
                  attr={
                      'indexed_public': {
                          'owner': {
                              'organization': 'org.testexample',
                              'personOrGroup': 'testOwner1'
                          },
                          'node_name': {
                              'name': 'node1'
                          },
                          'address': {
                              'country': 'SE',
                              'locality': 'testCity',
                              'street': 'testStreet',
                              'streetNumber': 1
                          }
                      }
                  },
                  loglevel=_config_pytest.getoption("loglevel"),
                  logfile=logfile,
                  outfile=outfile,
                  configfile="/tmp/calvin1.conf")
        rt2 = RT("http://%s:5004" % ip_addr)
        try:
            logfile = _config_pytest.getoption("logfile") + "5002"
            outfile = os.path.join(
                os.path.dirname(logfile),
                os.path.basename(logfile).replace("log", "out"))
            if outfile == logfile:
                outfile = None
        except:
            logfile = None
            outfile = None
        csruntime(ip_addr,
                  port=5002,
                  controlport=5005,
                  attr={
                      'indexed_public': {
                          'owner': {
                              'organization': 'org.testexample',
                              'personOrGroup': 'testOwner1'
                          },
                          'node_name': {
                              'name': 'node2'
                          },
                          'address': {
                              'country': 'SE',
                              'locality': 'testCity',
                              'street': 'testStreet',
                              'streetNumber': 1
                          }
                      }
                  },
                  loglevel=_config_pytest.getoption("loglevel"),
                  logfile=logfile,
                  outfile=outfile,
                  configfile="/tmp/calvin2.conf")
        rt3 = RT("http://%s:5005" % ip_addr)

        test_script_dir = absolute_filename('scripts/')
        request.addfinalizer(self.teardown)
예제 #17
0
    def start(self,
              iface='',
              network=None,
              bootstrap=None,
              cb=None,
              name=None,
              nodeid=None):
        if bootstrap is None:
            bootstrap = []

        if network is None:
            network = _conf.get_in_order("dht_network_filter", "ALL")
        self._network = network
        self._iface = iface
        self._bootstrap = bootstrap
        self._cb = cb
        self._name = name

        self._dlist = []
        self._ssdps = SSDPServiceDiscovery(iface)
        self._dlist += self._ssdps.start()
        domain = _conf.get("security", "security_domain_name")
        is_ca = False
        try:
            if _conf.get("security", "certificate_authority") == "True":
                ca = certificate_authority.CA(domain)
                #make sure private key exist
                if ca.verify_private_key_exist():
                    is_ca = True
        except:
            is_ca = False
        self._ssdps.update_server_params(CA_SERVICE_UUID,
                                         sign=is_ca,
                                         name=name)
        cert, certstr = certificate.get_own_cert(self._name)
        if not cert:
            _log.debug("runtime cert not available, let's create CSR")
            if is_ca:
                # We are the CA, just generate CSR and sign it
                csrfile = certificate.new_runtime(name, domain, nodeid=nodeid)
                _log.debug("Local CA sign runtime CSR")
                try:
                    content = open(csrfile, 'rt').read()
                    certpath = ca.sign_csr(csrfile)
                    certificate.store_own_cert(certpath=certpath)
                    return self._signed_cert_available()
                except:
                    _log.exception("Failed signing with local CA")
                    raise
            else:
                # Discover the signing CA
                _log.debug("No signed cert, discover CA signing CSR")
                self._sde_client = sde.Client(
                    name, nodeid,
                    CalvinCB(self._ssdps.start_search,
                             CA_SERVICE_UUID,
                             callback=self._signed_cert_received),
                    self._signed_cert_available)
        else:
            _log.debug("runtime cert available")
            self._signed_cert_available(cert=cert, certstr=certstr)