github.com/aarzilli/tools@v0.0.0-20151123112009-0d27094f75e0/appengine/login/googlesignin/jwt-go/rsa.go (about) 1 package jwt 2 3 import ( 4 "crypto" 5 "crypto/rand" 6 "crypto/rsa" 7 ) 8 9 // Implements the RSA family of signing methods signing methods 10 type SigningMethodRSA struct { 11 Name string 12 Hash crypto.Hash 13 } 14 15 // Specific instances for RS256 and company 16 var ( 17 SigningMethodRS256 *SigningMethodRSA 18 SigningMethodRS384 *SigningMethodRSA 19 SigningMethodRS512 *SigningMethodRSA 20 ) 21 22 func init() { 23 // RS256 24 SigningMethodRS256 = &SigningMethodRSA{"RS256", crypto.SHA256} 25 RegisterSigningMethod(SigningMethodRS256.Alg(), func() SigningMethod { 26 return SigningMethodRS256 27 }) 28 29 // RS384 30 SigningMethodRS384 = &SigningMethodRSA{"RS384", crypto.SHA384} 31 RegisterSigningMethod(SigningMethodRS384.Alg(), func() SigningMethod { 32 return SigningMethodRS384 33 }) 34 35 // RS512 36 SigningMethodRS512 = &SigningMethodRSA{"RS512", crypto.SHA512} 37 RegisterSigningMethod(SigningMethodRS512.Alg(), func() SigningMethod { 38 return SigningMethodRS512 39 }) 40 } 41 42 func (m *SigningMethodRSA) Alg() string { 43 return m.Name 44 } 45 46 // Implements the Verify method from SigningMethod 47 // For this signing method, must be either a PEM encoded PKCS1 or PKCS8 RSA public key as 48 // []byte, or an rsa.PublicKey structure. 49 func (m *SigningMethodRSA) Verify(signingString, signature string, key interface{}) error { 50 var err error 51 52 // Decode the signature 53 var sig []byte 54 if sig, err = DecodeSegment(signature); err != nil { 55 return err 56 } 57 58 var rsaKey *rsa.PublicKey 59 60 switch k := key.(type) { 61 case string: 62 if rsaKey, err = ParseRSAPublicKeyFromPEM([]byte(k)); err != nil { 63 return err 64 } 65 case []byte: 66 if rsaKey, err = ParseRSAPublicKeyFromPEM(k); err != nil { 67 return err 68 } 69 case *rsa.PublicKey: 70 rsaKey = k 71 default: 72 return ErrInvalidKey 73 } 74 75 // Create hasher 76 if !m.Hash.Available() { 77 return ErrHashUnavailable 78 } 79 hasher := m.Hash.New() 80 hasher.Write([]byte(signingString)) 81 82 // Verify the signature 83 return rsa.VerifyPKCS1v15(rsaKey, m.Hash, hasher.Sum(nil), sig) 84 } 85 86 // Implements the Sign method from SigningMethod 87 // For this signing method, must be either a PEM encoded PKCS1 or PKCS8 RSA private key as 88 // []byte, or an rsa.PrivateKey structure. 89 func (m *SigningMethodRSA) Sign(signingString string, key interface{}) (string, error) { 90 var err error 91 var rsaKey *rsa.PrivateKey 92 93 switch k := key.(type) { 94 case []byte: 95 if rsaKey, err = ParseRSAPrivateKeyFromPEM(k); err != nil { 96 return "", err 97 } 98 case *rsa.PrivateKey: 99 rsaKey = k 100 default: 101 return "", ErrInvalidKey 102 } 103 104 // Create the hasher 105 if !m.Hash.Available() { 106 return "", ErrHashUnavailable 107 } 108 109 hasher := m.Hash.New() 110 hasher.Write([]byte(signingString)) 111 112 // Sign the string and return the encoded bytes 113 if sigBytes, err := rsa.SignPKCS1v15(rand.Reader, rsaKey, m.Hash, hasher.Sum(nil)); err == nil { 114 return EncodeSegment(sigBytes), nil 115 } else { 116 return "", err 117 } 118 }