def _assign_keys(self, as_):
     isd_as_id = as_.isd_as_str()
     chain = self.loader.certs[isd_as_id]
     as_.certificate_chain = chain
     assert (chain['0']['Subject'] == isd_as_id)
     as_.sig_pub_key = chain['0']['SubjectSignKey']
     as_.enc_pub_key = chain['0']['SubjectEncKey']
     as_.sig_priv_key = self.loader.keys_sig[isd_as_id]
     as_.enc_priv_key = self.loader.keys_decrypt[isd_as_id]
     as_.master_as_key = self.loader.master0s[isd_as_id]
     if as_.is_core:
         trc = self.loader.trcs[as_.isd.isd_id]
         as_.core_offline_priv_key = self.loader.core_keys_offline[
             isd_as_id]
         as_.core_offline_pub_key = trc['CoreASes'][isd_as_id]['OfflineKey']
         as_.core_online_priv_key = self.loader.core_keys_online[isd_as_id]
         as_.core_online_pub_key = trc['CoreASes'][isd_as_id]['OnlineKey']
         as_.core_sig_priv_key = self.loader.core_keys_sig[isd_as_id]
         as_.core_sig_pub_key = base64.b64encode(
             SigningKey(base64.b64decode(
                 as_.core_sig_priv_key)).verify_key._key).decode()
         core_cert = Certificate(
             chain['1'])  # load the one from the json file and adapt it
         core_cert.subject = as_.isd_as_str()
         core_cert.issuer = as_.isd_as_str()  # self signed
         core_cert.subject_enc_key = ''
         core_cert.subject_sig_key = as_.core_sig_pub_key
         core_cert.sign(base64.b64decode(as_.core_online_priv_key))
         as_.core_certificate = core_cert.dict()
         # redo the AS cert in the chain
         cert = Certificate(chain['0'])
         cert.issuer = as_.isd_as_str()
         cert.sign(base64.b64decode(as_.core_sig_priv_key))
         as_.certificate_chain = {'0': cert.dict(), '1': core_cert.dict()}
     as_.save()
Example #2
0
def generate_as_certificate_chain(subject_as, issuing_as):
    """
    Create or update the AS Certificate for `subject_as`, issued by `issuing_as`.
    If the AS already has an AS Certificate, the version number is incremented for the
    new certificate.

    Requires that `issuing_as` is a core AS with an existing/up to date Core AS Certificate.
    Requires that the ASes are in the same ISD and that the TRC exists/is up to date.

    :param AS subject_as: Subject AS
    :param AS issuing_AS: Issuing AS
    :returns: the AS Certificate chain as a dict
    """
    assert issuing_as.is_core
    assert issuing_as.core_certificate
    assert issuing_as.isd == subject_as.isd
    isd = issuing_as.isd
    assert isd.trc

    trc_version = isd.trc['Version']

    if subject_as.certificate_chain:
        version = subject_as.certificate_chain["0"]['Version'] + 1
    else:
        version = 1

    core_as_cert = Certificate(issuing_as.core_certificate)

    cert = Certificate.from_values(
        subject=subject_as.isd_as_str(),
        issuer=issuing_as.isd_as_str(),
        trc_version=trc_version,
        version=version,
        comment="AS Certificate",
        can_issue=False,
        validity_period=core_as_cert.expiration_time - int(time.time()) - 1,
        subject_enc_key=base64.b64decode(
            subject_as.enc_pub_key),  # will be encoded again, but WTH
        subject_sig_key=base64.b64decode(subject_as.sig_pub_key),
        iss_priv_key=base64.b64decode(issuing_as.core_sig_priv_key))
    # CertificateChain does NOT have a dict method (only "to_json"), so we just do this manually:
    cert_chain_dict = {"0": cert.dict(), "1": core_as_cert.dict()}
    return cert_chain_dict