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  }