Example #1
0
 def _gen_as_certs(self, topo_id, as_conf):
     # Self-signed if cert_issuer is missing.
     issuer = TopoID(as_conf.get('cert_issuer', str(topo_id)))
     # Make sure that issuer is a core AS
     if issuer not in self.pub_online_root_keys:
         raise SCIONParseError("Certificate issuer is not a core AS: %s" % issuer)
     # Create core AS certificate
     if self.is_core(as_conf):
         signing_key = self.priv_online_root_keys[topo_id]
         can_issue = True
         comment = "Core AS Certificate"
         self.core_certs[topo_id] = Certificate.from_values(
             str(topo_id), str(issuer), INITIAL_TRC_VERSION, INITIAL_CERT_VERSION,
             comment, can_issue, DEFAULT_CORE_CERT_VALIDITY, self.enc_pub_keys[topo_id],
             self.pub_core_sig_keys[topo_id], signing_key
         )
     # Create regular AS certificate
     signing_key = self.priv_core_sig_keys[issuer]
     can_issue = False
     comment = "AS Certificate"
     self.certs[topo_id] = Certificate.from_values(
         str(topo_id), str(issuer), INITIAL_TRC_VERSION, INITIAL_CERT_VERSION,
         comment, can_issue, DEFAULT_LEAF_CERT_VALIDITY, self.enc_pub_keys[topo_id],
         self.sig_pub_keys[topo_id], signing_key, issuing_time=int(time.time())+2,
     )
Example #2
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'])
Example #3
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_version = isd.trc['Version']

    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=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()
Example #4
0
def generate_certificate(joining_ia, core_ia, core_sign_priv_key_file, core_cert_file, trc_file):
    """
    """
    core_ia_chain = CertificateChain.from_raw(read_file(core_cert_file))
    # AS cert is always expired one second before the expiration of the Core AS cert
    validity = core_ia_chain.core_as_cert.expiration_time - int(time.time()) - 1
    comment = "AS Certificate"
    core_ia_sig_priv_key = base64.b64decode(read_file(core_sign_priv_key_file))
    public_key_sign, private_key_sign = generate_sign_keypair()
    public_key_encr, private_key_encr = generate_enc_keypair()
    cert = Certificate.from_values(
        str(joining_ia), str(core_ia), INITIAL_TRC_VERSION, INITIAL_CERT_VERSION, comment,
        False, validity, public_key_encr, public_key_sign, core_ia_sig_priv_key)
    sig_priv_key = base64.b64encode(private_key_sign).decode()
    enc_priv_key = base64.b64encode(private_key_encr).decode()
    sig_priv_key_raw = base64.b64encode(SigningKey(private_key_sign)._signing_key).decode()
    joining_ia_chain = CertificateChain([cert, core_ia_chain.core_as_cert]).to_json()
    trc = open(trc_file).read()
    master_as_key = base64.b64encode(Random.new().read(16)).decode('utf-8')
    key_dict = {
        'enc_key': enc_priv_key,
        'sig_key': sig_priv_key,
        'sig_key_raw': sig_priv_key_raw,
        'master_as_key': master_as_key,
    }
    as_obj = ASCredential(joining_ia_chain, trc, key_dict)
    return as_obj
Example #5
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)
Example #6
0
 def _gen_as_certs(self, topo_id, as_conf):
     # Self-signed if cert_issuer is missing.
     issuer = TopoID(as_conf.get('cert_issuer', str(topo_id)))
     self.certs[topo_id] = Certificate.from_values(
         str(topo_id), str(issuer), INITIAL_CERT_VERSION, "", False,
         self.enc_pub_keys[topo_id], self.sig_pub_keys[topo_id],
         self.sig_priv_keys[issuer])
Example #7
0
 def from_raw(cls, chain_raw, lz4_=False):
     if lz4_:
         chain_raw = lz4.loads(chain_raw).decode("utf-8")
     chain = json.loads(chain_raw)
     certs = []
     for k in sorted(chain):
         cert = Certificate(chain[k])
         certs.append(cert)
     return CertificateChain(certs)
Example #8
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
Example #9
0
def accept_join_request(request, isd_as, request_id):
    """
    Accepts the join request, assigns a new AS ID to
    the requesting party and creates the certificate.
    This function is only executed by a core AS.
    """
    current_page = request.META.get('HTTP_REFERER')
    coord = get_object_or_404(OrganisationAdmin, user_id=request.user.id)
    logger.info("new AS name = %s isd_as = %s", request.POST['newASname'],
                isd_as)

    joining_as = request.POST['newASname']
    sig_pub_key = from_b64(request.POST['sig_pub_key'])
    enc_pub_key = from_b64(request.POST['enc_pub_key'])
    own_isdas = ISD_AS(isd_as)
    signing_as = AD.objects.get(as_id=own_isdas[1], isd=own_isdas[0])
    signing_as_sig_priv_key = from_b64(signing_as.sig_priv_key)
    signing_as_trc = str(signing_as.trc)
    joining_isdas = ISD_AS.from_values(own_isdas[0], joining_as)

    certificate = Certificate.from_values(
        str(joining_isdas),
        sig_pub_key,
        enc_pub_key,
        str(own_isdas),
        signing_as_sig_priv_key,
        INITIAL_CERT_VERSION,
    )

    accept_join_dict = {
        "isdas": str(own_isdas),
        "join_reply": {
            "request_id": int(request_id),
            "joining_isdas": str(joining_isdas),
            "signing_isdas": str(own_isdas),
            "certificate": str(certificate),
            "trc": signing_as_trc
        }
    }
    logger.info("accept join dict = %s", accept_join_dict)
    request_url = urljoin(
        COORD_SERVICE_URI,
        posixpath.join(UPLOAD_JOIN_REPLY_SVC, coord.key, coord.secret))
    headers = {'content-type': 'application/json'}
    try:
        requests.post(request_url, json=accept_join_dict, headers=headers)
    except requests.RequestException:
        logger.error("Failed to upload join reply to coordination service")
    return redirect(current_page)
Example #10
0
 def __init__(self, trc_dict):
     """
     :param dict trc_dict: TRC as dict.
     """
     for k, (name, type_) in self.FIELDS_MAP.items():
         val = trc_dict[k]
         if type_ in (int,):
             val = int(val)
         elif type_ in (dict, ):
             val = copy.deepcopy(val)
         setattr(self, name, val)
     for subject in trc_dict[CORE_ASES_STRING]:
         cert_dict = base64.b64decode(
             trc_dict[CORE_ASES_STRING][subject]).decode('utf-8')
         self.core_ases[subject] = Certificate(json.loads(cert_dict))
     for subject in trc_dict[SIGNATURES_STRING]:
         self.signatures[subject] = \
             base64.b64decode(trc_dict[SIGNATURES_STRING][subject])
Example #11
0
def generate_certificate(joining_ia, core_ia, core_sign_priv_key_file,
                         core_cert_file, trc_file):
    """
    """
    validity = Certificate.AS_VALIDITY_PERIOD
    comment = "AS Certificate"
    core_ia_sig_priv_key = base64.b64decode(read_file(core_sign_priv_key_file))
    public_key_sign, private_key_sign = generate_sign_keypair()
    public_key_encr, private_key_encr = generate_enc_keypair()
    cert = Certificate.from_values(str(joining_ia), str(core_ia),
                                   INITIAL_TRC_VERSION, INITIAL_CERT_VERSION,
                                   comment, False, validity, public_key_encr,
                                   public_key_sign, core_ia_sig_priv_key)
    core_ia_chain = CertificateChain.from_raw(read_file(core_cert_file))
    sig_priv_key = base64.b64encode(private_key_sign).decode()
    enc_priv_key = base64.b64encode(private_key_encr).decode()
    joining_ia_chain = CertificateChain([cert, core_ia_chain.core_as_cert
                                         ]).to_json()
    trc = open(trc_file).read()
    master_as_key = base64.b64encode(Random.new().read(16)).decode('utf-8')
    as_obj = ASCredential(sig_priv_key, enc_priv_key, joining_ia_chain, trc,
                          master_as_key)
    return as_obj
Example #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)
 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 #14
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'])