...
1
16
17 package bootstrap
18
19 import (
20 "fmt"
21 "strings"
22
23 jose "gopkg.in/square/go-jose.v2"
24 )
25
26
27
28
29 func ComputeDetachedSignature(content, tokenID, tokenSecret string) (string, error) {
30 jwk := &jose.JSONWebKey{
31 Key: []byte(tokenSecret),
32 KeyID: tokenID,
33 }
34
35 opts := &jose.SignerOptions{
36
37
38
39 ExtraHeaders: map[jose.HeaderKey]interface{}{
40 "kid": tokenID,
41 },
42 }
43
44 signer, err := jose.NewSigner(jose.SigningKey{Algorithm: jose.HS256, Key: jwk}, opts)
45 if err != nil {
46 return "", fmt.Errorf("can't make a HS256 signer from the given token: %v", err)
47 }
48
49 jws, err := signer.Sign([]byte(content))
50 if err != nil {
51 return "", fmt.Errorf("can't HS256-sign the given token: %v", err)
52 }
53
54 fullSig, err := jws.CompactSerialize()
55 if err != nil {
56 return "", fmt.Errorf("can't serialize the given token: %v", err)
57 }
58 return stripContent(fullSig)
59 }
60
61
62
63
64
65
66 func stripContent(fullSig string) (string, error) {
67 parts := strings.Split(fullSig, ".")
68 if len(parts) != 3 {
69 return "", fmt.Errorf("compact JWS format must have three parts")
70 }
71
72 return parts[0] + ".." + parts[2], nil
73 }
74
75
76 func DetachedTokenIsValid(detachedToken, content, tokenID, tokenSecret string) bool {
77 newToken, err := ComputeDetachedSignature(content, tokenID, tokenSecret)
78 if err != nil {
79 return false
80 }
81 return detachedToken == newToken
82 }
83
View as plain text