def _sig_input(self, idx=None): if idx is None: idx = len(self.p.asEntries) - 1 b = [self.p.sdata] for i in range(idx + 1): sblob = self.p.asEntries[i] b.append(sblob.blob) ssign = ProtoSign(sblob.sign) b.append(ssign.sig_pack(i != idx)) return b"".join(b)
class SignedCtrlPayload(Cerealizable): NAME = "SignedCtrlPayload" P_CLS = P.SignedCtrlPld def __init__(self, p): # pragma: no cover super().__init__(p) self.psign = ProtoSign(self.p.sign) @classmethod def from_raw(cls, raw): data = Raw(raw, "%s.from_raw" % cls.NAME) plen = struct.unpack("!I", data.pop(4))[0] if len(data) != plen: raise SCIONParseError( "Payload length mismatch. Expected: %s Actual: %s" % (plen, len(data))) try: p = cls.P_CLS.from_bytes_packed(data.pop()).as_builder() except capnp.lib.capnp.KjException as e: raise SCIONParseError("Unable to parse %s capnp message: %s" % (cls.NAME, e)) from None return cls.from_proto(p) @classmethod def from_values(cls, cpld_raw, sign=None): if not sign: sign = ProtoSign.from_values(ProtoSignType.NONE, b"") return cls(cls.P_CLS.new_message(blob=cpld_raw, sign=sign.p)) def sign(self, key): return self.psign.sign(key, self.p.blob) def verify(self, key): return self.psign.verify(key, self.p.blob) def pack(self): # pragma: no cover raw = self.proto().to_bytes_packed() return struct.pack("!I", len(raw)) + raw def pld(self): return CtrlPayload.from_raw(self.p.blob)
def create_sign(ia: ISD_AS, chain_ver: int, trc_ver: int) -> ProtoSign: """ Create ProtoSign for the specified values with ed25519 as the singing algorithm. :param ISD_AS ia: ISD-AS of the signing AS. :param int chain_ver: Version of the certificate authenticating the signing key. :param int trc_ver: Version of the TRC authenticating the certificate chain. :returns: The sign object :rtype: ProtoSign """ sign = DefaultSignSrc.from_values(ia, chain_ver, trc_ver) return ProtoSign.from_values(ProtoSignType.ED25519, sign.pack())
def verify(self, key, idx=None): if idx is None: idx = len(self.p.asEntries) - 1 s = ProtoSign(self.p.asEntries[idx].sign) return s.verify(key, self._sig_input(idx))
def sign(self, key): # pragma: no cover assert len(self.p.asEntries) > 0, "No ASMarkings to sign" s = ProtoSign(self.p.asEntries[-1].sign) s.sign(key, self._sig_input())
def from_values(cls, cpld_raw, sign=None): if not sign: sign = ProtoSign.from_values(ProtoSignType.NONE, b"") return cls(cls.P_CLS.new_message(blob=cpld_raw, sign=sign.p))
def __init__(self, p): # pragma: no cover super().__init__(p) self.psign = ProtoSign(self.p.sign)
def from_values(cls, cpld_raw, sig_type=ProtoSignType.NONE, sig_src=b""): s = ProtoSign.from_values(sig_type, sig_src) return cls(cls.P_CLS.new_message(blob=cpld_raw, sign=s.p))