Пример #1
0
    def verify(self, subject, issuer_cert):
        """
        Perform one step verification.

        :param str subject:
            the certificate subject. It can either be an AS, an email address or
            a domain address.
        :param str issuer_cert: the certificate issuer. It can only be an AS.
        :raises: SCIONVerificationError if the verification fails.
        """
        if subject != self.subject:
            raise SCIONVerificationError(
                "The given subject (%s) doesn't match the certificate's subject (%s):\n%s"
                % (subject, self.subject, self))
        if int(time.time()) >= self.expiration_time:
            raise SCIONVerificationError("This certificate expired:\n%s" %
                                         self)
        if int(time.time()) >= issuer_cert.expiration_time:
            raise SCIONVerificationError(
                "The issuer certificate expired:\n%s" % issuer_cert)
        try:
            self._verify_signature(self.signature_raw,
                                   issuer_cert.subject_sig_key_raw)
        except SCIONVerificationError:
            raise SCIONVerificationError("Signature verification failed:\n%s" %
                                         self)
Пример #2
0
    def verify(self, subject, trc):
        """
        Perform the entire chain verification. First verifies the AS certificate against the core AS
        certificate, then verifies the core AS certificate against the TRC.

        :param str subject:
            the subject of the first certificate in the certificate chain.
        :param trc: TRC containing all root of trust certificates for one ISD.
        :type trc: :class:`TRC`
        :raises: SCIONVerificationError if the verification fails.
        """
        # Verify AS certificate against core AS certificate
        try:
            self.as_cert.verify(subject, self.core_as_cert.subject_sig_key_raw)
        except SCIONVerificationError as e:
            raise SCIONVerificationError(
                "AS certificate verification failed: %s" % e)
        # Verify core AS certificate against TRC
        try:
            self.core_as_cert.verify(
                self.as_cert.issuer,
                trc.core_ases[self.core_as_cert.issuer][ONLINE_KEY_STRING])
        except SCIONVerificationError as e:
            raise SCIONVerificationError(
                "Core AS certificate verification failed: %s" % e)
Пример #3
0
def verify_sig_chain_trc(msg, sig, subject, chain, trc):
    """
    Verify whether the packed message with attached signature is validly
    signed by a particular subject belonging to a valid certificate chain.

    :param bytes msg: message corresponding to the given signature.
    :param bytes sig: signature computed on msg.
    :param ISD_AS subject: signer identity.
    :param CertificateChain chain: Certificate chain containing the signing entity's certificate.
    :param TRC trc: Issuing TRC containing all root of trust certificates for one ISD.

    :raises: SCIONVerificationError if the verification fails.
    """
    assert isinstance(chain, CertificateChain)
    assert isinstance(trc, TRC)
    subject = str(subject)
    try:
        chain.verify(subject, trc)
    except SCIONVerificationError as e:
        raise SCIONVerificationError(
            "The certificate chain verification failed:\n%s" % e)
    verifying_key = None
    for signer_cert in chain.certs:
        if signer_cert.subject == subject:
            verifying_key = signer_cert.subject_sig_key_raw
            break
    if verifying_key is None:
        if subject not in trc.core_ases:
            raise SCIONVerificationError(
                "Signer's public key has not been found: %s" % subject)
        verifying_key = trc.core_ases[subject].subject_sig_key_raw
    verify(msg, sig, verifying_key)
Пример #4
0
    def verify(self, subject, verifying_key):
        """
        Perform one step verification.

        :param str subject:
            the certificate subject. It can either be an AS, an email address or
            a domain address.
        :param bytes verifying_key: the key to be used for signature verification.
        :raises: SCIONVerificationError if the verification fails.
        """
        if self.version == 0:
            raise SCIONVerificationError("Invalid certificate version 0:\n%s" %
                                         self)
        if subject != self.subject:
            raise SCIONVerificationError(
                "The given subject (%s) doesn't match the certificate's subject (%s):\n%s"
                % (subject, self.subject, self))
        if int(time.time()) >= self.expiration_time:
            raise SCIONVerificationError("This certificate expired:\n%s" %
                                         self)
        try:
            self._verify_signature(self.signature_raw, verifying_key)
        except SCIONVerificationError:
            raise SCIONVerificationError("Signature verification failed:\n%s" %
                                         self)
Пример #5
0
    def verify(self, subject, trc):
        """
        Perform the entire chain verification. It verifies each pair and at the
        end verifies the last certificate of the chain with the root certificate
        that was used to sign it.

        :param str subject:
            the subject of the first certificate in the certificate chain.
        :param trc: TRC containing all root of trust certificates for one ISD.
        :type trc: :class:`TRC`
        :raises: SCIONVerificationError if the verification fails.
        """
        if not self.certs:
            raise SCIONVerificationError(
                "The certificate chain is not initialized.")
        cert = self.certs[0]
        for issuer_cert in self.certs[1:]:
            if issuer_cert.subject == subject:
                break
            cert.verify(subject, issuer_cert)
            cert = issuer_cert
            subject = cert.subject
        # First check whether a root cert was added to the chain.
        if cert.issuer != subject:
            raise SCIONVerificationError(
                "Root Certificate added to chain:\n%s" % cert)
        # Try to find a root cert in the trc.
        try:
            cert.verify_core(trc.core_ases[cert.issuer][ONLINE_KEY_STRING])
        except SCIONVerificationError:
            raise SCIONVerificationError(
                "Core AS certificate verification failed.")
Пример #6
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]
Пример #7
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]
Пример #8
0
    def check_active(self, max_trc=None):
        """
        Check if trusted TRC is active and can be used for certificate chain verification.

        :param TRC max_trc: newest available TRC for same ISD. (If none, self is newest TRC)
        :raises: SCIONVerificationError
        """
        if self.quarantine:
            raise SCIONVerificationError("Early announcement")
        now = int(time.time())
        if not (self.create_time <= now <= self.exp_time):
            raise SCIONVerificationError(
                "Current time outside of validity period. "
                "Now %s Creation %s Expiration %s" %
                (now, self.create_time, self.exp_time))
        if not max_trc or self.version == max_trc.version:
            return
        if self.version + 1 != max_trc.version:
            raise SCIONVerificationError(
                "Inactive TRC version: %s. Expected %s or %s" %
                (self.version, max_trc.version, max_trc.version - 1))
        if now > max_trc.create_time + max_trc.grace_period:
            raise SCIONVerificationError(
                "TRC grace period has passed. Now %s Expiration %s" %
                (now, max_trc.create_time + max_trc.grace_period))
Пример #9
0
def verify_chain_trc(subject, chain, trc):
    """
    Verify the certificate chain for subject.
    """
    subject = str(subject)
    try:
        chain.verify(subject, trc)
    except SCIONVerificationError as e:
        raise SCIONVerificationError("The certificate chain verification failed:\n%s" % e)
Пример #10
0
 def _verify_exp_time(self, exp_time, chain):
     """
     Verify that certificate chain cover the expiration time.
     :raises SCIONVerificationError
     """
     # chain is only verifiable if TRC.exp_time >= CoreCert.exp_time >= LeafCert.exp_time
     if chain.as_cert.expiration_time < exp_time:
         raise SCIONVerificationError(
             "Certificate chain %sv%s expires before path segment" % chain.get_leaf_isd_as_ver())
Пример #11
0
    def verify_update(self, old_trc):
        """
        Verify TRC update.
        Unsuccessful verification raises an error.

        :param TRC old_trc: a verified TRC, used as a trust anchor.
        :raises: SCIONVerificationError
        """
        if old_trc.isd != self.isd:
            raise SCIONVerificationError("Invalid TRC ISD %s. Expected %s" % (
                self.isd, old_trc.isd))
        if old_trc.version + 1 != self.version:
            raise SCIONVerificationError("Invalid TRC version %s. Expected %s" % (
                self.version, old_trc.version + 1))
        if self.create_time < old_trc.create_time + old_trc.grace_period:
            raise SCIONVerificationError("Invalid timestamp %s. Expected > %s " % (
                self.create_time, old_trc.create_time + old_trc.grace_period))
        if self.quarantine or old_trc.quarantine:
            raise SCIONVerificationError("Early announcement")
        self._verify_signatures(old_trc)
Пример #12
0
    def verify(self, trusted_trc):
        """
        Verify TRC based on a trusted TRC.

        :param TRC trusted_trc: a verified TRC, used as a trust anchor.
        :raises: SCIONVerificationError
        """
        if self.version == 0:
            raise SCIONVerificationError("Invalid TRC version 0")
        if self.isd == trusted_trc.isd:
            self.verify_update(trusted_trc)
        else:
            self.verify_xsig(trusted_trc)
Пример #13
0
def verify(msg, sig, verifying_key):
    """
    Verify a signature.

    :param bytes msg: message that was signed.
    :param bytes sig: signature to verify.
    :param bytes verifying_key: verifying key from generate_signature_keypair().
    :returns: True or False whether the verification succeeds or fails.
    :rtype: boolean
    """
    try:
        return msg == VerifyKey(verifying_key).verify(msg, sig)
    except BadSignatureError:
        raise SCIONVerificationError("Signature corrupt or forged.") from None
Пример #14
0
    def verify(self, spld: SignedCtrlPayload) -> bool:
        """
        Verify checks if the signed control payload can be verified.
        If not, an error is raised.

        :param SignedCtrlPayload spld: the signed control payload to be verified.
        :returns: whether the verification was successful.
        :rtype: bool
        :raises: SCIONVerificationError
        """
        try:
            cpld = spld.pld()
        except SCIONParseError as e:
            raise SCIONVerificationError(
                "Unable to unpack control payload. Error: %s" % e) from None
        if self.ignore_sign(cpld):
            return True
        try:
            vkey = self.get_verifying_key(spld.psign)
        except (SCIONKeyError, SCIONParseError, SCIONVerificationError) as e:
            raise SCIONVerificationError(
                "Unable to fetch verifying key. Error: %s" % e) from None
        return spld.verify(vkey)
Пример #15
0
def verify_sig_chain_trc(msg, sig, subject, chain, trc):
    """
    Verify whether the packed message with attached signature is validly
    signed by a particular subject belonging to a valid certificate chain.

    :param bytes msg: message corresponding to the given signature.
    :param bytes sig: signature computed on msg.
    :param ISD_AS subject: signer identity.
    :param CertificateChain chain: Certificate chain containing the signing entity's certificate.
    :param TRC trc: Issuing TRC containing all root of trust certificates for one ISD.

    :raises: SCIONVerificationError if the verification fails.
    """
    assert isinstance(chain, CertificateChain), type(chain)
    assert isinstance(trc, TRC), type(trc)
    verify_chain_trc(subject, chain, trc)
    verifying_key = chain.as_cert.subject_sig_key_raw
    if not verifying_key:
        raise SCIONVerificationError("Signer's public key has not been found: %s" % subject)
    verify(msg, sig, verifying_key)
Пример #16
0
    def _verify_signatures(self, old_trc):
        """
        Perform signature verification for core signatures as defined
        in old TRC. Raises an error if verification is unsuccessful.

        :param: TRC old_trc: the previous TRC which has already been verified.
        :raises: SCIONVerificationError
        """
        # Only look at signatures which are from core ASes as defined in old TRC
        val_count = 0
        # Count number of verifiable signatures
        for signer in old_trc.core_ases.keys():
            public_key = old_trc.core_ases[signer][ONLINE_KEY_STRING]
            try:
                verify(self._sig_input(), self.signatures[signer], public_key)
                val_count += 1
            except (SCIONVerificationError, KeyError):
                continue
        # Check if enough valid signatures
        if val_count < old_trc.quorum_trc:
            raise SCIONVerificationError("Not enough valid signatures %s. Expected %s" % (
                val_count, old_trc.quorum_trc))
Пример #17
0
    def verify(self, subject, trc):
        """
        Perform the entire chain verification. First verifies the AS certificate against the core AS
        certificate, then verifies the core AS certificate against the TRC.

        :param str subject:
            the subject of the first certificate in the certificate chain.
        :param trc: TRC containing all root of trust certificates for one ISD.
        :type trc: :class:`TRC`
        :raises: SCIONVerificationError if the verification fails.
        """
        # Verify AS certificate against core AS certificate
        leaf = self.as_cert
        core = self.core_as_cert
        if leaf.issuing_time < core.issuing_time:
            raise SCIONVerificationError(
                "AS certificate verification failed: Leaf issued before core certificate. Leaf: %s "
                "Core: %s" % (iso_timestamp(
                    leaf.issuing_time), iso_timestamp(core.issuing_time)))
        if leaf.expiration_time > core.expiration_time:
            raise SCIONVerificationError(
                "AS certificate verification failed: Leaf expires after core certificate. Leaf: %s "
                "Core: %s" % (iso_timestamp(leaf.expiration_time),
                              iso_timestamp(core.expiration_time)))
        if not core.can_issue:
            raise SCIONVerificationError(
                "AS certificate verification failed: Core certificate cannot issue certificates"
            )
        try:
            leaf.verify(subject, core.subject_sig_key_raw)
        except SCIONVerificationError as e:
            raise SCIONVerificationError(
                "AS certificate verification failed: %s" % e)
        # Verify core AS certificate against TRC
        if core.expiration_time > trc.exp_time:
            raise SCIONVerificationError(
                "Core AS certificate verification failed: Core certificate expires after TRC. "
                "Core: %s TRC: %s" % (iso_timestamp(
                    core.expiration_time), iso_timestamp(trc.exp_time)))
        try:
            core.verify(leaf.issuer,
                        trc.core_ases[core.issuer][ONLINE_KEY_STRING])
        except SCIONVerificationError as e:
            raise SCIONVerificationError(
                "Core AS certificate verification failed: %s" % e)