You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

rsa_pss.go 3.4KB

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