author | Alberto Bertogli
<albertito@blitiri.com.ar> 2017-02-23 20:27:24 UTC |
committer | Alberto Bertogli
<albertito@blitiri.com.ar> 2017-02-23 21:33:20 UTC |
parent | c4a5ad3db2556ecd921e3bc4967a1bc5d189f9e1 |
internal/client/config.go | +14 | -3 |
internal/client/grpc.go | +17 | -38 |
internal/proto/remoteu2f.pb.go | +4 | -0 |
internal/proto/remoteu2f.proto | +4 | -0 |
remoteu2f-cli/main.go | +1 | -1 |
remoteu2f-proxy/embedded_data.go | +6 | -2 |
remoteu2f-proxy/to_embed/authenticate.html | +3 | -1 |
remoteu2f-proxy/to_embed/register.html | +3 | -1 |
diff --git a/internal/client/config.go b/internal/client/config.go index 372b763..51832a0 100644 --- a/internal/client/config.go +++ b/internal/client/config.go @@ -8,6 +8,8 @@ import ( "io/ioutil" "math/big" "os" + + "github.com/tstranex/u2f" ) // Default configuration directory, relative to the user's home directory. @@ -109,9 +111,18 @@ func (c *Config) NewBackupCodes() error { return nil } -func (c *Config) RegistrationValues() [][]byte { - var rs [][]byte - for _, r := range c.Registrations { +// RegistrationValues returns the registrations in the configuration file, as +// a slice of u2f.Registration structures (which is a friendly form for the +// client functions). +func (c *Config) RegistrationValues() []u2f.Registration { + var rs []u2f.Registration + for _, binr := range c.Registrations { + r := u2f.Registration{} + if err := r.UnmarshalBinary(binr); err != nil { + // TODO - Should we account for this? + // Backwards-incompatible changes could cause this. + panic(err) + } rs = append(rs, r) } return rs diff --git a/internal/client/grpc.go b/internal/client/grpc.go index e89b1cb..ea0ad90 100644 --- a/internal/client/grpc.go +++ b/internal/client/grpc.go @@ -66,15 +66,16 @@ type PendingRegister struct { challenge *u2f.Challenge } -func (c *RemoteU2FClient) PrepareRegister(msg, appID string) (*PendingRegister, error) { - var trustedFacets = []string{appID} +func (c *RemoteU2FClient) PrepareRegister( + msg, appID string, regs []u2f.Registration) (*PendingRegister, error) { - challenge, err := u2f.NewChallenge(appID, trustedFacets) + challenge, err := u2f.NewChallenge(appID, []string{appID}) if err != nil { return nil, fmt.Errorf("u2f.NewChallenge error: %v", err) } - j, err := json.Marshal(challenge.RegisterRequest()) + req := u2f.NewWebRegisterRequest(challenge, regs) + j, err := json.Marshal(req) if err != nil { return nil, fmt.Errorf("json marshalling error: %v", err) } @@ -124,41 +125,21 @@ type PendingAuth struct { Key *pb.Url // Registrations we sent auth requests for. - regs []*u2f.Registration + regs []u2f.Registration - // Challenges matching each registration. - challenges []*u2f.Challenge + // Challenge. + challenge *u2f.Challenge } -func (c *RemoteU2FClient) PrepareAuthentication(msg, appID string, marshalledRegs [][]byte) ( - *PendingAuth, error) { - - var trustedFacets = []string{appID} +func (c *RemoteU2FClient) PrepareAuthentication( + msg, appID string, regs []u2f.Registration) (*PendingAuth, error) { - pa := &PendingAuth{} - signReqs := []*u2f.SignRequest{} - - // Generate one signature request for each registration. - for _, mreg := range marshalledRegs { - reg := &u2f.Registration{} - err := reg.UnmarshalBinary(mreg) - if err != nil { - return nil, fmt.Errorf("u2f.ParseRegistration: %v\n", err) - } - - // Can/should we reuse the challenge for all the registrations? - challenge, err := u2f.NewChallenge(appID, trustedFacets) - if err != nil { - return nil, fmt.Errorf("u2f.NewChallenge error: %v", err) - } - - sr := challenge.SignRequest(*reg) - signReqs = append(signReqs, sr) - - pa.challenges = append(pa.challenges, challenge) - pa.regs = append(pa.regs, reg) + challenge, err := u2f.NewChallenge(appID, []string{appID}) + if err != nil { + return nil, fmt.Errorf("u2f.NewChallenge error: %v", err) } + signReqs := challenge.SignRequest(regs) j, err := json.Marshal(signReqs) if err != nil { return nil, fmt.Errorf("json marshalling error: %v", err) @@ -173,9 +154,7 @@ func (c *RemoteU2FClient) PrepareAuthentication(msg, appID string, marshalledReg return nil, fmt.Errorf("error preparing: %v", err) } - pa.Key = key - - return pa, nil + return &PendingAuth{key, regs, challenge}, nil } func (c *RemoteU2FClient) CompleteAuthentication(pa *PendingAuth) error { @@ -192,9 +171,9 @@ func (c *RemoteU2FClient) CompleteAuthentication(pa *PendingAuth) error { return fmt.Errorf("invalid response: %s", err) } - for i, reg := range pa.regs { + for _, reg := range pa.regs { // TODO: support counters. - _, err = reg.Authenticate(signResp, *pa.challenges[i], 0) + _, err = reg.Authenticate(signResp, *pa.challenge, 0) if err == nil { return nil } diff --git a/internal/proto/remoteu2f.pb.go b/internal/proto/remoteu2f.pb.go index eca3b5a..e34fd6d 100644 --- a/internal/proto/remoteu2f.pb.go +++ b/internal/proto/remoteu2f.pb.go @@ -85,6 +85,10 @@ func (*Url) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{1} } // Prepare an operation. type Prepare struct { // Generic json content to return. + // This is a marshalled version of u2f.WebRegisterRequest or + // u2f.WebSignRequest, depending on the operation. + // We don't need to access this directly in the proxy, so we keep this + // opaque and decode it again at javascript. Json []byte `protobuf:"bytes,1,opt,name=json,proto3" json:"json,omitempty"` // User-readable message to show on the web page. Msg string `protobuf:"bytes,2,opt,name=msg" json:"msg,omitempty"` diff --git a/internal/proto/remoteu2f.proto b/internal/proto/remoteu2f.proto index 16be073..3519803 100644 --- a/internal/proto/remoteu2f.proto +++ b/internal/proto/remoteu2f.proto @@ -16,6 +16,10 @@ message Url { // Prepare an operation. message Prepare { // Generic json content to return. + // This is a marshalled version of u2f.WebRegisterRequest or + // u2f.WebSignRequest, depending on the operation. + // We don't need to access this directly in the proxy, so we keep this + // opaque and decode it again at javascript. bytes json = 1; // User-readable message to show on the web page. diff --git a/remoteu2f-cli/main.go b/remoteu2f-cli/main.go index 3c4a156..0eefe56 100644 --- a/remoteu2f-cli/main.go +++ b/remoteu2f-cli/main.go @@ -244,7 +244,7 @@ func Register(ctx *cli.Context) { user, hostname := mustUserInfo() msg := fmt.Sprintf("%s@%s", user, hostname) - pr, err := c.PrepareRegister(msg, conf.AppID) + pr, err := c.PrepareRegister(msg, conf.AppID, conf.RegistrationValues()) if err != nil { fatalf("Error preparing registration: %v\n", err) } diff --git a/remoteu2f-proxy/embedded_data.go b/remoteu2f-proxy/embedded_data.go index bb5bc73..4417fec 100644 --- a/remoteu2f-proxy/embedded_data.go +++ b/remoteu2f-proxy/embedded_data.go @@ -42,7 +42,9 @@ const authenticate_html = `<!DOCTYPE html> <script type="text/javascript" src="remoteu2f.js"></script> <script type="text/javascript" src="u2f_api.js"></script> <script> - u2f.sign({{.Request}}, handleKeyResponse, 2*60); + req = {{.Request}}; + u2f.sign(req.appId, req.challenge, req.registeredKeys, + handleKeyResponse, 2*60); </script> </body> @@ -86,7 +88,9 @@ const register_html = `<!DOCTYPE html> <script type="text/javascript" src="remoteu2f.js"></script> <script type="text/javascript" src="u2f_api.js"></script> <script> - u2f.register([{{.Request}}], [], handleKeyResponse, 2*60) + req = {{.Request}}; + u2f.register(req.appId, req.registerRequests, req.registeredKeys, + handleKeyResponse, 2*60) </script> </body> diff --git a/remoteu2f-proxy/to_embed/authenticate.html b/remoteu2f-proxy/to_embed/authenticate.html index e462795..385bf59 100644 --- a/remoteu2f-proxy/to_embed/authenticate.html +++ b/remoteu2f-proxy/to_embed/authenticate.html @@ -33,7 +33,9 @@ <script type="text/javascript" src="remoteu2f.js"></script> <script type="text/javascript" src="u2f_api.js"></script> <script> - u2f.sign({{.Request}}, handleKeyResponse, 2*60); + req = {{.Request}}; + u2f.sign(req.appId, req.challenge, req.registeredKeys, + handleKeyResponse, 2*60); </script> </body> diff --git a/remoteu2f-proxy/to_embed/register.html b/remoteu2f-proxy/to_embed/register.html index 9b70789..8f5f968 100644 --- a/remoteu2f-proxy/to_embed/register.html +++ b/remoteu2f-proxy/to_embed/register.html @@ -31,7 +31,9 @@ <script type="text/javascript" src="remoteu2f.js"></script> <script type="text/javascript" src="u2f_api.js"></script> <script> - u2f.register([{{.Request}}], [], handleKeyResponse, 2*60) + req = {{.Request}}; + u2f.register(req.appId, req.registerRequests, req.registeredKeys, + handleKeyResponse, 2*60) </script> </body>