Skip to content

Commit

Permalink
PS: Push cert chain to local CS
Browse files Browse the repository at this point in the history
Fixes #2056
  • Loading branch information
lukedirtwalker committed Nov 1, 2018
1 parent b8362fd commit a594eec
Show file tree
Hide file tree
Showing 5 changed files with 79 additions and 27 deletions.
3 changes: 2 additions & 1 deletion go/cert_srv/setup.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ import (
"github.com/scionproto/scion/go/lib/infra/modules/trust/trustdb"
"github.com/scionproto/scion/go/lib/log"
"github.com/scionproto/scion/go/lib/snet"
"github.com/scionproto/scion/go/proto"
)

const (
Expand Down Expand Up @@ -89,7 +90,7 @@ func initState(config *Config) error {
}
trustConf := &trust.Config{
MustHaveLocalChain: true,
IsCS: true,
ServiceType: proto.ServiceType_cs,
}
config.state.Store, err = trust.NewStore(config.state.TrustDB, config.General.Topology.ISD_AS,
rand.Uint64(), trustConf, log.Root())
Expand Down
10 changes: 7 additions & 3 deletions go/lib/infra/modules/trust/config.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright 2018 ETH Zurich
// Copyright 2018 ETH Zurich, Anapaya Systems
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
Expand All @@ -14,6 +14,10 @@

package trust

import (
"github.com/scionproto/scion/go/proto"
)

// FIXME(scrye): When reloading support gets added again, Options should include
// all the reloadable aspects of the trust store. Instead of direct access,
// accessors should be preferred to ensure concurrency-safe reads.
Expand All @@ -23,6 +27,6 @@ type Config struct {
// IA must always return a valid chain. This is set to true on CSes and to
// false on others.
MustHaveLocalChain bool
// IsCS is set to true on CSes and false on others.
IsCS bool
// ServiceType is the type of the service that uses the store.
ServiceType proto.ServiceType
}
10 changes: 5 additions & 5 deletions go/lib/infra/modules/trust/resolvers.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright 2018 ETH Zurich
// Copyright 2018 ETH Zurich, Anapaya Systems
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -38,7 +38,7 @@ type trcRequest struct {
// If postHook is set, run the callback to verify the downloaded object and insert into
// the database. Also, used to generate different DedupeKeys for requests
// for valid vs invalid crypto.
postHook ValidateTRCF
postHook ValidateTRCFunc
}

func (req *trcRequest) DedupeKey() string {
Expand Down Expand Up @@ -66,7 +66,7 @@ type chainRequest struct {
// If postHook is set, run the callback to verify the downloaded object and insert into
// the database. Also, used to generate different DedupeKeys for requests
// for valid vs invalid crypto.
postHook ValidateChainF
postHook ValidateChainFunc
}

func (req *chainRequest) DedupeKey() string {
Expand All @@ -81,6 +81,6 @@ func (req *chainRequest) BroadcastKey() string {
return fmt.Sprintf("%sv%d", req.ia, req.version)
}

type ValidateTRCF func(ctx context.Context, trcObj *trc.TRC) error
type ValidateTRCFunc func(ctx context.Context, trcObj *trc.TRC) error

type ValidateChainF func(ctx context.Context, chain *cert.Chain) error
type ValidateChainFunc func(ctx context.Context, chain *cert.Chain) error
78 changes: 61 additions & 17 deletions go/lib/infra/modules/trust/trust.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import (
"github.com/scionproto/scion/go/lib/ctrl/cert_mgmt"
"github.com/scionproto/scion/go/lib/infra"
"github.com/scionproto/scion/go/lib/infra/dedupe"
"github.com/scionproto/scion/go/lib/infra/messenger"
"github.com/scionproto/scion/go/lib/infra/modules/itopo"
"github.com/scionproto/scion/go/lib/infra/modules/trust/trustdb"
"github.com/scionproto/scion/go/lib/log"
Expand Down Expand Up @@ -229,7 +230,7 @@ func (store *Store) getTRC(ctx context.Context, isd addr.ISD, version uint64,
version: version,
id: store.nextID(),
server: server,
postHook: store.newInsertTRCHook(),
postHook: store.InsertTRCHook,
})
}

Expand All @@ -248,15 +249,12 @@ func (store *Store) getTRCFromNetwork(ctx context.Context, req *trcRequest) (*tr
}
}

// newInsertTRCHook returns a TRC validation callback which always inserts the
// TRC into the database.
func (store *Store) newInsertTRCHook() ValidateTRCF {
return func(ctx context.Context, trcObj *trc.TRC) error {
if _, err := store.trustdb.InsertTRCCtx(ctx, trcObj); err != nil {
return common.NewBasicError("Unable to store TRC in database", err)
}
return nil
// InsertTRCHook always inserts the TRC into the database.
func (store *Store) InsertTRCHook(ctx context.Context, trcObj *trc.TRC) error {
if _, err := store.trustdb.InsertTRCCtx(ctx, trcObj); err != nil {
return common.NewBasicError("Unable to store TRC in database", err)
}
return nil
}

// GetValidChain asks the trust store to return a valid certificate chain for ia.
Expand Down Expand Up @@ -348,17 +346,52 @@ func (store *Store) getChain(ctx context.Context, ia addr.IA, version uint64,
})
}

func (store *Store) newChainValidator(validator *trc.TRC) ValidateChainFunc {
if store.config.ServiceType == proto.ServiceType_ps {
return store.newChainValidatorForwarding(validator)
}
return store.newChainValidatorLocal(validator)
}

func (store *Store) newChainValidatorForwarding(validator *trc.TRC) ValidateChainFunc {
return func(ctx context.Context, chain *cert.Chain) error {
if err := verifyChain(validator, chain); err != nil {
return err
}
_, err := store.trustdb.InsertChainCtx(ctx, chain)
if err != nil {
return common.NewBasicError("Unable to store CertChain in database", err)
}
// forward to local CS, async
go func() {
defer log.LogPanicAndExit()
addr, err := store.ChooseServer(store.ia)
if err != nil {
log.Error("Failed to select server to forward cert cahin", "err", err)
}
rawChain, err := chain.Compress()
if err != nil {
log.Error("Failed to compress chain for forwarding", "err", err)
}
// TODO(lukedirtwalker): use extended context?
err = store.msger.SendCertChain(ctx, &cert_mgmt.Chain{
RawChain: rawChain,
}, addr, messenger.NextId())
if err != nil {
log.Error("Failed to forward cert chain", "err", err)
}
}()
return nil
}
}

// newChainValidator returns a Chain validation callback with verifier as trust
// anchor. If validation succeeds, the certificate chain is also inserted in
// the trust database.
func (store *Store) newChainValidator(validator *trc.TRC) ValidateChainF {
func (store *Store) newChainValidatorLocal(validator *trc.TRC) ValidateChainFunc {
return func(ctx context.Context, chain *cert.Chain) error {
if validator == nil {
return common.NewBasicError("Chain verification failed, nil verifier", nil,
"target", chain)
}
if err := chain.Verify(chain.Leaf.Subject, validator); err != nil {
return common.NewBasicError("Chain verification failed", err)
if err := verifyChain(validator, chain); err != nil {
return err
}
_, err := store.trustdb.InsertChainCtx(ctx, chain)
if err != nil {
Expand All @@ -368,6 +401,17 @@ func (store *Store) newChainValidator(validator *trc.TRC) ValidateChainF {
}
}

func verifyChain(validator *trc.TRC, chain *cert.Chain) error {
if validator == nil {
return common.NewBasicError("Chain verification failed, nil verifier", nil,
"target", chain)
}
if err := chain.Verify(chain.Leaf.Subject, validator); err != nil {
return common.NewBasicError("Chain verification failed", err)
}
return nil
}

// issueChainRequest requests a Chain from the trust store backend.
func (store *Store) getChainFromNetwork(ctx context.Context,
req *chainRequest) (*cert.Chain, error) {
Expand Down Expand Up @@ -570,7 +614,7 @@ func (store *Store) isLocal(address net.Addr) error {
// destination AS.
func (store *Store) ChooseServer(destination addr.IA) (net.Addr, error) {
topo := itopo.GetCurrentTopology()
if !store.config.IsCS {
if store.config.ServiceType != proto.ServiceType_cs {
svcInfo, err := topo.GetSvcInfo(proto.ServiceType_cs)
if err != nil {
return nil, err
Expand Down
5 changes: 4 additions & 1 deletion go/path_srv/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ import (
"github.com/scionproto/scion/go/path_srv/internal/handlers"
"github.com/scionproto/scion/go/path_srv/internal/psconfig"
"github.com/scionproto/scion/go/path_srv/internal/segsyncer"
"github.com/scionproto/scion/go/proto"
)

type Config struct {
Expand Down Expand Up @@ -90,7 +91,9 @@ func realMain() int {
return 1
}
topo := itopo.GetCurrentTopology()
trustConf := &trust.Config{}
trustConf := &trust.Config{
ServiceType: proto.ServiceType_ps,
}
trustStore, err := trust.NewStore(trustDB, topo.ISD_AS,
rand.Uint64(), trustConf, log.Root())
if err != nil {
Expand Down

0 comments on commit a594eec

Please sign in to comment.