github.com/lestrrat-go/jwx/v2@v2.0.21/jws/interface.go (about) 1 package jws 2 3 import ( 4 "github.com/lestrrat-go/iter/mapiter" 5 "github.com/lestrrat-go/jwx/v2/internal/iter" 6 "github.com/lestrrat-go/jwx/v2/jwa" 7 ) 8 9 type DecodeCtx interface { 10 CollectRaw() bool 11 } 12 13 // Message represents a full JWS encoded message. Flattened serialization 14 // is not supported as a struct, but rather it's represented as a 15 // Message struct with only one `signature` element. 16 // 17 // Do not expect to use the Message object to verify or construct a 18 // signed payload with. You should only use this when you want to actually 19 // programmatically view the contents of the full JWS payload. 20 // 21 // As of this version, there is one big incompatibility when using Message 22 // objects to convert between compact and JSON representations. 23 // The protected header is sometimes encoded differently from the original 24 // message and the JSON serialization that we use in Go. 25 // 26 // For example, the protected header `eyJ0eXAiOiJKV1QiLA0KICJhbGciOiJIUzI1NiJ9` 27 // decodes to 28 // 29 // {"typ":"JWT", 30 // "alg":"HS256"} 31 // 32 // However, when we parse this into a message, we create a jws.Header object, 33 // which, when we marshal into a JSON object again, becomes 34 // 35 // {"typ":"JWT","alg":"HS256"} 36 // 37 // Notice that serialization lacks a line break and a space between `"JWT",` 38 // and `"alg"`. This causes a problem when verifying the signatures AFTER 39 // a compact JWS message has been unmarshaled into a jws.Message. 40 // 41 // jws.Verify() doesn't go through this step, and therefore this does not 42 // manifest itself. However, you may see this discrepancy when you manually 43 // go through these conversions, and/or use the `jwx` tool like so: 44 // 45 // jwx jws parse message.jws | jwx jws verify --key somekey.jwk --stdin 46 // 47 // In this scenario, the first `jwx jws parse` outputs a parsed jws.Message 48 // which is marshaled into JSON. At this point the message's protected 49 // headers and the signatures don't match. 50 // 51 // To sign and verify, use the appropriate `Sign()` and `Verify()` functions. 52 type Message struct { 53 dc DecodeCtx 54 payload []byte 55 signatures []*Signature 56 b64 bool // true if payload should be base64 encoded 57 } 58 59 type Signature struct { 60 dc DecodeCtx 61 headers Headers // Unprotected Headers 62 protected Headers // Protected Headers 63 signature []byte // Signature 64 detached bool 65 } 66 67 type Visitor = iter.MapVisitor 68 type VisitorFunc = iter.MapVisitorFunc 69 type HeaderPair = mapiter.Pair 70 type Iterator = mapiter.Iterator 71 72 // Signer generates the signature for a given payload. 73 type Signer interface { 74 // Sign creates a signature for the given payload. 75 // The second argument is the key used for signing the payload, and is usually 76 // the private key type associated with the signature method. For example, 77 // for `jwa.RSXXX` and `jwa.PSXXX` types, you need to pass the 78 // `*"crypto/rsa".PrivateKey` type. 79 // Check the documentation for each signer for details 80 Sign([]byte, interface{}) ([]byte, error) 81 82 Algorithm() jwa.SignatureAlgorithm 83 } 84 85 type hmacSignFunc func([]byte, []byte) ([]byte, error) 86 87 // HMACSigner uses crypto/hmac to sign the payloads. 88 type HMACSigner struct { 89 alg jwa.SignatureAlgorithm 90 sign hmacSignFunc 91 } 92 93 type Verifier interface { 94 // Verify checks whether the payload and signature are valid for 95 // the given key. 96 // `key` is the key used for verifying the payload, and is usually 97 // the public key associated with the signature method. For example, 98 // for `jwa.RSXXX` and `jwa.PSXXX` types, you need to pass the 99 // `*"crypto/rsa".PublicKey` type. 100 // Check the documentation for each verifier for details 101 Verify(payload []byte, signature []byte, key interface{}) error 102 } 103 104 type HMACVerifier struct { 105 signer Signer 106 }