Skip to content

Commit

Permalink
Rework of the revocation authentication, this includes changes in:
Browse files Browse the repository at this point in the history
- Border Router
- SCIOND
- Path Server
- Beacon Server

The hashtree based revocation has been replaced by signed messages.
  • Loading branch information
worxli committed Apr 12, 2018
1 parent c40b81f commit e99d720
Show file tree
Hide file tree
Showing 47 changed files with 463 additions and 1,026 deletions.
4 changes: 2 additions & 2 deletions go/border/ifstate/ifstate.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,12 +68,12 @@ type state struct {
type Info struct {
IfID common.IFIDType
Active bool
RevInfo *path_mgmt.RevInfo
RevInfo *path_mgmt.SignedRevInfo
RawRev common.RawBytes
ActiveMetric prometheus.Gauge
}

func NewInfo(ifID common.IFIDType, active bool, rev *path_mgmt.RevInfo,
func NewInfo(ifID common.IFIDType, active bool, rev *path_mgmt.SignedRevInfo,
rawRev common.RawBytes) *Info {
i := &Info{
IfID: ifID,
Expand Down
13 changes: 8 additions & 5 deletions go/border/revinfo.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,20 +43,23 @@ func (r *Router) RevInfoFwd() {
defer liblog.LogPanicAndExit()
// Run forever.
for args := range r.revInfoQ {
log.Debug("Forwarding revocation", "revInfo", args.RevInfo.String(), "targets", args.Addrs)
revInfo, err := args.SignedRevInfo.RevInfo()
if err != nil {
log.Error("Error getting RevInfo from SignedRevInfo", "err", err)
}
log.Debug("Forwarding revocation", "revInfo", revInfo.String(), "targets", args.Addrs)
for _, svcAddr := range args.Addrs {
r.fwdRevInfo(args.RevInfo, &svcAddr)
r.fwdRevInfo(args.SignedRevInfo, &svcAddr)
}
}

}

// fwdRevInfo forwards RevInfo payloads to a designated local host.
func (r *Router) fwdRevInfo(revInfo *path_mgmt.RevInfo, dstHost addr.HostAddr) {
func (r *Router) fwdRevInfo(signedRevInfo *path_mgmt.SignedRevInfo, dstHost addr.HostAddr) {
ctx := rctx.Get()
// Pick first local address from topology as source.
srcAddr := ctx.Conf.Net.LocAddr[0].PublicAddrInfo(ctx.Conf.Topo.Overlay)
cpld, err := ctrl.NewPathMgmtPld(revInfo, nil, nil)
cpld, err := ctrl.NewPathMgmtPld(signedRevInfo, nil, nil)
if err != nil {
log.Error("Error generating RevInfo Ctrl payload", "err", err)
return
Expand Down
12 changes: 8 additions & 4 deletions go/border/rpkt/path.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ import (
"github.com/scionproto/scion/go/border/rcmn"
"github.com/scionproto/scion/go/lib/assert"
"github.com/scionproto/scion/go/lib/common"
"github.com/scionproto/scion/go/lib/crypto"
"github.com/scionproto/scion/go/lib/scmp"
"github.com/scionproto/scion/go/lib/spath"
)
Expand Down Expand Up @@ -102,13 +101,18 @@ func (rp *RtrPkt) validateLocalIF(ifid *common.IFIDType) error {
return nil
}
// Interface is revoked.
revInfo := state.RevInfo
signedRevInfo := state.RevInfo
revInfo, err := signedRevInfo.RevInfo()
if err != nil {
rp.Warn("Could not parse RevInfo for revoked interface", "ifid", *ifid)
return nil
}
if revInfo == nil {
rp.Warn("No RevInfo for revoked interface", "ifid", *ifid)
return nil
}
// Check that we have a revocation for the current epoch.
if !crypto.VerifyHashTreeEpoch(revInfo.Epoch) {
// Check that the revocation timestamp is within the TTL.
if !revInfo.Valid() {
// If the BR does not have a revocation for the current epoch, it considers
// the interface as active until it receives a new revocation.
newState := ifstate.NewInfo(*ifid, true, nil, nil)
Expand Down
4 changes: 2 additions & 2 deletions go/border/rpkt/payload_scmp.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ import (
)

type RevTokenCallbackArgs struct {
RevInfo *path_mgmt.RevInfo
Addrs []addr.HostSVC
SignedRevInfo *path_mgmt.SignedRevInfo
Addrs []addr.HostSVC
}

// parseSCMPPayload is a hook that can be used for hookPayload, to retrieve the
Expand Down
3 changes: 2 additions & 1 deletion go/border/rpkt/process.go
Original file line number Diff line number Diff line change
Expand Up @@ -333,9 +333,10 @@ func (rp *RtrPkt) processSCMPRevocation() error {
return common.NewBasicError("Invalid SCMP Info type in SCMP packet", nil,
"expected", "*scmp.InfoRevocation", "actual", common.TypeOf(pld.Info))
}
if args.RevInfo, err = path_mgmt.NewRevInfoFromRaw(infoRev.RevToken); err != nil {
if args.SignedRevInfo, err = path_mgmt.NewSignedRevInfoFromRaw(infoRev.RevToken); err != nil {
return common.NewBasicError("Unable to decode revToken", err)
}

intf := rp.Ctx.Conf.Net.IFs[*rp.ifCurr]
rp.SrcIA() // Ensure that rp.srcIA has been set
if (rp.dstIA.I == rp.Ctx.Conf.Topo.ISD_AS.I && intf.Type == topology.CoreLink) ||
Expand Down
50 changes: 0 additions & 50 deletions go/lib/crypto/htree.go

This file was deleted.

2 changes: 1 addition & 1 deletion go/lib/ctrl/path_mgmt/ifstate_infos.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ func (i *IFStateInfos) String() string {
type IFStateInfo struct {
IfID uint64
Active bool
RevInfo *RevInfo
RevInfo *SignedRevInfo
}

func (i *IFStateInfo) String() string {
Expand Down
4 changes: 2 additions & 2 deletions go/lib/ctrl/path_mgmt/path_mgmt.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ type union struct {
SegReply *SegReply
SegReg *SegReg
SegSync *SegSync
RevInfo *RevInfo
RevInfo *SignedRevInfo
IFStateReq *IFStateReq `capnp:"ifStateReq"`
IFStateInfos *IFStateInfos `capnp:"ifStateInfos"`
}
Expand All @@ -50,7 +50,7 @@ func (u *union) set(c proto.Cerealizable) error {
case *SegSync:
u.Which = proto.PathMgmt_Which_segSync
u.SegSync = p
case *RevInfo:
case *SignedRevInfo:
u.Which = proto.PathMgmt_Which_revInfo
u.RevInfo = p
case *IFStateReq:
Expand Down
67 changes: 51 additions & 16 deletions go/lib/ctrl/path_mgmt/rev_info.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,26 +18,55 @@ package path_mgmt

import (
"fmt"
"time"

//log "github.com/inconshreveable/log15"

"github.com/scionproto/scion/go/lib/addr"
"github.com/scionproto/scion/go/lib/assert"
"github.com/scionproto/scion/go/lib/common"
"github.com/scionproto/scion/go/lib/util"
"github.com/scionproto/scion/go/proto"
)

const MinRevTTL = 10 * time.Second // Revocation MinRevTTL

var _ proto.Cerealizable = (*RevInfo)(nil)
var _ proto.Cerealizable = (*SignedRevInfo)(nil)

type SignedRevInfo struct {
Blob common.RawBytes
Sign *proto.SignS
revInfo *RevInfo `capnp:"-"`
}

func NewSignedRevInfoFromRaw(b common.RawBytes) (*SignedRevInfo, error) {
sr := &SignedRevInfo{}
return sr, proto.ParseFromRaw(sr, sr.ProtoId(), b)
}

func (sr *SignedRevInfo) ProtoId() proto.ProtoIdType {
return proto.SignedBlob_TypeID
}

func (sr *SignedRevInfo) RevInfo() (*RevInfo, error) {
var err error
if sr.revInfo == nil {
sr.revInfo, err = NewRevInfoFromRaw(sr.Blob)
}
return sr.revInfo, err
}

func (sp *SignedRevInfo) String() string {
return fmt.Sprintf("SignedRevInfo: %s %s", sp.Blob, sp.Sign)
}

type RevInfo struct {
IfID uint64
Epoch uint64
Nonce common.RawBytes
Siblings []SiblingHash
PrevRoot common.RawBytes
NextRoot common.RawBytes
RawIsdas addr.IAInt `capnp:"isdas"`
HashType uint16
TreeTTL uint32
IfID uint64
RawIsdas addr.IAInt `capnp:"isdas"`
LinkType proto.LinkType // Link type of revocation
Timestamp uint32 // Time in seconds since unix epoch
RevTTL uint32 // Validity period of the revocation in seconds
}

func NewRevInfoFromRaw(b common.RawBytes) (*RevInfo, error) {
Expand All @@ -48,16 +77,22 @@ func NewRevInfoFromRaw(b common.RawBytes) (*RevInfo, error) {
func (r *RevInfo) IA() addr.IA {
return r.RawIsdas.IA()
}

func (r *RevInfo) Valid() bool {
assert.Must(r.RevTTL >= uint32(MinRevTTL.Seconds()), "RevTTL must not be smaller than MinRevTTL")
now := uint32(time.Now().Unix())
// Revocation is not valid if its timestamp is not within the MinRevTTL
if r.Timestamp > now || r.Timestamp < now-r.RevTTL {
return false
}
return true
}

func (r *RevInfo) ProtoId() proto.ProtoIdType {
return proto.RevInfo_TypeID
}

func (r *RevInfo) String() string {
return fmt.Sprintf("IA: %s IfID: %d Epoch: %d TreeTTL: %d",
r.IA(), r.IfID, r.Epoch, r.TreeTTL)
}

type SiblingHash struct {
IsLeft bool
Hash common.RawBytes
return fmt.Sprintf("IA: %s IfID: %d Link type: %s Timestamp: %s TTL: %d",
r.IA(), r.IfID, r.LinkType, util.USecsToTime(uint64(r.Timestamp)), r.RevTTL)
}
15 changes: 7 additions & 8 deletions go/lib/ctrl/seg/as.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,13 @@ import (
var _ proto.Cerealizable = (*ASEntry)(nil)

type ASEntry struct {
RawIA addr.IAInt `capnp:"isdas"`
TrcVer uint64
CertVer uint64
IfIDSize uint8
HopEntries []*HopEntry `capnp:"hops"`
HashTreeRoot common.RawBytes
MTU uint16 `capnp:"mtu"`
Exts struct {
RawIA addr.IAInt `capnp:"isdas"`
TrcVer uint64
CertVer uint64
IfIDSize uint8
HopEntries []*HopEntry `capnp:"hops"`
MTU uint16 `capnp:"mtu"`
Exts struct {
RoutingPolicy common.RawBytes `capnp:"-"` // Not supported yet
Sibra common.RawBytes `capnp:"-"` // Not supported yet
}
Expand Down
10 changes: 8 additions & 2 deletions go/lib/pathmgr/pathmgr.go
Original file line number Diff line number Diff line change
Expand Up @@ -237,7 +237,13 @@ func (r *PR) Revoke(revInfo common.RawBytes) {
}

func (r *PR) revoke(revInfo common.RawBytes) {
parsedRev, err := path_mgmt.NewRevInfoFromRaw(revInfo)
parsedSignedRev, err := path_mgmt.NewSignedRevInfoFromRaw(revInfo)
if err != nil {
log.Error("Revocation failed, unable to parse signed revocation info",
"revInfo", revInfo, "err", err)
return
}
parsedRev, err := parsedSignedRev.RevInfo()
if err != nil {
log.Error("Revocation failed, unable to parse revocation info",
"revInfo", revInfo, "err", err)
Expand All @@ -248,7 +254,7 @@ func (r *PR) revoke(revInfo common.RawBytes) {
log.Error("Revocation failed, unable to connect to SCIOND", "err", err)
return
}
reply, err := conn.RevNotification(parsedRev)
reply, err := conn.RevNotification(parsedSignedRev)
if err != nil {
log.Error("Revocation failed, unable to inform SCIOND about revocation", "err", err)
return
Expand Down
3 changes: 2 additions & 1 deletion go/lib/sciond/mock.go
Original file line number Diff line number Diff line change
Expand Up @@ -137,10 +137,11 @@ func (m *MockConn) RevNotificationFromRaw(revInfo []byte) (*RevReply, error) {

// RevNotification deletes the edge containing revInfo.IfID from the
// multigraph. RevNotification does not perform any validation of revInfo.
func (m *MockConn) RevNotification(revInfo *path_mgmt.RevInfo) (*RevReply, error) {
func (m *MockConn) RevNotification(signedRevInfo *path_mgmt.SignedRevInfo) (*RevReply, error) {
m.lock.Lock()
defer m.lock.Unlock()

revInfo, _ := signedRevInfo.RevInfo()
m.g.RemoveLink(common.IFIDType(revInfo.IfID))
return &RevReply{
Result: RevValid,
Expand Down
8 changes: 4 additions & 4 deletions go/lib/sciond/sciond.go
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ type Connector interface {
// SCMP message.
RevNotificationFromRaw(revInfo []byte) (*RevReply, error)
// RevNotification sends a RevocationInfo message to SCIOND.
RevNotification(revInfo *path_mgmt.RevInfo) (*RevReply, error)
RevNotification(signedRevInfo *path_mgmt.SignedRevInfo) (*RevReply, error)
// Close shuts down the connection to a SCIOND server.
Close() error
}
Expand Down Expand Up @@ -306,14 +306,14 @@ func (c *connector) SVCInfo(svcTypes []ServiceType) (*ServiceInfoReply, error) {

func (c *connector) RevNotificationFromRaw(revInfo []byte) (*RevReply, error) {
// Extract information from notification
ri, err := path_mgmt.NewRevInfoFromRaw(revInfo)
ri, err := path_mgmt.NewSignedRevInfoFromRaw(revInfo)
if err != nil {
return nil, err
}
return c.RevNotification(ri)
}

func (c *connector) RevNotification(revInfo *path_mgmt.RevInfo) (*RevReply, error) {
func (c *connector) RevNotification(signedRevInfo *path_mgmt.SignedRevInfo) (*RevReply, error) {
c.Lock()
defer c.Unlock()

Expand All @@ -324,7 +324,7 @@ func (c *connector) RevNotification(revInfo *path_mgmt.RevInfo) (*RevReply, erro
Id: c.nextID(),
Which: proto.SCIONDMsg_Which_revNotification,
RevNotification: RevNotification{
RevInfo: revInfo,
RevInfo: signedRevInfo,
},
},
reliable.NilAppAddr,
Expand Down
2 changes: 1 addition & 1 deletion go/lib/sciond/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,7 @@ func (entry ASInfoReplyEntry) String() string {
}

type RevNotification struct {
RevInfo *path_mgmt.RevInfo
RevInfo *path_mgmt.SignedRevInfo
}

type RevReply struct {
Expand Down
1 change: 0 additions & 1 deletion go/proto/gen.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ var RootTypes = []string{
"CtrlPld",
"PathSegment",
"PathSegmentSignedData",
"RevInfo",
"SCIONDMsg",
"SignedBlob",
"SignedCtrlPld",
Expand Down
4 changes: 2 additions & 2 deletions proto/if_state.capnp
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@ using Go = import "go.capnp";
$Go.package("proto");
$Go.import("github.com/scionproto/scion/go/proto");

using RevInfo = import "rev_info.capnp";
using Sign = import "sign.capnp";

struct IFStateInfo {
ifID @0 :UInt64;
active @1 :Bool;
revInfo @2 :RevInfo.RevInfo;
revInfo @2 :Sign.SignedBlob;
}

struct IFStateInfos {
Expand Down
Loading

0 comments on commit e99d720

Please sign in to comment.