Example #1
0
    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]
Example #2
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]
Example #3
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)
Example #4
0
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)