Skip to content

Commit

Permalink
Drkey (scionproto#63), rebased
Browse files Browse the repository at this point in the history
* DRKey implementation (scionproto#51)

* Mapping of FirstOrder Messages of Capnp to go/lib

* Second level drkey message representation

* InputType for PRF added

* Add DRKeyLvl2 representation

* Second order rep. and key derivation suite

* Add enc/dec of DRKeyLvl1

* add keystore

* remove AS2HostPair

* fix keystore tests

* update req & rep according to spec

* Finalize msg representation

* Extend infra module to handle DRKey requests and replies

* Moved keystore

* DRKey Handler skeleton for CSGO

* Finalized DRKey messaging in infra

* Introduce epoch type

* Add nonce for encryption as payload

* Change date for first level derivation to epoch number

* Implement DRKeyLvl1 Request & Reply Handler for cert_srv

* minor fixes

* Fixed after rebase

* Fix build.

Minimize changes to setup.
Fix configuration use on drkey handler.
Remove main package usage in drkey.tasks.

* Add UT covering level1 drkey exchange

* Return the reply object and UT it

* Refactor a bit the level 1 reply handler

* Reintroduce the drkey keystore

* Refactor the keystore

* Configuration refactor

* Rebased on master.

Coming from 2fed00a pre-scionlab to current master.
Many changes regarding Messenger and ResponseWriter. Pending code marked with TODO drkeytest .
Not passing yet UTs nor they build.

* Update the mocks

* sciond DRkey level 2 API function skeleton

* Continue with the sciond DRKey API.

Relay on the messenger methods to obtain the level 2 keys,
just synchronously wait for the reply and send it back.

* Fix some issues with sciond capnp structures, refactor

* Send something from the handler to test sciond.

Finish writing the reply back from the response writer to sciond.
Fix mapping name of field in lvl2 reply to capnp.

* Handle request for level 2.

Skeleton for srcAS being this AS.
UTs.

* WIP Level 2 exchange.

Added beginning of a UT covering the case of relaying the query to another CS.
WIP relay the query to another CS (level 2 only for now).

* WIP Level 2 exchange.

Some refactors. drkey.keystore now has an interface.

* Mock drkeystore in handler UT

* Storing level 2 key in DB.

Missing UT.

* Complete the data-flow sciond-CS

* Fix getting the cert. chain from remote AS.

The L2 request handler now derives the key from L1 from another CS, instead
of requesting the L2 key itself.
Changed signature of DRKeyStore.GetDRKeyLvl1.

* Cleanup handler UT

* Add a DRKey Store clean task

* Simplify DRKeyStore, start drkey.Requester

* Add new fcn to drkey store

* Add yet another fcn to keystore

* Update pending list in requester

* Requester setup & UT

* Requester processes pending L1 keys

* Requester UT

* SecretValue function added

* DRKey L1 pending never has itself

* Cleanup

* Obtain SV with the correct timestamp.

Also cache the SVs until expiration time.

* Refactoring, mainly naming

Symbols under go/lib/ctrl/drkey_mgmt .

* Refactor, rename.

Some symbols in go/lib/drkey .

* New drkey types

* Refactoring.

Creating packages like in the beacon service:
- "drkeystorage" with an interface of what a Store is .
- "drkey", with implementations of the SV, DRkey level 1 and 2, and also a concrete Store; it
also defines the interface for the DB.
- "drkeydbsqlite" implementing the DB defined in drkey.

Some UTs brought back to life.

Still pending the derivation interface, the protocol mapping and cleaning everywhere.

* Correct package name to drkeystorage

* Introduction of Protocol.

There is no configuration counterpart yet.

* Minor refactoring

* Rollback changes to python

* Use Lvl1, Lvl2 and not L1 or Level1

* replace TODO drkeytest w/ TODO(juagargi)

* DRKey own configuration.

Allow DRKey not to be configured, and run an empty DRKey store.
Rename Store methods.

* Fix drkeydbsqlite UT

* Reintroduce the drkey Store mock.

Also build UTs again; some of them fail now.
The level 2 handler does not read a level 2 key from the store, but always derives
it from the level 1 now.

* Simplified configuration.

Added config option to map protocols to drkey derivations.

* Fixes to the drkey configuration samples

* Update signer and verifier in the CS

* Split handler file

* Remove unused function

* Rename some methods from the handlers

* Refactor, better func names, added comments

* Better names in drkey_mgmt

* drkeystorage Store interface change

* The level 1 reply contains a timestamp.

Also use its CertVerDst field to retrieve the correct certificate when
decrypting the reply.
Add a config. value holding the age tolerance of the reply.

* rename handler files

* Also bazel build file, because renaming

* Comments and some refactoring

* make the set with the correct size already

* Display time values in drkey_ctrl with the compact format.

Also call util.SecsToTime instead of calling time.Unix with the value casted to int64.

* missing bazel build file

* Refactor. String methods for keys back.

The definition of DRKey is modified to just embed RawBytes.

* Remove GetMasterKey from Store

* Refactor the drkey types.

The secret value and keys are composed of the meta info and a DRKey.
A DRKey is just a RawBytes.
Leave DRKey.String but remove all other String methods.

* Refactor: rename

* Split the SV from the Store interface

* Rename import package

* SecretValueFactory: don't set duration or master key

* No default derivation.

Removed the default derivation. When a request with a protocol is not mapped to
a specific derivation, it fails.

* Refactor: split protocol into 2 files

* Move Store implementation to cert_srv

* New level 1 store

* Handlers in ServiceStore

* Modified protocol interfaces.

Added interface DelegationDerivation, with a method to derive from DS.
Modified the delegated implementation.
Added default implementations for scmp and piskes.
Added default initialization of the registry, with scmp and piskes in it.

* Move DeriveLvl1 to the protocol pkg

* Clean up store, Lvl1DB interface

* refactor: split DB in two structs

* Base Backend

* Changes in level 2 derivation.

Use mac.Sum(nil) to obtain the key value.
For level 2 standard derivation, write 1 byte with the length of protocol.
Don't write the length otherwise.

* Follow the docs deriving SV and lvl2 keys

* Fix delegated derivation to follow the docs

* Adapt cert drkey UTs

* further UT cleaning in cert_srv/internal/config

* comment out requester UT as requester is commented out

* EpochToSV to the drkey store prior to renaming

* rename EpochToSV to SecretValueStore

* Fix more go/lib/drkey UTs

* fix drkeydbsqlite/db_test UT

* removed convey

* simplify protocol registry

* Simplify registry again

* remove until properly defined

* Slightly modify DRKeyGetLvl2Key in sciond.

Also remove drkeystorage.Store as mock class.

* Check DRKey config values also in the CS config UT

* WIP: replace custom ia(string) function with xtest.MustParseIA

* Removed configuration for protocols.

Protocols are not configurable anymore.
There is a list of preconfigured protocols. For now it contains only
SCMP (direct standard level 2 derivation) and PISKES (delegated derivation through
delegation secret).
Refactor. Adapt UTs.

* WIP prepare for DRKey client store

* split implementation of store in several files

* WIP: client store

* WIP: DRKey store for sciond

* DRKey store for sciond

* Remove SetMessenger from the client store

* cleanup

* CS config sample in one file

* Add delegation configuration list

* Configure which end hosts get DSs

* Fix bug in delegated derivation.

And add UT.

* drkey store cleaner runs also in sciond

* Level 1 key prefetcher

* fix: quic message handler okay with not handled message types (scionproto#3236)

* Clearer messages

* Allow sciond to work without DRKey

* Fixes after rebasing DRKey
  • Loading branch information
juagargi authored and matzf committed Jan 8, 2020
1 parent b62e55e commit f84248d
Show file tree
Hide file tree
Showing 94 changed files with 5,880 additions and 367 deletions.
66 changes: 47 additions & 19 deletions docker/perapp/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -8,80 +8,108 @@ scion_app_images(
binary = "//go/border:border",
appdir = "/app",
workdir = "/share",
entrypoint = ["/app/border", "-config", "/share/conf/br.toml"],
entrypoint = [
"/app/border",
"-config",
"/share/conf/br.toml",
],
)

scion_app_images(
name = "beacon_srv",
binary = "//go/beacon_srv:beacon_srv",
appdir = "/app",
workdir = "/share",
entrypoint = ["/app/beacon_srv", "-config", "/share/conf/bs.toml"],
entrypoint = [
"/app/beacon_srv",
"-config",
"/share/conf/bs.toml",
],
)

scion_app_images(
name = "cert_srv",
binary = "//go/cert_srv:cert_srv",
appdir = "/app",
workdir = "/share",
entrypoint = ["/app/cert_srv", "-config", "/share/conf/cs.toml"],
entrypoint = [
"/app/cert_srv",
"-config",
"/share/conf/cs.toml",
],
)

scion_app_images(
name = "dispatcher_go",
binary = "//go/godispatcher:godispatcher",
appdir = "/app",
workdir = "/share",
entrypoint = ["/app/godispatcher", "-config", "/share/conf/disp.toml"],
entrypoint = [
"/app/godispatcher",
"-config",
"/share/conf/disp.toml",
],
)

scion_app_images(
name = "path_srv",
binary = "//go/path_srv:path_srv",
appdir = "/app",
workdir = "/share",
entrypoint = ["/app/path_srv", "-config", "/share/conf/ps.toml"],
entrypoint = [
"/app/path_srv",
"-config",
"/share/conf/ps.toml",
],
)

scion_app_images(
name = "sciond",
binary = "//go/sciond:sciond",
appdir = "/app",
workdir = "/share",
entrypoint = ["/app/sciond", "-config", "/share/conf/sd.toml"],
entrypoint = [
"/app/sciond",
"-config",
"/share/conf/sd.toml",
],
)

scion_app_images(
name = "sig",
binary = "//go/sig:sig",
appdir = "/app",
workdir = "/share",
entrypoint = ["/app/sig", "-config", "/share/conf/sig.toml"],
entrypoint = [
"/app/sig",
"-config",
"/share/conf/sig.toml",
],
)

# To generate the images: bazel run //docker/perapp:prod
container_bundle(
name = "prod",
images = {
"scion_border:latest": ":border_prod",
"scion_beacon:latest": ":beacon_srv_prod",
"scion_cert:latest": ":cert_srv_prod",
"scion_border:latest": ":border_prod",
"scion_beacon:latest": ":beacon_srv_prod",
"scion_cert:latest": ":cert_srv_prod",
"scion_dispatcher_go:latest": ":dispatcher_go_prod",
"scion_path:latest": ":path_srv_prod",
"scion_sciond:latest": ":sciond_prod",
"scion_sig_nocap:latest": ":sig_prod",
"scion_path:latest": ":path_srv_prod",
"scion_sciond:latest": ":sciond_prod",
"scion_sig_nocap:latest": ":sig_prod",
},
)

container_bundle(
name = "debug",
images = {
"scion_border_debug:latest": ":border_debug",
"scion_beacon_debug:latest": ":beacon_srv_debug",
"scion_cert_debug:latest": ":cert_srv_debug",
"scion_border_debug:latest": ":border_debug",
"scion_beacon_debug:latest": ":beacon_srv_debug",
"scion_cert_debug:latest": ":cert_srv_debug",
"scion_dispatcher_go_debug:latest": ":dispatcher_go_debug",
"scion_path_debug:latest": ":path_srv_debug",
"scion_sciond_debug:latest": ":sciond_debug",
"scion_sig_nocap_debug:latest": ":sig_debug",
"scion_path_debug:latest": ":path_srv_debug",
"scion_sciond_debug:latest": ":sciond_debug",
"scion_sig_nocap_debug:latest": ":sig_debug",
},
)
2 changes: 2 additions & 0 deletions go/cert_srv/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,11 @@ go_library(
visibility = ["//visibility:private"],
deps = [
"//go/cert_srv/internal/config:go_default_library",
"//go/cert_srv/internal/drkey:go_default_library",
"//go/lib/addr:go_default_library",
"//go/lib/common:go_default_library",
"//go/lib/discovery:go_default_library",
"//go/lib/drkeystorage:go_default_library",
"//go/lib/env:go_default_library",
"//go/lib/fatal:go_default_library",
"//go/lib/infra:go_default_library",
Expand Down
17 changes: 16 additions & 1 deletion go/cert_srv/internal/config/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,23 @@ go_library(
name = "go_default_library",
srcs = [
"config.go",
"drkey.go",
"sample.go",
"state.go",
],
importpath = "github.com/scionproto/scion/go/cert_srv/internal/config",
visibility = ["//go/cert_srv:__subpackages__"],
deps = [
"//go/lib/common:go_default_library",
"//go/lib/config:go_default_library",
"//go/lib/drkey:go_default_library",
"//go/lib/drkeystorage:go_default_library",
"//go/lib/env:go_default_library",
"//go/lib/infra:go_default_library",
"//go/lib/infra/modules/idiscovery:go_default_library",
"//go/lib/infra/modules/trust:go_default_library",
"//go/lib/infra/modules/trust/trustdb:go_default_library",
"//go/lib/keyconf:go_default_library",
"//go/lib/scrypto/cert:go_default_library",
"//go/lib/serrors:go_default_library",
"//go/lib/truststorage:go_default_library",
Expand All @@ -22,14 +30,21 @@ go_library(

go_test(
name = "go_default_test",
srcs = ["config_test.go"],
srcs = [
"config_test.go",
"drkey_test.go",
"state_test.go",
],
data = glob(["testdata/**"]),
embed = [":go_default_library"],
deps = [
"//go/lib/env/envtest:go_default_library",
"//go/lib/infra/modules/idiscovery/idiscoverytest:go_default_library",
"//go/lib/keyconf:go_default_library",
"//go/lib/scrypto:go_default_library",
"//go/lib/truststorage/truststoragetest:go_default_library",
"@com_github_burntsushi_toml//:go_default_library",
"@com_github_smartystreets_goconvey//convey:go_default_library",
"@com_github_stretchr_testify//assert:go_default_library",
],
)
10 changes: 10 additions & 0 deletions go/cert_srv/internal/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ const (

var _ config.Config = (*Config)(nil)

// Config that contains all necessary parameters to run a CS.
type Config struct {
General env.General
Features env.Features
Expand All @@ -59,9 +60,11 @@ type Config struct {
Sciond env.SciondClient `toml:"sd_client"`
TrustDB truststorage.TrustDBConf
Discovery idiscovery.Config
DRKey DRKeyConfig
CS CSConfig
}

// InitDefaults will initialize the configuration variables with their default values.
func (cfg *Config) InitDefaults() {
config.InitAll(
&cfg.General,
Expand All @@ -72,10 +75,12 @@ func (cfg *Config) InitDefaults() {
&cfg.Sciond,
&cfg.TrustDB,
&cfg.Discovery,
&cfg.DRKey,
&cfg.CS,
)
}

// Validate will validate all configuration variables.
func (cfg *Config) Validate() error {
return config.ValidateAll(
&cfg.General,
Expand All @@ -85,10 +90,12 @@ func (cfg *Config) Validate() error {
&cfg.Sciond,
&cfg.TrustDB,
&cfg.Discovery,
&cfg.DRKey,
&cfg.CS,
)
}

// Sample writes a sample of the configuration.
func (cfg *Config) Sample(dst io.Writer, path config.Path, _ config.CtxMap) {
config.WriteSample(dst, path, config.CtxMap{config.ID: idSample},
&cfg.General,
Expand All @@ -100,16 +107,19 @@ func (cfg *Config) Sample(dst io.Writer, path config.Path, _ config.CtxMap) {
&cfg.QUIC,
&cfg.TrustDB,
&cfg.Discovery,
&cfg.DRKey,
&cfg.CS,
)
}

// ConfigName returns the configuration name for this block.
func (cfg *Config) ConfigName() string {
return "cs_config"
}

var _ config.Config = (*CSConfig)(nil)

// CSConfig holds the configuration values for a CS that don't have their own block.
type CSConfig struct {
// LeafReissueLeadTime indicates how long in advance of leaf cert expiration
// the reissuance process starts.
Expand Down
11 changes: 11 additions & 0 deletions go/cert_srv/internal/config/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,18 +75,24 @@ func InitTestConfig(cfg *Config) {
truststoragetest.InitTestConfig(&cfg.TrustDB)
idiscoverytest.InitTestConfig(&cfg.Discovery)
InitTestCSConfig(&cfg.CS)
InitTestDRKeyConfig(&cfg.DRKey)
}

func InitTestCSConfig(cfg *CSConfig) {
cfg.AutomaticRenewal = true
cfg.DisableCorePush = true
}

func InitTestDRKeyConfig(cfg *DRKeyConfig) {
cfg.EpochDuration.Duration = 23 * time.Hour
}

func CheckTestConfig(t *testing.T, cfg *Config, id string) {
envtest.CheckTest(t, &cfg.General, &cfg.Logging, &cfg.Metrics, &cfg.Tracing, &cfg.Sciond, id)
truststoragetest.CheckTestConfig(t, &cfg.TrustDB, id)
idiscoverytest.CheckTestConfig(t, &cfg.Discovery)
CheckTestCSConfig(t, &cfg.CS)
CheckTestDRKeyConfig(t, &cfg.DRKey)
}

func CheckTestCSConfig(t *testing.T, cfg *CSConfig) {
Expand All @@ -97,3 +103,8 @@ func CheckTestCSConfig(t *testing.T, cfg *CSConfig) {
assert.Equal(t, IssuerReissTime, cfg.IssuerReissueLeadTime.Duration)
assert.False(t, cfg.DisableCorePush)
}

func CheckTestDRKeyConfig(t *testing.T, cfg *DRKeyConfig) {
assert.Equal(t, cfg.EpochDuration.Duration, DefaultEpochDuration)
assert.Equal(t, cfg.MaxReplyAge.Duration, DefaultMaxReplyAge)
}
104 changes: 104 additions & 0 deletions go/cert_srv/internal/config/drkey.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
// Copyright 2019 ETH Zurich
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package config

import (
"io"
"time"

"github.com/scionproto/scion/go/lib/config"
"github.com/scionproto/scion/go/lib/drkey"
"github.com/scionproto/scion/go/lib/drkeystorage"
"github.com/scionproto/scion/go/lib/util"
)

const (
// DefaultEpochDuration is the default duration for the drkey SV and derived keys
DefaultEpochDuration = 24 * time.Hour
// DefaultMaxReplyAge is the default allowed age for replies.
DefaultMaxReplyAge = 2 * time.Second
)

var _ (config.Config) = (*DRKeyConfig)(nil)

// DRKeyConfig is the configuration for the connection to the trust database.
type DRKeyConfig struct {
// enabled is set to true if we find all the required fields in the configuration.
enabled bool
// DRKeyDB contains the DRKey DB configuration.
DRKeyDB drkeystorage.DRKeyDBConf
// EpochDuration is the duration of the keys in this CS.
EpochDuration util.DurWrap
// MaxReplyAge is the age limit for a level 1 reply to be accepted. Older are rejected.
MaxReplyAge util.DurWrap
// AuthorizedDelegations is the DelegationList for this CS.
Delegation drkeystorage.DelegationList
}

// NewDRKeyConfig returns a pointer to a valid, empty configuration.
func NewDRKeyConfig() *DRKeyConfig {
c := DRKeyConfig{
DRKeyDB: drkeystorage.DRKeyDBConf{},
Delegation: drkeystorage.DelegationList{},
}
return &c
}

// InitDefaults initializes values of unset keys and determines if the configuration enables DRKey.
func (cfg *DRKeyConfig) InitDefaults() {
cfg.enabled = true
if cfg.EpochDuration.Duration == 0 {
cfg.enabled = false
cfg.EpochDuration.Duration = DefaultEpochDuration
}
if cfg.MaxReplyAge.Duration == 0 {
cfg.MaxReplyAge.Duration = DefaultMaxReplyAge
}
config.InitAll(&cfg.DRKeyDB, &cfg.Delegation)
if cfg.DRKeyDB.Connection() == "" {
cfg.enabled = false
}
}

// Enabled returns true if DRKey is configured. False otherwise.
func (cfg *DRKeyConfig) Enabled() bool {
// TODO(juagargi): check that disabled CSs can receive DRKey queries from sciond (mine crashes)
return cfg.enabled
}

// Validate validates that all values are parsable.
func (cfg *DRKeyConfig) Validate() error {
if !cfg.Enabled() {
return nil
}
return config.ValidateAll(&cfg.DRKeyDB, &cfg.Delegation)
}

// Sample writes a config sample to the writer.
func (cfg *DRKeyConfig) Sample(dst io.Writer, path config.Path, ctx config.CtxMap) {
config.WriteString(dst, drkeySample)
config.WriteSample(dst, path, config.CtxMap{config.ID: idSample},
&cfg.DRKeyDB, &cfg.Delegation)
}

// ConfigName is the key in the toml file.
func (cfg *DRKeyConfig) ConfigName() string {
return "drkey"
}

// NewDB creates a drkey.DB from the config.
func (cfg *DRKeyConfig) NewDB() (drkey.Lvl1DB, error) {
return cfg.DRKeyDB.NewLvl1DB()
}
Loading

0 comments on commit f84248d

Please sign in to comment.