Christopher Ramey
3 years ago
5 changed files with 114 additions and 16 deletions
@ -0,0 +1,72 @@ |
|||
package server |
|||
|
|||
import ( |
|||
"crypto/hmac" |
|||
"crypto/sha256" |
|||
"encoding/json" |
|||
"fmt" |
|||
"time" |
|||
) |
|||
|
|||
type APICommand struct { |
|||
Expires time.Time `json:"exp"` |
|||
Command string `json:"cmd"` |
|||
Scheme string `json:"sch"` |
|||
Signature []byte `json:"sig,omitempty"` |
|||
} |
|||
|
|||
func ParseAPICommand(jsn []byte) (*APICommand, error) { |
|||
api := &APICommand{} |
|||
err := json.Unmarshal(jsn, api) |
|||
if err != nil { |
|||
return nil, err |
|||
} |
|||
return api, nil |
|||
} |
|||
|
|||
func (ac *APICommand) JSON() ([]byte, error) { |
|||
return json.Marshal(ac) |
|||
} |
|||
|
|||
func (ac *APICommand) Sign(key []byte) error { |
|||
switch ac.Scheme { |
|||
case "hmac-sha256": |
|||
j, err := ac.JSON() |
|||
if err != nil { |
|||
return fmt.Errorf("json encoding error") |
|||
} |
|||
|
|||
mac := hmac.New(sha256.New, key) |
|||
mac.Write(j) |
|||
ac.Signature = mac.Sum(nil) |
|||
|
|||
case "": |
|||
return fmt.Errorf("scheme may not be empty") |
|||
|
|||
default: |
|||
return fmt.Errorf("unsupported scheme: %s", ac.Scheme) |
|||
} |
|||
return nil |
|||
} |
|||
|
|||
func (ac *APICommand) Validate(key []byte) error { |
|||
cpy := &APICommand{ |
|||
Expires: ac.Expires, |
|||
Command: ac.Command, |
|||
Scheme: ac.Scheme, |
|||
} |
|||
err := cpy.Sign(key) |
|||
if err != nil { |
|||
return err |
|||
} |
|||
|
|||
if !hmac.Equal(cpy.Signature, ac.Signature) { |
|||
return fmt.Errorf("invalid signature") |
|||
} |
|||
|
|||
if time.Now().After(ac.Expires) { |
|||
return fmt.Errorf("command expired") |
|||
} |
|||
|
|||
return nil |
|||
} |
Write
Preview
Loading…
Cancel
Save
Reference in new issue