Esempio n. 1
0
def generate_core_certificate(as_):
    """
    Create or update the Core AS Certificate for `as_`.
    If the AS already has a Core AS Certificate, the version number is incremented for the
    new certificate.

    Requires that TRC for the related ISD exists/is up to date.

    :param AS as_: a core AS
    :returns: the Core AS Certificate as a dict
    """
    isd = as_.isd
    assert isd.trc
    trc = TRC(isd.trc)

    if as_.core_certificate:
        version = as_.core_certificate['Version'] + 1
    else:
        version = 1

    cert = Certificate.from_values(
        subject=as_.isd_as_str(),
        issuer=as_.isd_as_str(),
        trc_version=trc.version,
        version=version,
        comment="Core AS Certificate",
        can_issue=True,
        validity_period=min(trc.exp_time - int(time.time()) - 1,
                            CORE_AS_VALIDITY_PERIOD),
        subject_enc_key=b"",
        subject_sig_key=base64.b64decode(as_.core_sig_pub_key),
        iss_priv_key=base64.b64decode(as_.core_online_priv_key))
    return cert.dict()
Esempio n. 2
0
def prep_approved_join_reply(request, join_rep_dict, own_isdas, own_as_obj):
    """
    Prepares the join reply for the APPROVED case.
    """
    logger.info("New AS ID = %s", request.POST['newASId'])
    joining_as = request.POST['newASId']
    is_core = request.POST['join_as_a_core']
    sig_pub_key = from_b64(request.POST['sig_pub_key'])
    enc_pub_key = from_b64(request.POST['enc_pub_key'])
    signing_as_sig_priv_key = from_b64(own_as_obj.sig_priv_key)
    joining_ia = TopoID.from_values(own_isdas[0], joining_as)
    if is_core.lower() == "true":
        validity = Certificate.CORE_AS_VALIDITY_PERIOD
        comment = "Core AS Certificate"
    else:
        validity = Certificate.AS_VALIDITY_PERIOD
        comment = "AS Certificate"
    cert = Certificate.from_values(
        str(joining_ia), str(own_isdas), INITIAL_TRC_VERSION, INITIAL_CERT_VERSION, comment,
        is_core, validity, enc_pub_key, sig_pub_key, SigningKey(signing_as_sig_priv_key)
    )
    respond_ia_chain = CertificateChain.from_raw(own_as_obj.certificate)
    request_ia_chain = CertificateChain([cert, respond_ia_chain.core_as_cert])
    join_rep_dict['JoiningIA'] = str(joining_ia)
    join_rep_dict['IsCore'] = is_core.lower() == "true"
    join_rep_dict['RespondIA'] = str(own_isdas)
    join_rep_dict['JoiningIACertificate'] = request_ia_chain.to_json()
    join_rep_dict['RespondIACertificate'] = respond_ia_chain.to_json()
    join_rep_dict['TRC'] = TRC.from_raw(own_as_obj.trc).to_json()
    logger.debug("Accepting Join Request = %s", join_rep_dict)
Esempio n. 3
0
 def _create_trc(self, isd):
     quorum_trc = min(self.core_count[isd], MAX_QUORUM_TRC)
     self.trcs[isd] = TRC.from_values(isd, "ISD %s" % isd,
                                      INITIAL_TRC_VERSION, {}, {}, {},
                                      THRESHOLD_EEPKI, {}, quorum_trc,
                                      MAX_QUORUM_CAS, INITIAL_GRACE_PERIOD,
                                      False, {}, DEFAULT_TRC_VALIDITY)
Esempio n. 4
0
    def _check_trc(self, isd, expected_core_ases, expected_version=None):
        """
        Check the ISD's TRC and return it as a TRC object.
        :param ISD isd:
        :param [str] expected_core_ases: ISD-AS strings for all core ases
        :param int expected_version: optional
        :returns: TRC
        :rtype: TRC
        """
        self.assertEqual(set(isd.trc['CoreASes'].keys()),
                         set(expected_core_ases))
        self.assertEqual(set(isd.trc_priv_keys.keys()),
                         set(expected_core_ases))
        for isd_as in expected_core_ases:
            utils.check_sig_keypair(self,
                                    isd.trc['CoreASes'][isd_as]['OnlineKey'],
                                    isd.trc_priv_keys[isd_as])

        json_trc = json.dumps(
            isd.trc)  # round trip through json, just to make sure this works
        trc = TRC.from_raw(json_trc)
        trc.check_active()
        if expected_version is not None:
            self.assertEqual(trc.version, expected_version)
        return trc
Esempio n. 5
0
def check_trc(testcase,
              isd,
              expected_core_ases=None,
              expected_version=None,
              prev_trc=None):
    """
    Check the ISD's TRC and return it as a TRC object.
    :param ISD isd:
    :param [str] expected_core_ases: optional, ISD-AS strings for all core ases
    :param int expected_version: optional, expected version for current TRC.
    :param TRC prev_trc: optional, previous TRC to verify current TRC.
    :returns: TRC
    :rtype: TRC
    """
    if expected_core_ases is None:
        expected_core_ases = set(as_.isd_as_str()
                                 for as_ in isd.ases.filter(is_core=True))
    testcase.assertEqual(set(isd.trc['CoreASes'].keys()),
                         set(expected_core_ases))
    testcase.assertEqual(set(isd.trc_priv_keys.keys()),
                         set(expected_core_ases))

    for isd_as in isd.trc['CoreASes'].keys():
        check_sig_keypair(testcase, isd.trc['CoreASes'][isd_as]['OnlineKey'],
                          isd.trc_priv_keys[isd_as])

    json_trc = json.dumps(
        isd.trc)  # round trip through json, just to make sure this works
    trc = TRC.from_raw(json_trc)
    trc.check_active()
    if expected_version is not None:
        testcase.assertEqual(trc.version, expected_version)
    if prev_trc is not None:
        trc.verify(prev_trc)
    return trc
Esempio n. 6
0
def check_core_cert(testcase, as_, trc):
    """
    Check that the AS's core certificate can be verified with the TRC.
    """
    testcase.assertIsNotNone(as_.core_certificate)
    cert = Certificate(as_.core_certificate)
    isd_as = as_.isd_as_str()
    cert.verify(isd_as, TRC(trc).core_ases[isd_as]['OnlineKey'])
Esempio n. 7
0
def check_cert_chain(testcase, as_, trc):
    """
    Check that the AS's certificate chain can be verified with the TRC.
    """
    testcase.assertIsNotNone(as_.certificate_chain)
    json_cert_chain = json.dumps(as_.certificate_chain)
    cert_chain = CertificateChain.from_raw(json_cert_chain)
    cert_chain.verify(as_.isd_as_str(), TRC(trc))
Esempio n. 8
0
 def _init_trcs(self):  # pragma: no cover
     trcfiles = list(glob.glob("%s/*.trc" % self._dir))
     trcfiles.extend(
         glob.glob("%s/%s-*.trc" % (self._cachedir, self._ename)))
     for path in trcfiles:
         trc_raw = read_file(path)
         self.add_trc(TRC.from_raw(trc_raw), write=False)
         logging.debug("Loaded: %s" % path)
Esempio n. 9
0
 def _cached_trcs_handler(self, raw_entries):
     """
     Handles cached (through ZK) TRCs, passed as a list.
     """
     for raw in raw_entries:
         trc = TRC.from_raw(raw.decode('utf-8'))
         rep = TRCReply.from_values(trc)
         self.process_trc_reply(rep, None, from_zk=True)
     logging.debug("Processed %s trcs from ZK", len(raw_entries))
Esempio n. 10
0
def generate_trc(isd):
    """
    Create or update the TRC for the given ISD.
    Returns the TRC as a dict and a dict containing the private keys needed to sign the next
    TRC version.

    :param ISD isd:
    :returns: (dict, dict) TRC, trc_priv_keys
    """
    if isd.trc:
        version = isd.trc['Version'] + 1
    else:
        version = 1

    core_ases = list(isd.ases.filter(is_core=True))

    core_ases_keys = {
        as_.isd_as_str(): {
            ONLINE_KEY_STRING: as_.core_online_pub_key,
            ONLINE_KEY_ALG_STRING: KEYGEN_ALG,
            OFFLINE_KEY_STRING: as_.core_offline_pub_key,
            OFFLINE_KEY_ALG_STRING: KEYGEN_ALG
        }
        for as_ in core_ases
    }

    trc = TRC.from_values(isd=isd.isd_id,
                          description=str(isd),
                          version=version,
                          core_ases=core_ases_keys,
                          root_cas={},
                          cert_logs={},
                          threshold_eepki=0,
                          rains={},
                          quorum_trc=len(core_ases),
                          quorum_cas=0,
                          grace_period=0,
                          quarantine=False,
                          signatures={},
                          validity_period=TRC_VALIDITY_PERIOD)

    # Sign with private keys corresponding to public keys (core AS online public keys) in previous
    # TRC version
    # For initial version simply use the private online keys
    core_ases_online_priv_keys = {
        as_.isd_as_str(): as_.core_online_priv_key
        for as_ in core_ases
    }
    signing_keys = isd.trc_priv_keys or core_ases_online_priv_keys

    for isd_as, sig_priv_key in signing_keys.items():
        trc.sign(isd_as, base64.b64decode(sig_priv_key))

    # Return trc and signing keys for next version:
    # The keys and signatures are contained as bytes-objects in the dict returned, encode them
    return _base64encode_dict(
        trc.dict(with_signatures=True)), core_ases_online_priv_keys
Esempio n. 11
0
class TRCReply(CertMgmtBase):  # pragma: no cover
    NAME = "TRCReply"
    PAYLOAD_TYPE = CertMgmtType.TRC_REPLY
    P_CLS = P.TRCRep

    def __init__(self, p):
        super().__init__(p)
        self.trc = TRC(p.trc, lz4_=True)

    @classmethod
    def from_values(cls, trc):
        return cls(cls.P_CLS.new_message(trc=trc.pack(lz4_=True)))

    def short_desc(self):
        return "%sv%s" % self.trc.get_isd_ver()

    def __str__(self):
        isd, ver = self.trc.get_isd_ver()
        return "%s: ISD: %s version: %s TRC: %s" % (self.NAME, isd, ver,
                                                    self.trc)
Esempio n. 12
0
def prep_approved_join_reply(request, join_rep_dict, own_isdas, own_as_obj):
    """
    Prepares the join reply for the APPROVED case.
    """
    logger.info("New AS ID = %s", request.POST['newASId'])
    joining_as = request.POST['newASId']
    is_core = request.POST['join_as_a_core']
    sig_pub_key = from_b64(request.POST['sig_pub_key'])
    enc_pub_key = from_b64(request.POST['enc_pub_key'])
    signing_as_sig_priv_key = from_b64(own_as_obj.sig_priv_key)
    joining_ia = ISD_AS.from_values(own_isdas[0], joining_as)
    cert = Certificate.from_values(str(joining_ia), str(own_isdas),
                                   INITIAL_CERT_VERSION, "", False,
                                   enc_pub_key, sig_pub_key,
                                   SigningKey(signing_as_sig_priv_key))
    respond_ia_chain = CertificateChain.from_raw(own_as_obj.certificate)
    request_ia_chain = CertificateChain([cert, respond_ia_chain.certs[0]])
    join_rep_dict['JoiningIA'] = str(joining_ia)
    join_rep_dict['IsCore'] = is_core.lower() == "true"
    join_rep_dict['RespondIA'] = str(own_isdas)
    join_rep_dict['JoiningIACertificate'] = request_ia_chain.to_json()
    join_rep_dict['RespondIACertificate'] = respond_ia_chain.to_json()
    join_rep_dict['TRC'] = TRC.from_raw(own_as_obj.trc).to_json()
    logger.debug("Accepting Join Request = %s", join_rep_dict)
Esempio n. 13
0
 def _init_trcs(self):  # pragma: no cover
     for path in glob.glob("%s/*.trc" % self._dir):
         trc_raw = read_file(path)
         self.add_trc(TRC.from_raw(trc_raw), write=False)
         logging.debug("Loaded: %s" % path)
Esempio n. 14
0
 def _check_cert_chain(self, as_, trc):
     self.assertIsNotNone(as_.certificate_chain)
     json_cert_chain = json.dumps(as_.certificate_chain)
     cert_chain = CertificateChain.from_raw(json_cert_chain)
     cert_chain.verify(as_.isd_as_str(), TRC(trc))
Esempio n. 15
0
 def _check_core_cert(self, as_, trc):
     self.assertIsNotNone(as_.core_certificate)
     cert = Certificate(as_.core_certificate)
     isd_as = as_.isd_as_str()
     cert.verify(isd_as, TRC(trc).core_ases[isd_as]['OnlineKey'])
Esempio n. 16
0
        log.add(e)
        log.build()  # test building for each node
    log.build()
    # Policy trees should be consistent
    random.shuffle(all_)
    assert log.policy_tree.get_root() == Log(all_).policy_tree.get_root()
    return log


if __name__ == "__main__":
    # PYTHONPATH=..:../scion ./tests.py tmp/msc.cert tmp/scp.cert ISD1-V0.trc
    if len(sys.argv) != 2:
        print("%s <TRC>" % sys.argv[0])
        sys.exit(-1)
    with open(sys.argv[1], "r") as f:
        trc = TRC.from_raw(f.read())
    # Load generated objects
    mscs, scps = load_mscs_scps()
    for domain_name in mscs:
        msc = mscs[domain_name]
        scp = scps[domain_name]
        # Verify MSC
        verifier(msc, scp, trc, domain_name)
        # Test basic packing and parsing
        test_pack_parse(msc, scp)
    mscsl = list(mscs.values())
    scpsl = list(scps.values())
    # Test log operations
    log = test_log_local(mscsl, scpsl)
    # Test proofs
    test_proofs(log, mscsl, scpsl)
Esempio n. 17
0
 def _create_trc(self, isd):
     self.trcs[isd] = TRC.from_values(isd, "ISD %s" % isd, 0, {}, {}, {}, 2,
                                      'dns_srv_addr', 2, 3, 18000, True, {})
Esempio n. 18
0
 def _create_trc(self, isd):
     self.trcs[isd] = TRC.from_values(isd, 0, {},
                                      {'ca.com': 'ca.com_cert_base64'}, {},
                                      2, 'dns_srv_addr', 'dns_srv_cert', 2,
                                      3, 2, True, {}, 18000)
Esempio n. 19
0
 def __init__(self, p):
     super().__init__(p)
     self.trc = TRC.from_raw(p.trc, lz4_=True)
Esempio n. 20
0
 def _create_trc(self, isd):
     validity_period = TRC.VALIDITY_PERIOD
     self.trcs[isd] = TRC.from_values(isd, "ISD %s" % isd,
                                      INITIAL_TRC_VERSION, {}, {}, {}, 2,
                                      {}, 2, 3, 18000, False, {},
                                      validity_period)