Skip to content

DRKey ported from the old SCIONLab#77

Merged
juagargi merged 14 commits intonetsec-ethz:scionlabfrom
juagargi:scionlab_drkey_feature.rebased
Dec 17, 2020
Merged

DRKey ported from the old SCIONLab#77
juagargi merged 14 commits intonetsec-ethz:scionlabfrom
juagargi:scionlab_drkey_feature.rebased

Conversation

@juagargi
Copy link
Member

@juagargi juagargi commented Dec 10, 2020

This is a port for the new SCIONLab of the old DRKey implementation. This old implementation was working previously, but had to be adapted to the new gRPC, among other things.

Pending:


This change is Reviewable

* lib drkey files

* Epoch based on Validity period https://github.com/scionproto/scion/pull/2842/files

* added test for secret value derivation

* embed Validity in Epoch

* Replacing RawBytes by byte slice, using xtest to parse hex string

suite.go moved out to package exchange

Added Equal to DRkey

added dep in BUILD.bazel

* add bazel for exchange pkg
* lib drkey protocol files

* adding AS->Host, Host->Host to standard UI + minor changes

* Replacing RawBytes by byte slice

* Added suite.go UT

* mending protocol BUILD.bazel

* using testify in suite.go UT

* refactoring testify protocol_test.go
* Initial commit lib drkey drkeysqlite files

* refactor to Epoch based on Validity

* minor changes out of revision

* refactoring db_test with testify
* proto/sciond.capnp added drkey data + proto/drkey_mgmt.capnp + auto-generated files + inital go/lib/ctrl/drkey_mgmnt

* adapted lvl2_rep to Epoch based Validity

* replaced RawBytes by byte slice

replaced some missed RawBytes

* Use scrpyto.Version in Lvl1Rep.CrtVerDst

* added drkey in ctrl/union.go

* solving some golint warning in drkey_mgmt

* replacing RawBytes in Lvl2req
* inital commit drkeystorage pkg

* testify refactoring config_test.go
* cppki validity refactoring

* Drkey protobuf

* changes in drkeystorage:

- Modified ServiceStore interface
- Added mock

* added DRKey cp requests

* Added package go/pkg/cs/drkey:

- ServiceStore adapted to use new Fetcher
- Prefetcher and SecretValueStore

* Added ValitadePeerWithCert function:

- This function might help validating authentication information from peer in DRKey exchanges.

* added package go/pkg/cs/drkey/grpc:

- DRKeyService which handles both Lvl1 and Lvl2 request.
- DRKeyFetcher which fetches Lvl1 keys from some remote CS.

* added drkey CS config:
- added DRKey and DRKeyDB configuration files

* Refactoring drkey protobuf

* trust: added ClientTransportCredentials:

ClientTransportCredentials is used as a wrapper around TLS credentials so that the certificate and server name can be check within the grpc dialing.

- Lvl1KeyFetching test is adapted to use ClientTransportCredentials.

* mending test to pass

* small fixings and explicit implements

* refactoring pkg/cs UT

* protobuf: Refactoring protobuf Lvl1Response and added UTo

* added test inner function to prefectch keys + fixing error checking in drkey_service

* deleting unnecessary callOption in drkey_fetcher

* improving tests

* fixing lint errors
* move DRKey requests/responses to their own package

* add protobuf DRKey RPC in sciond

* added DRKey feature to go/pkg/sciond package:

- Implemented RPC interface to serve Lvl2Key request to scionD.
- Implemented Fetcher to fetch Lvl2Key from local CS.
- Added ClientStore which encompases the logic to handle DRKeyLvl2 feature.
- Added UTs.

* fixing lint errors

* fixing error with serverName in transport_credentials
* fix bug in Lvl2reqToProtoRequest

* add go/lib/sciond

* fixing serverName handling in verifyConnection

* fixing validateLvl2Req

* fixing concurrency in prefetcher

* fixing log messages and config in go/pkg/sciond

* added TLSQUIC stack in go/lib/infra/:

- QUICStack in infraenv.go is modified so that it also returns a separate QUIC stack.
- Added TLSQUICDialer which redirects requests to the TLSQUIC stack.
- Added new svc transport.

* plugging in DRKey in scionD and CS

* fixing lint and tests

* added sciond mock
Copy link
Member Author

@juagargi juagargi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For reference. DRKey has no effect if not configured.
In CS:
DRKey is disabled if not configured through the use of cfg.DRKey.Enabled() in cs.go.
There are two module init functions: in piskes.go and scmp.go.
Both init functions just create a protocol instance and add it to the KnownDerivations map. "Almost" no effect.

In sciond:
If the configuration does't include a cfg.DRKeyDB.Connection, it's completely disabled.

Reviewable status: 0 of 149 files reviewed, all discussions resolved

Copy link
Member Author

@juagargi juagargi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sample client and gen directory with DRKey on https://gist.github.com/juagargi/508edaa77358a25867f06c7f21530f19

Reviewable status: 0 of 139 files reviewed, all discussions resolved

@juagargi juagargi marked this pull request as ready for review December 15, 2020 14:06
Copy link

@matzf matzf left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed 67 of 139 files at r1.
Reviewable status: 67 of 139 files reviewed, 5 unresolved discussions (waiting on @juagargi)


go/cs/cs.go, line 378 at r1 (raw file):

	//DRKey feature
	var drkeyServStore drkeystorage.ServiceStore
	var svFactory drkeystorage.SecretValueFactory

Nit: move into block below.


go/cs/cs.go, line 427 at r1 (raw file):

				libgrpc.LogIDServerInterceptor(),
			),
		)

It's not clear to me why this quicTLSServer (and e.g. the key/cert pair configuration) is required at all. Why can this not use the other infrastructure? Why are the key/cert pairs specific to DRKey?
If it is necessary, I'd argue that this code should be moved to e.g. go/lib/infra/infraenv/infraenv.go where the rest of the quic infrastructure "lives".


go/cs/config/drkey.go, line 47 at r1 (raw file):

	EpochDuration util.DurWrap `toml:"epoch_duration,omitempty"`
	// MaxReplyAge is the age limit for a level 1 reply to be accepted. Older are rejected.
	MaxReplyAge util.DurWrap `toml:"max_reply_age,omitempty"`

This config value appears to be unused.


go/cs/config/drkey.go, line 83 at r1 (raw file):

func (cfg *DRKeyConfig) Enabled() bool {
	// TODO(juagargi): check that disabled CSs can receive DRKey queries from sciond (mine crashes)
	return cfg.enabled

Nit: the way this is handled looks correct, but it would be clearer without the intermediate enabled state. Just return cfg.DRKeyDB.Connection != "" would do.


go/cs/config/drkey.go, line 88 at r1 (raw file):

// Validate validates that all values are parsable.
func (cfg *DRKeyConfig) Validate() error {
	if !cfg.Enabled() {

Nit: I think it's preferable to validate all the provided values, even this is disabled.

Copy link

@matzf matzf left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewable status: 67 of 139 files reviewed, 5 unresolved discussions (waiting on @juagargi)


proto/drkey/mgmt/v1/mgmt.proto, line 83 at r1 (raw file):

    google.protobuf.Timestamp epoch_end = 4;
    // Additional information (optional)
    bytes misc = 5;

Drop this?

Copy link

@JordiSubira JordiSubira left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewable status: 67 of 139 files reviewed, 5 unresolved discussions (waiting on @juagargi and @matzf)


go/cs/cs.go, line 427 at r1 (raw file):

Previously, matzf (Matthias Frei) wrote…

It's not clear to me why this quicTLSServer (and e.g. the key/cert pair configuration) is required at all. Why can this not use the other infrastructure? Why are the key/cert pairs specific to DRKey?
If it is necessary, I'd argue that this code should be moved to e.g. go/lib/infra/infraenv/infraenv.go where the rest of the quic infrastructure "lives".

Currently the messaging stack used looks like gRPC/HTTP2/QUIC/UDP/SCION and the go library doesn't support http3, thus we cannot access the quic tls connection underneath. This quicTLSServer enables the access to the certificates which we want to check in both server and client sides. I agree this might look a little bit awkward but I already discuss this with Dominik from Anapaya and that's a solution we came up with.

Some changes have been introduced in infraenv.go to enable this new messaging stack, but if you think anything else can be moved there, we can discuss that, were you thinking sth in concrete?

Copy link

@JordiSubira JordiSubira left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewable status: 67 of 139 files reviewed, 5 unresolved discussions (waiting on @juagargi and @matzf)


go/cs/cs.go, line 427 at r1 (raw file):

Previously, JordiSubira wrote…

Currently the messaging stack used looks like gRPC/HTTP2/QUIC/UDP/SCION and the go library doesn't support http3, thus we cannot access the quic tls connection underneath. This quicTLSServer enables the access to the certificates which we want to check in both server and client sides. I agree this might look a little bit awkward but I already discuss this with Dominik from Anapaya and that's a solution we came up with.

Some changes have been introduced in infraenv.go to enable this new messaging stack, but if you think anything else can be moved there, we can discuss that, were you thinking sth in concrete?

Actually , taking a second look what makes sense to me is moving out the fileLoader struct at the bottom, do you have some suggestion?


proto/drkey/mgmt/v1/mgmt.proto, line 83 at r1 (raw file):

Previously, matzf (Matthias Frei) wrote…

Drop this?

This would differ from what's specified here https://scion.docs.anapaya.net/en/latest/cryptography/DRKeyInfra.html#second-level, eventhough, I don't think this is a major issue. @juagargi might want to have a word about that.

Copy link

@JordiSubira JordiSubira left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewable status: 63 of 139 files reviewed, 2 unresolved discussions (waiting on @matzf)


go/cs/cs.go, line 378 at r1 (raw file):

Previously, matzf (Matthias Frei) wrote…

Nit: move into block below.

Done


go/cs/config/drkey.go, line 47 at r1 (raw file):

Previously, matzf (Matthias Frei) wrote…

This config value appears to be unused.

Removed


go/cs/config/drkey.go, line 83 at r1 (raw file):

Previously, matzf (Matthias Frei) wrote…

Nit: the way this is handled looks correct, but it would be clearer without the intermediate enabled state. Just return cfg.DRKeyDB.Connection != "" would do.

Done


go/cs/config/drkey.go, line 88 at r1 (raw file):

Previously, matzf (Matthias Frei) wrote…

Nit: I think it's preferable to validate all the provided values, even this is disabled.

Done

Copy link

@matzf matzf left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed 2 of 139 files at r1, 4 of 4 files at r2.
Reviewable status: 69 of 139 files reviewed, 1 unresolved discussion (waiting on @juagargi)


go/cs/cs.go, line 427 at r1 (raw file):

Previously, JordiSubira wrote…

Actually , taking a second look what make sense to me is moving out the fileLoader struct at the bottom, do you have some suggestion?

Ok, I got the main point now: for DRKey, you want to check client and server TLS certificates against the TRC/control plane PKI. The naming with "TLS" does not make that at all clear to be honest -- quic always uses TLS so it just seems odd.

This infrastructure for a CPPKI-backed-TLS (if that's the right way to put it) appears to be more generic than its use here for DRKey. I think it would make sense to try to upstream this separately and immediately.
Looking at this again now, it's not quite as much code to be moved out as I thought there was. But it would seem to make sense would be to move the getCredentials and the srvConfig and the related logic to create a "TLSQUICDialer" / Service to libgrpc.

What is not quite clear to me yet is what key/cert pair is to be used for this. Looking e.g. through the verification code, I get the impression that this is the AS key/cert. But then, why the separate configuration entry?

Not blocking as you're trying to move forward quickly, but it would be nice if this could be improved in a follow up.


go/cs/config/drkey.go, line 83 at r1 (raw file):

Previously, JordiSubira wrote…

Done

Nit: just return cfg.DRKeyDB.Connection != ""?

Can you also remove the outdated TODO above it, please?


proto/daemon/v1/BUILD.bazel, line 12 at r2 (raw file):

        "@com_google_protobuf//:duration_proto",
        "@com_google_protobuf//:timestamp_proto",
        "//proto/drkey/mgmt/v1:drkey",

Must be first in list, buildifier complains "reformat listsort unsafesort".


proto/drkey/mgmt/v1/mgmt.proto, line 83 at r1 (raw file):

Previously, JordiSubira wrote…

This would differ from what's specified here https://scion.docs.anapaya.net/en/latest/cryptography/DRKeyInfra.html#second-level, eventhough, I don't think this is a major issue. @juagargi might want to have a word about that.

@juagargi? You said this was a left-over.
Again, not blocking -- if we accept breaking changes in the future, this can be removed in a follow up.

Copy link
Member Author

@juagargi juagargi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewable status: 69 of 139 files reviewed, 1 unresolved discussion (waiting on @juagargi)


proto/drkey/mgmt/v1/mgmt.proto, line 83 at r1 (raw file):

Previously, matzf (Matthias Frei) wrote…

@juagargi? You said this was a left-over.
Again, not blocking -- if we accept breaking changes in the future, this can be removed in a follow up.

It is part of a non implemented feature. It is part of the spec. though, but doable in a second / third iteration over DRKey.

Copy link

@matzf matzf left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewable status: 69 of 139 files reviewed, 3 unresolved discussions (waiting on @juagargi)


proto/drkey/mgmt/v1/mgmt.proto, line 54 at r2 (raw file):

        // Host address
        bytes host = 2;
    }

In other proto definitions, host addresses are simply defined as strings that are then parsed (no type field necessary). This doesn't seem obviously better, but consistency probably makes sense. Otherwise, type should be an enum.
Relatedly (but not very important perhaps), couldn't drkey handle the host addresses as opaque strings anyway? There does not seem to be a real reason to parse them (other than to validate the configuration etc.)?

(Not blocking, can be improved in a (protocol-breaking) follow up change.)


proto/drkey/mgmt/v1/mgmt.proto, line 58 at r2 (raw file):

    string protocol = 1;
    // Requested DRKeyProtoKeyType
    uint32 req_type = 2;

Both protocol and req_type should preferably be an enum in protobuf.

(Not blocking, can be improved in a (protocol-breaking) follow up change.)

Copy link

@JordiSubira JordiSubira left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewable status: 66 of 140 files reviewed, 3 unresolved discussions (waiting on @matzf)


go/cs/cs.go, line 427 at r1 (raw file):

Previously, matzf (Matthias Frei) wrote…

Ok, I got the main point now: for DRKey, you want to check client and server TLS certificates against the TRC/control plane PKI. The naming with "TLS" does not make that at all clear to be honest -- quic always uses TLS so it just seems odd.

This infrastructure for a CPPKI-backed-TLS (if that's the right way to put it) appears to be more generic than its use here for DRKey. I think it would make sense to try to upstream this separately and immediately.
Looking at this again now, it's not quite as much code to be moved out as I thought there was. But it would seem to make sense would be to move the getCredentials and the srvConfig and the related logic to create a "TLSQUICDialer" / Service to libgrpc.

What is not quite clear to me yet is what key/cert pair is to be used for this. Looking e.g. through the verification code, I get the impression that this is the AS key/cert. But then, why the separate configuration entry?

Not blocking as you're trying to move forward quickly, but it would be nice if this could be improved in a follow up.

Yes the idea of the name was stating that this stack was used in TLS/gRPC, we can choose some other name of course.

I discussed with Dominik having some things merge in a separate PR, but he suggested that we could try it out first and then merge.

I've moved out the getCredentials and the fileLoader to the trustlib, srvConfig looks quite straightforward to me, but if you think it is worth it to move it out, I can do it.

It wasn't clear for me either, at a high level I believe it could be any certificate valid according to the CPPKI for that AS with Client/ServerAuthenticate, that's why I put it separately. I guess we can take a further look if necessary.


go/cs/config/drkey.go, line 83 at r1 (raw file):

Previously, matzf (Matthias Frei) wrote…

Nit: just return cfg.DRKeyDB.Connection != ""?

Can you also remove the outdated TODO above it, please?

Done


proto/daemon/v1/BUILD.bazel, line 12 at r2 (raw file):

Previously, matzf (Matthias Frei) wrote…

Must be first in list, buildifier complains "reformat listsort unsafesort".

Done


proto/drkey/mgmt/v1/mgmt.proto, line 54 at r2 (raw file):

Previously, matzf (Matthias Frei) wrote…

In other proto definitions, host addresses are simply defined as strings that are then parsed (no type field necessary). This doesn't seem obviously better, but consistency probably makes sense. Otherwise, type should be an enum.
Relatedly (but not very important perhaps), couldn't drkey handle the host addresses as opaque strings anyway? There does not seem to be a real reason to parse them (other than to validate the configuration etc.)?

(Not blocking, can be improved in a (protocol-breaking) follow up change.)

I will write it down for the next iteration


proto/drkey/mgmt/v1/mgmt.proto, line 58 at r2 (raw file):

Previously, matzf (Matthias Frei) wrote…

Both protocol and req_type should preferably be an enum in protobuf.

(Not blocking, can be improved in a (protocol-breaking) follow up change.)

I will write it down for the next iteration

Copy link

@matzf matzf left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed 1 of 139 files at r1, 1 of 5 files at r3.
Reviewable status: 68 of 140 files reviewed, all discussions resolved (waiting on @matzf)

Copy link

@FR4NK-W FR4NK-W left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewable status: 68 of 140 files reviewed, 1 unresolved discussion (waiting on @juagargi and @matzf)


go/lib/drkey/protocol/protocol_test.go, line 188 at r3 (raw file):

four

Two? Three?
What are the other two for besides scmp and piskes?

Copy link
Member Author

@juagargi juagargi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

Reviewable status: 68 of 140 files reviewed, 1 unresolved discussion (waiting on @FR4NK-W and @matzf)


go/lib/drkey/protocol/protocol_test.go, line 188 at r3 (raw file):

Previously, FR4NK-W wrote…
four

Two? Three?
What are the other two for besides scmp and piskes?

We used to have four names in the past, being "standard" and "delegated" aliases for "scmp" and "piskes".
Fixed comment now.

Copy link
Member Author

@juagargi juagargi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:lgtm:

Reviewable status: 68 of 140 files reviewed, all discussions resolved (waiting on @matzf)

@FR4NK-W FR4NK-W dismissed their stale review December 17, 2020 16:26

Comment cleared

Copy link

@matzf matzf left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewable status: 68 of 140 files reviewed, all discussions resolved (waiting on @matzf)

Copy link
Member Author

@juagargi juagargi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed 133 of 139 files at r1, 2 of 4 files at r2, 5 of 5 files at r3.
Reviewable status: 139 of 140 files reviewed, all discussions resolved (waiting on @juagargi)

Copy link
Member Author

@juagargi juagargi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed 1 of 1 files at r4.
Reviewable status: :shipit: complete! all files reviewed, all discussions resolved (waiting on @juagargi)

Copy link

@matzf matzf left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed 67 of 139 files at r1, 4 of 5 files at r3, 1 of 1 files at r4.
Reviewable status: :shipit: complete! all files reviewed, all discussions resolved (waiting on @juagargi)

@juagargi juagargi merged commit 707a5e6 into netsec-ethz:scionlab Dec 17, 2020
@juagargi juagargi deleted the scionlab_drkey_feature.rebased branch December 17, 2020 16:29
matzf added a commit that referenced this pull request Oct 5, 2021
Squashed changes for DRKey, ported to latest upstream master branch.

This includes the following main commits:

* 707a5e6 DRKey ported from the old SCIONLab (#77)

  This is itself a squashed commit  containing the bulk of the newly
  added DRKey implementation.

* 5a623a2 Allow a second call to initQUICSockets. (#79)
* df3a258 unify personal annotations to JordiSubira (#80)
* 9380c76 fix Level 1 key Exchange (#81)

  Add sanity check in the drkey_fetcher which validates that the
  response srcIA matches the intended server IA.

* a90f354 Remove redundant fields from Lvl1Req/Resp (#83)
* 64f4c23 cs/drkey: handle situations where no path to a peer AS can be found (#90)

  This condition is now handled analog to a similar condition in
  github.com/scionproto/scion/go/pkg/trust.AuthRouter.ChooseServer

The main change applied to make this compatible with the master
branch was to resolve the renaming / moving of what was previously
pkg/sciond to now pkg/daemon.

Co-authored-by: JordiSubira <jordi.subira.nieto@gmail.com>
Co-authored-by: Juan A. Garcia Pardo <juagargi@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants