Beispiel #1
0
def check_cert_chain(testcase, cert_chain):
    """
    Check that the AS's certificate chain can be verified with the issuer certificate.
    """
    testcase.assertIsNotNone(cert_chain)

    leaf = cert_chain.certificate[1]
    leaf_pld = jws.decode_payload(leaf)

    testcase.assertEqual(leaf_pld["version"], cert_chain.version)
    testcase.assertEqual(leaf_pld["subject"], cert_chain.AS.isd_as_str())

    issuer = leaf_pld["issuer"]
    issuer_ia = issuer["isd_as"]
    issuer_as = issuer_ia.split('-')[1]
    issuer_ver = issuer["certificate_version"]

    # Check that the issuer certificate in the chain is identical to the issuer cert in the DB:
    issuer_cert = Certificate.objects.get(type=Certificate.ISSUER,
                                          AS__as_id=issuer_as,
                                          version=issuer_ver)
    testcase.assertEqual(issuer_cert.certificate, cert_chain.certificate[0])

    # Verify the signature
    issuer_pld = jws.decode_payload(issuer_cert.certificate)
    issuer_pub_key = issuer_pld["keys"]["issuing"]["key"]
    sig_valid = jws.verify(leaf["payload"], leaf["protected"],
                           leaf["signature"], issuer_pub_key)
    testcase.assertTrue(sig_valid)
Beispiel #2
0
def check_trc(testcase, isd, expected_core_ases=None, expected_version=None):
    """
    Check the ISD's latest TRC
    :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.
    """
    if expected_core_ases is None:
        expected_core_ases = set(as_.as_id
                                 for as_ in isd.ases.filter(is_core=True))

    trc = isd.trcs.latest_or_none()
    if len(expected_core_ases) > 0:
        testcase.assertIsNotNone(trc)
    if expected_version is not None:
        testcase.assertEqual(trc.version, expected_version)
    if trc is None:
        return

    trc_pld = jws.decode_payload(trc.trc)
    testcase.assertEqual(trc_pld['trc_version'], trc.version)
    testcase.assertEqual(set(trc_pld['primary_ases'].keys()),
                         set(expected_core_ases))

    if trc.version > 1:
        # Check that TRC update is valid
        prev_trc = isd.trcs.get(version=trc.version - 1)
        prev_trc_pld = jws.decode_payload(prev_trc.trc)
        # Minimal check:
        voters = set(trc_pld['votes'].keys())
        allowed_voters = set(prev_trc_pld['primary_ases'].keys())
        testcase.assertTrue(voters.issubset(allowed_voters))
        testcase.assertGreaterEqual(len(trc_pld['votes']),
                                    prev_trc_pld['voting_quorum'])
Beispiel #3
0
def check_issuer_cert(testcase, issuer_cert, expected_trc_version=None):
    """
    Check that the issuer certificate can be verified with a TRC.
    Check that the certificate is issued by the expected_trc_version, if set.
    """
    testcase.assertIsNotNone(issuer_cert)

    cert = issuer_cert.certificate
    cert_pld = jws.decode_payload(cert)

    testcase.assertEqual(cert_pld["version"], issuer_cert.version)
    testcase.assertEqual(cert_pld["subject"], issuer_cert.AS.isd_as_str())

    subject_ia = cert_pld["subject"]
    subject_as = subject_ia.split('-')[1]
    trc_version = cert_pld["issuer"]["trc_version"]
    if expected_trc_version is not None:
        testcase.assertEqual(trc_version, expected_trc_version)

    trc = TRC.objects.get(isd=issuer_cert.AS.isd, version=trc_version)
    trc_pld = jws.decode_payload(trc.trc)
    issuing_grant_pub_key = trc_pld["primary_ases"][subject_as]["keys"][
        "issuing_grant"]["key"]
    sig_valid = jws.verify(cert["payload"], cert["protected"],
                           cert["signature"], issuing_grant_pub_key)

    testcase.assertTrue(sig_valid)
Beispiel #4
0
    def gen_trc_update(self, primary_ases, prev_trc, prev_voting_offline):
        """
        Helper: create update TRC
        """

        # decode prev payload to find next version number
        # we dont need to do this in production, but here it serves as a little sanity check for
        # the payload.
        prev = jws.decode_payload(prev_trc)
        prev_version = prev["trc_version"]
        self.assertGreaterEqual(1, prev_version)
        version = prev_version + 1

        # define validity time with arbitrary time offset from previous validity start.
        # key lifetime is not extended, so validty end is the same
        # Just for "fun", not really relevant.
        prev_not_before = datetime.utcfromtimestamp(
            prev['validity']['not_before'])
        prev_not_after = datetime.utcfromtimestamp(
            prev['validity']['not_after'])
        not_before = prev_not_before + timedelta(days=31)
        not_after = prev_not_after

        trc = trcs.generate_trc(self.isd1, version, DEFAULT_TRC_GRACE_PERIOD,
                                not_before, not_after, primary_ases, prev_trc,
                                prev_voting_offline)

        return trc
Beispiel #5
0
def _decode_primary_ases(trc):
    payload = jws.decode_payload(trc)

    def _key_info(key_entry):
        return Key(
            version=key_entry['key_version'],
            priv_key=None,
            pub_key=key_entry['key'],
        )

    def _core_keys(as_entry):
        return CoreKeys(**{
            usage: _key_info(key_entry) for usage, key_entry in as_entry['keys'].items()
        })

    return {as_id: _core_keys(as_entry)
            for as_id, as_entry in payload['primary_ases'].items()}