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, )
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()
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
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)
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])
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)
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
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
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)