interface.go 3.6 KB

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