@@ -18,14 +18,18 @@ import (
18
18
"context"
19
19
"encoding/hex"
20
20
"fmt"
21
+ "net"
21
22
"time"
22
23
23
24
"github.com/scionproto/scion/go/lib/addr"
24
- drkeyctrl "github.com/scionproto/scion/go/lib/ctrl/drkey"
25
25
"github.com/scionproto/scion/go/lib/daemon"
26
26
"github.com/scionproto/scion/go/lib/drkey"
27
+ "github.com/scionproto/scion/go/lib/drkey/fetcher"
28
+ "github.com/scionproto/scion/go/lib/scrypto/cppki"
27
29
cppb "github.com/scionproto/scion/go/pkg/proto/control_plane"
30
+ dkpb "github.com/scionproto/scion/go/pkg/proto/drkey"
28
31
"google.golang.org/grpc"
32
+ "google.golang.org/protobuf/types/known/timestamppb"
29
33
)
30
34
31
35
// check just ensures the error is nil, or complains and quits
@@ -35,21 +39,42 @@ func check(e error) {
35
39
}
36
40
}
37
41
38
- type Client struct {
42
+ type dialer struct {
39
43
daemon daemon.Connector
40
44
}
41
45
46
+ func (d * dialer ) Dial (ctx context.Context , _ net.Addr ) (* grpc.ClientConn , error ) {
47
+ // Obtain CS address from scion daemon
48
+ svcs , err := d .daemon .SVCInfo (ctx , nil )
49
+ check (err )
50
+ cs := svcs [addr .SvcCS ]
51
+ if len (cs ) == 0 {
52
+ panic ("no CS svc address" )
53
+ }
54
+
55
+ // Contact CS directly for SV
56
+ return grpc .DialContext (ctx , cs , grpc .WithInsecure ())
57
+ }
58
+
59
+ type Client struct {
60
+ fetcher * fetcher.FromCS
61
+ }
62
+
42
63
func NewClient (ctx context.Context , sciondPath string ) Client {
43
64
daemon , err := daemon .NewService (sciondPath ).Connect (ctx )
44
65
check (err )
45
66
return Client {
46
- daemon : daemon ,
67
+ fetcher : & fetcher.FromCS {
68
+ Dialer : & dialer {
69
+ daemon : daemon ,
70
+ },
71
+ },
47
72
}
48
73
}
49
74
50
75
func (c Client ) HostHostKey (ctx context.Context , meta drkey.HostHostMeta ) drkey.HostHostKey {
51
76
// get L2 key: (slow path)
52
- key , err := c .daemon .DRKeyGetHostHostKey (ctx , meta )
77
+ key , err := c .fetcher .DRKeyGetHostHostKey (ctx , meta )
53
78
check (err )
54
79
return key
55
80
}
@@ -68,36 +93,47 @@ func NewServer(ctx context.Context, sciondPath string) Server {
68
93
69
94
// fetchSV obtains the Secret Value (SV) for the selected protocol/epoch.
70
95
// From this SV, all keys for this protocol/epoch can be derived locally.
71
- // The IP address of the server must be explicitly allowed to abtain this SV
96
+ // The IP address of the server must be explicitly allowed to obtain this SV
72
97
// from the the control server.
73
98
func (s Server ) fetchSV (ctx context.Context , meta drkey.SVMeta ) drkey.SV {
74
- // Obtain CS address from scion daemon
99
+ // Obtain CS address from scion daemon. Note there's no need to use
100
+ // the daemon as long as a valid address could be passed to the dialing
101
+ // function.
75
102
svcs , err := s .daemon .SVCInfo (ctx , nil )
76
103
check (err )
77
104
cs := svcs [addr .SvcCS ]
105
+ if len (cs ) == 0 {
106
+ panic ("no CS svc address" )
107
+ }
78
108
79
109
// Contact CS directly for SV
80
110
conn , err := grpc .DialContext (ctx , cs , grpc .WithInsecure ())
81
111
check (err )
82
112
defer conn .Close ()
83
113
client := cppb .NewDRKeyIntraServiceClient (conn )
84
- protoReq , err := drkeyctrl .SVMetaToProtoRequest (meta )
85
- check (err )
86
- rep , err := client .SV (ctx , protoReq )
114
+
115
+ rep , err := client .SV (ctx , & dkpb.SVRequest {
116
+ ValTime : timestamppb .New (meta .Validity ),
117
+ ProtocolId : dkpb .Protocol (meta .ProtoId ),
118
+ })
87
119
check (err )
88
- key , err := drkeyctrl . GetSVFromReply (meta .ProtoId , rep )
120
+ key , err := getSecretFromReply (meta .ProtoId , rep )
89
121
check (err )
90
122
return key
91
123
}
92
124
93
125
func (s Server ) HostHostKey (sv drkey.SV , meta drkey.HostHostMeta ) drkey.HostHostKey {
94
- var deriver drkey.SpecificDeriver
126
+ deriver := ( & drkey.SpecificDeriver {})
95
127
lvl1 , err := deriver .DeriveLvl1 (drkey.Lvl1Meta {
96
- DstIA : meta .DstIA ,
128
+ Validity : meta .Validity ,
129
+ ProtoId : meta .ProtoId ,
130
+ SrcIA : meta .SrcIA ,
131
+ DstIA : meta .DstIA ,
97
132
}, sv .Key )
98
133
check (err )
99
134
asHost , err := deriver .DeriveHostAS (drkey.HostASMeta {
100
- SrcHost : meta .SrcHost ,
135
+ Lvl2Meta : meta .Lvl2Meta ,
136
+ SrcHost : meta .SrcHost ,
101
137
}, lvl1 )
102
138
check (err )
103
139
hosthost , err := deriver .DeriveHostToHost (meta .DstHost , asHost )
@@ -122,15 +158,15 @@ func main() {
122
158
const sciondForClient = "[fd00:f00d:cafe::7f00:c]:30255"
123
159
clientIA , err := addr .ParseIA ("1-ff00:0:112" )
124
160
check (err )
125
- const clientIP = "fd00:f00d:cafe::7f00:c "
161
+ const clientIP = "fd00:f00d:cafe::7f00:b "
126
162
127
163
ctx , cancelF := context .WithTimeout (context .Background (), 4 * time .Second )
128
164
defer cancelF ()
129
165
130
166
// meta describes the key that both client and server derive
131
167
meta := drkey.HostHostMeta {
132
168
Lvl2Meta : drkey.Lvl2Meta {
133
- ProtoId : drkey .DNS ,
169
+ ProtoId : drkey .SCMP ,
134
170
// Validity timestamp; both sides need to use the same time stamp when deriving the key
135
171
// to ensure they derive keys for the same epoch.
136
172
// Usually this is coordinated by means of a timestamp in the message.
@@ -168,3 +204,30 @@ func main() {
168
204
169
205
fmt .Printf ("Server,\t host key = %s\t duration = %s\n " , hex .EncodeToString (serverKey .Key [:]), durationServer )
170
206
}
207
+
208
+ func getSecretFromReply (
209
+ proto drkey.Protocol ,
210
+ rep * dkpb.SVResponse ,
211
+ ) (drkey.SV , error ) {
212
+
213
+ err := rep .EpochBegin .CheckValid ()
214
+ if err != nil {
215
+ return drkey.SV {}, err
216
+ }
217
+ err = rep .EpochEnd .CheckValid ()
218
+ if err != nil {
219
+ return drkey.SV {}, err
220
+ }
221
+ epoch := drkey.Epoch {
222
+ Validity : cppki.Validity {
223
+ NotBefore : rep .EpochBegin .AsTime (),
224
+ NotAfter : rep .EpochEnd .AsTime (),
225
+ },
226
+ }
227
+ returningKey := drkey.SV {
228
+ ProtoId : proto ,
229
+ Epoch : epoch ,
230
+ }
231
+ copy (returningKey .Key [:], rep .Key )
232
+ return returningKey , nil
233
+ }
0 commit comments