fork of indigo with slightly nicer lexgen
at main 2.0 kB view raw
1package auth 2 3import ( 4 "crypto" 5 6 atcrypto "github.com/bluesky-social/indigo/atproto/crypto" 7 "github.com/golang-jwt/jwt/v5" 8) 9 10var ( 11 signingMethodES256K *signingMethodAtproto 12 signingMethodES256 *signingMethodAtproto 13 supportedAlgs []string 14) 15 16// Implementation of jwt.SigningMethod for the `atproto/crypto` types. 17type signingMethodAtproto struct { 18 alg string 19 hash crypto.Hash 20 toOutSig toOutSig 21 sigLen int 22} 23 24type toOutSig func(sig []byte) []byte 25 26func init() { 27 // tells JWT library to serialize 'aud' as regular string, not array of strings (when signing) 28 jwt.MarshalSingleStringAsArray = false 29 30 signingMethodES256K = &signingMethodAtproto{ 31 alg: "ES256K", 32 hash: crypto.SHA256, 33 toOutSig: toES256K, 34 sigLen: 64, 35 } 36 jwt.RegisterSigningMethod(signingMethodES256K.Alg(), func() jwt.SigningMethod { 37 return signingMethodES256K 38 }) 39 signingMethodES256 = &signingMethodAtproto{ 40 alg: "ES256", 41 hash: crypto.SHA256, 42 toOutSig: toES256, 43 sigLen: 64, 44 } 45 jwt.RegisterSigningMethod(signingMethodES256.Alg(), func() jwt.SigningMethod { 46 return signingMethodES256 47 }) 48 supportedAlgs = []string{signingMethodES256K.Alg(), signingMethodES256.Alg()} 49} 50 51func (sm *signingMethodAtproto) Verify(signingString string, sig []byte, key interface{}) error { 52 pub, ok := key.(atcrypto.PublicKey) 53 if !ok { 54 return jwt.ErrInvalidKeyType 55 } 56 57 if !sm.hash.Available() { 58 return jwt.ErrHashUnavailable 59 } 60 61 if len(sig) != sm.sigLen { 62 return jwt.ErrTokenSignatureInvalid 63 } 64 65 // NOTE: important to use using "lenient" variant here 66 return pub.HashAndVerifyLenient([]byte(signingString), sig) 67} 68 69func (sm *signingMethodAtproto) Sign(signingString string, key interface{}) ([]byte, error) { 70 priv, ok := key.(atcrypto.PrivateKey) 71 if !ok { 72 return nil, jwt.ErrInvalidKeyType 73 } 74 75 return priv.HashAndSign([]byte(signingString)) 76} 77 78func (sm *signingMethodAtproto) Alg() string { 79 return sm.alg 80} 81 82func toES256K(sig []byte) []byte { 83 return sig[:64] 84} 85 86func toES256(sig []byte) []byte { 87 return sig[:64] 88}