- Notifications
You must be signed in to change notification settings - Fork 371
/
Copy pathrsa_pss.go
135 lines (119 loc) · 3.38 KB
/
rsa_pss.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
//go:build go1.4
// +build go1.4
package jwt
import (
"crypto"
"crypto/rand"
"crypto/rsa"
)
// SigningMethodRSAPSS implements the RSAPSS family of signing methods signing methods
typeSigningMethodRSAPSSstruct {
*SigningMethodRSA
Options*rsa.PSSOptions
// VerifyOptions is optional. If set overrides Options for rsa.VerifyPPS.
// Used to accept tokens signed with rsa.PSSSaltLengthAuto, what doesn't follow
// https://tools.ietf.org/html/rfc7518#section-3.5 but was used previously.
// See https://github.com/dgrijalva/jwt-go/issues/285#issuecomment-437451244 for details.
VerifyOptions*rsa.PSSOptions
}
// Specific instances for RS/PS and company.
var (
SigningMethodPS256*SigningMethodRSAPSS
SigningMethodPS384*SigningMethodRSAPSS
SigningMethodPS512*SigningMethodRSAPSS
)
funcinit() {
// PS256
SigningMethodPS256=&SigningMethodRSAPSS{
SigningMethodRSA: &SigningMethodRSA{
Name: "PS256",
Hash: crypto.SHA256,
},
Options: &rsa.PSSOptions{
SaltLength: rsa.PSSSaltLengthEqualsHash,
},
VerifyOptions: &rsa.PSSOptions{
SaltLength: rsa.PSSSaltLengthAuto,
},
}
RegisterSigningMethod(SigningMethodPS256.Alg(), func() SigningMethod {
returnSigningMethodPS256
})
// PS384
SigningMethodPS384=&SigningMethodRSAPSS{
SigningMethodRSA: &SigningMethodRSA{
Name: "PS384",
Hash: crypto.SHA384,
},
Options: &rsa.PSSOptions{
SaltLength: rsa.PSSSaltLengthEqualsHash,
},
VerifyOptions: &rsa.PSSOptions{
SaltLength: rsa.PSSSaltLengthAuto,
},
}
RegisterSigningMethod(SigningMethodPS384.Alg(), func() SigningMethod {
returnSigningMethodPS384
})
// PS512
SigningMethodPS512=&SigningMethodRSAPSS{
SigningMethodRSA: &SigningMethodRSA{
Name: "PS512",
Hash: crypto.SHA512,
},
Options: &rsa.PSSOptions{
SaltLength: rsa.PSSSaltLengthEqualsHash,
},
VerifyOptions: &rsa.PSSOptions{
SaltLength: rsa.PSSSaltLengthAuto,
},
}
RegisterSigningMethod(SigningMethodPS512.Alg(), func() SigningMethod {
returnSigningMethodPS512
})
}
// Verify implements token verification for the SigningMethod.
// For this verify method, key must be an rsa.PublicKey struct
func (m*SigningMethodRSAPSS) Verify(signingStringstring, sig []byte, keyinterface{}) error {
varrsaKey*rsa.PublicKey
switchk:=key.(type) {
case*rsa.PublicKey:
rsaKey=k
default:
returnnewError("RSA-PSS verify expects *rsa.PublicKey", ErrInvalidKeyType)
}
// Create hasher
if!m.Hash.Available() {
returnErrHashUnavailable
}
hasher:=m.Hash.New()
hasher.Write([]byte(signingString))
opts:=m.Options
ifm.VerifyOptions!=nil {
opts=m.VerifyOptions
}
returnrsa.VerifyPSS(rsaKey, m.Hash, hasher.Sum(nil), sig, opts)
}
// Sign implements token signing for the SigningMethod.
// For this signing method, key must be an rsa.PrivateKey struct
func (m*SigningMethodRSAPSS) Sign(signingStringstring, keyinterface{}) ([]byte, error) {
varrsaKey*rsa.PrivateKey
switchk:=key.(type) {
case*rsa.PrivateKey:
rsaKey=k
default:
returnnil, newError("RSA-PSS sign expects *rsa.PrivateKey", ErrInvalidKeyType)
}
// Create the hasher
if!m.Hash.Available() {
returnnil, ErrHashUnavailable
}
hasher:=m.Hash.New()
hasher.Write([]byte(signingString))
// Sign the string and return the encoded bytes
ifsigBytes, err:=rsa.SignPSS(rand.Reader, rsaKey, m.Hash, hasher.Sum(nil), m.Options); err==nil {
returnsigBytes, nil
} else {
returnnil, err
}
}