def _verify_drkey_reply(self, rep, meta): """ Verify that the first order DRKey reply is legit. I.e. the signature matches, timestamp is recent. :param DRKeyReply rep: the first order DRKey reply. :param UDPMetadata meta: the metadata. :returns Certificate of the responder. :rtype: Certificate :raises: SCIONVerificationError """ if meta and meta.ia != rep.isd_as: raise SCIONVerificationError("Response from other ISD-AS: %s" % rep.isd_as) if drkey_time() - rep.p.timestamp > DRKEY_REQUEST_TIMEOUT: raise SCIONVerificationError("Expired reply from %s. %ss old. Max %ss" % ( rep.isd_as, drkey_time() - rep.p.timestamp, DRKEY_REQUEST_TIMEOUT)) trc = self.trust_store.get_trc(rep.isd_as[0]) chain = self.trust_store.get_cert(rep.isd_as, rep.p.certVerSrc) err = [] if not chain: self._send_cc_request(rep.isd_as, rep.p.certVerSrc) err.append("Certificate not present for %s(v: %s)" % (rep.isd_as, rep.p.certVerSrc)) if not trc: self._send_trc_request(rep.isd_as[0], rep.p.trcVer, rep.isd_as[1]) err.append("TRC not present for %s(v: %s)" % (rep.isd_as[0], rep.p.trcVer)) if err: raise SCIONVerificationError(", ".join(err)) raw = get_signing_input_rep(rep.isd_as, rep.p.timestamp, rep.p.expTime, rep.p.cipher) try: verify_sig_chain_trc(raw, rep.p.signature, rep.isd_as, chain, trc) except SCIONVerificationError as e: raise SCIONVerificationError(str(e)) return chain.certs[0]
def _verify_drkey_request(self, req, meta): """ Verify that the first order DRKey request is legit. I.e. the signature is valid, the correct ISD AS is queried, timestamp is recent. :param DRKeyRequest req: the first order DRKey request. :param UDPMetadata meta: the metadata. :returns Certificate of the requester. :rtype: Certificate :raises: SCIONVerificationError """ if self.addr.isd_as != req.isd_as: raise SCIONVerificationError("Request for other ISD-AS: %s" % req.isd_as) if drkey_time() - req.p.timestamp > DRKEY_REQUEST_TIMEOUT: raise SCIONVerificationError("Expired request from %s. %ss old. Max %ss" % ( meta.ia, drkey_time() - req.p.timestamp, DRKEY_REQUEST_TIMEOUT)) trc = self.trust_store.get_trc(meta.ia[0]) chain = self.trust_store.get_cert(meta.ia, req.p.certVer) err = [] if not chain: self._send_cc_request(meta.ia, req.p.certVer) err.append("Certificate not present for %s(v: %s)" % (meta.ia, req.p.certVer)) if not trc: self._send_trc_request(meta.ia[0], req.p.trcVer, meta.ia[1]) err.append("TRC not present for %s(v: %s)" % (meta.ia[0], req.p.trcVer)) if err: raise SCIONVerificationError(", ".join(err)) raw = drkey_signing_input_req(req.isd_as, req.p.flags.prefetch, req.p.timestamp) try: verify_sig_chain_trc(raw, req.p.signature, meta.ia, chain, trc) except SCIONVerificationError as e: raise SCIONVerificationError(str(e)) return chain.certs[0]
def get_drkey_reply(sv, src_ia, dst_ia, priv_key, signing_key, cert_ver, dst_cert, trc_ver): """ Generate a DRKeyReply. The Reply is signed with the signing key. The contained drkey is encrypted using the public key of the destination certificate. :param DRKeySecretValue sv: the local secret value used to derive the DRKey. :param ISD_AS src_ia: the local ISD-AS address. :param ISD_AS dst_ia: the ISD-AS for which the DRKey is computed. :param PrivateKey priv_key: local private key. :param SigningKey signing_key: local signing key. :param int cert_ver: version of the certificate, priv_key and signing_key are associated with. :param Certificate dst_cert: the certificated of the destination ISD-AS. :param int trc_ver: version of trc associated with cert_ver. :returns: the resulting DRKeyReply :rtype: DRKeyReply """ drkey = derive_drkey_raw(sv, dst_ia) cipher = bytes( encrypt(drkey, priv_key, PublicKey(dst_cert.subject_enc_key_raw))) timestamp = drkey_time() signature = sign( get_signing_input_rep(src_ia, timestamp, sv.exp_time, cipher), signing_key) return DRKeyReply.from_values(src_ia, timestamp, sv.exp_time, cipher, signature, cert_ver, dst_cert.version, trc_ver)
def get_drkey_request(dst_ia, prefetch, signing_key, cert_ver, trc_ver): """ Generate a DRKeyRequest. The Request is signed with the signing key of the specified certificate. :param ISD_AS dst_ia: destination of the DRKey request. :param Bool prefetch: indicator if prefetch (True) or not (False). :param SigningKey signing_key: the signing key :param int cert_ver: version of the certificate associated with singing key :param int trc_ver: version of the trc associated with the certificate. :returns: the signed DRKeyRequest. :rtype: DRKeyRequest """ timestamp = drkey_time() signature = sign(drkey_signing_input_req(dst_ia, prefetch, timestamp), signing_key) return DRKeyRequest.from_values(prefetch, dst_ia, timestamp, signature, cert_ver, trc_ver)