Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PS: Push cert chain to local CS #2079

Merged
merged 2 commits into from
Nov 2, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
80 changes: 63 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,54 @@ 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)
}

// XXX(lukedirtwalker): This is not the final solution. It has many issues, see:
// https://github.com/scionproto/scion/issues/2083
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 +403,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 +616,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