@@ -35,6 +35,7 @@ func newErrResp(err error) *errResp {
35
35
36
36
type CreateTaskReq struct {
37
37
Nonce uint64 `json:"nonce" binding:"required"`
38
+ DeviceID string `json:"deviceID" binding:"required"`
38
39
ProjectID string `json:"projectID" binding:"required"`
39
40
ProjectVersion string `json:"projectVersion,omitempty"`
40
41
Payloads []string `json:"payloads" binding:"required"`
@@ -88,13 +89,13 @@ func (s *httpServer) createTask(c *gin.Context) {
88
89
c .JSON (http .StatusBadRequest , newErrResp (errors .Wrap (err , "failed to decode signature from hex format" )))
89
90
return
90
91
}
91
- pubkey , alg , err := recoverPubkey (* req , sig )
92
+ deviceAddr := common .HexToAddress (strings .TrimPrefix (req .DeviceID , "did:io:" ))
93
+ addr , sig , alg , err := recoverAddr (* req , sig , deviceAddr )
92
94
if err != nil {
93
95
slog .Error ("failed to recover public key" , "error" , err )
94
96
c .JSON (http .StatusBadRequest , newErrResp (errors .Wrap (err , "invalid signature; could not recover public key" )))
95
97
return
96
98
}
97
- addr := crypto .PubkeyToAddress (* pubkey )
98
99
99
100
ok , err := s .db .IsDeviceApproved (pid , addr )
100
101
if err != nil {
@@ -174,24 +175,40 @@ func (s *httpServer) createTask(c *gin.Context) {
174
175
})
175
176
}
176
177
177
- func recoverPubkey (req CreateTaskReq , sig []byte ) (* ecdsa. PublicKey , string , error ) {
178
+ func recoverAddr (req CreateTaskReq , sig []byte , deviceAddr common. Address ) (common. Address , [] byte , string , error ) {
178
179
req .Signature = ""
179
180
reqJson , err := json .Marshal (req )
180
181
if err != nil {
181
- return nil , "" , errors .Wrap (err , "failed to marshal request into json format" )
182
+ return common. Address {}, nil , "" , errors .Wrap (err , "failed to marshal request into json format" )
182
183
}
183
184
184
185
switch req .Algorithm {
185
186
default :
186
- hash := sha256 .New ()
187
- hash .Write (reqJson )
188
- h := hash .Sum (nil )
187
+ h := sha256 .Sum256 (reqJson )
188
+ res := []struct {
189
+ pk * ecdsa.PublicKey
190
+ sig []byte
191
+ }{}
192
+ rID := []uint8 {0 , 1 }
193
+ for _ , id := range rID {
194
+ ns := append (sig , byte (id ))
195
+ if pk , err := crypto .SigToPub (h [:], ns ); err != nil {
196
+ slog .Debug ("failed to recover public key from signature" , "error" , err , "recover_id" , id , "signature" , hexutil .Encode (sig ))
197
+ } else {
198
+ res = append (res , struct {
199
+ pk * ecdsa.PublicKey
200
+ sig []byte
201
+ }{pk : pk , sig : ns })
202
+ }
203
+ }
189
204
190
- pk , err := crypto .SigToPub (h , sig )
191
- if err != nil {
192
- return nil , "" , errors .Wrap (err , "failed to recover public key from signature" )
205
+ for _ , r := range res {
206
+ addr := crypto .PubkeyToAddress (* r .pk )
207
+ if bytes .Equal (addr .Bytes (), deviceAddr .Bytes ()) {
208
+ return addr , r .sig , "ES256" , nil
209
+ }
193
210
}
194
- return pk , "ES256 " , nil
211
+ return common. Address {}, nil , " " , errors . New ( "failed to recover public key from signature" )
195
212
}
196
213
}
197
214
0 commit comments