symmetric.go 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. package jwk
  2. import (
  3. "crypto"
  4. "encoding/json"
  5. "fmt"
  6. "github.com/lestrrat/go-jwx/internal/base64"
  7. "github.com/lestrrat/go-jwx/jwa"
  8. pdebug "github.com/lestrrat/go-pdebug"
  9. "github.com/pkg/errors"
  10. )
  11. func newSymmetricKey(key []byte) (*SymmetricKey, error) {
  12. if len(key) == 0 {
  13. return nil, errors.New(`non-empty []byte key required`)
  14. }
  15. var hdr StandardHeaders
  16. hdr.Set(KeyTypeKey, jwa.OctetSeq)
  17. return &SymmetricKey{
  18. headers: &hdr,
  19. key: key,
  20. }, nil
  21. }
  22. // Materialize returns the octets for this symmetric key.
  23. // Since this is a symmetric key, this just calls Octets
  24. func (s SymmetricKey) Materialize() (interface{}, error) {
  25. return s.Octets(), nil
  26. }
  27. // Octets returns the octets in the key
  28. func (s SymmetricKey) Octets() []byte {
  29. return s.key
  30. }
  31. // Thumbprint returns the JWK thumbprint using the indicated
  32. // hashing algorithm, according to RFC 7638
  33. func (s SymmetricKey) Thumbprint(hash crypto.Hash) ([]byte, error) {
  34. h := hash.New()
  35. fmt.Fprintf(h, `{"k":"`)
  36. fmt.Fprintf(h, base64.EncodeToString(s.key))
  37. fmt.Fprintf(h, `","kty":"oct"}`)
  38. return h.Sum(nil), nil
  39. }
  40. func (k *SymmetricKey) UnmarshalJSON(data []byte) (err error) {
  41. if pdebug.Enabled {
  42. g := pdebug.Marker("jwk.SymmetricKey.UnmarshalJSON").BindError(&err)
  43. defer g.End()
  44. }
  45. m := map[string]interface{}{}
  46. if err := json.Unmarshal(data, &m); err != nil {
  47. return errors.Wrap(err, `failed to unmarshal public key`)
  48. }
  49. if err := k.ExtractMap(m); err != nil {
  50. return errors.Wrap(err, `failed to extract data from map`)
  51. }
  52. return nil
  53. }
  54. func (s *SymmetricKey) ExtractMap(m map[string]interface{}) (err error) {
  55. if pdebug.Enabled {
  56. g := pdebug.Marker("jwk.SymmetricKey.ExtractMap").BindError(&err)
  57. defer g.End()
  58. }
  59. const kKey = `k`
  60. kbuf, err := getRequiredKey(m, kKey)
  61. if err != nil {
  62. return errors.Wrapf(err, `failed to get required key '%s'`, kKey)
  63. }
  64. delete(m, kKey)
  65. var hdrs StandardHeaders
  66. if err := hdrs.ExtractMap(m); err != nil {
  67. return errors.Wrap(err, `failed to extract header values`)
  68. }
  69. *s = SymmetricKey{
  70. headers: &hdrs,
  71. key: kbuf,
  72. }
  73. return nil
  74. }
  75. func (s SymmetricKey) MarshalJSON() (buf []byte, err error) {
  76. if pdebug.Enabled {
  77. g := pdebug.Marker("jwk.SymmetricKey.MarshalJSON").BindError(&err)
  78. defer g.End()
  79. }
  80. m := make(map[string]interface{})
  81. if err := s.PopulateMap(m); err != nil {
  82. return nil, errors.Wrap(err, `failed to populate symmetric key values`)
  83. }
  84. return json.Marshal(m)
  85. }
  86. func (s SymmetricKey) PopulateMap(m map[string]interface{}) (err error) {
  87. if pdebug.Enabled {
  88. g := pdebug.Marker("jwk.SymmetricKey.PopulateMap").BindError(&err)
  89. defer g.End()
  90. }
  91. if err := s.headers.PopulateMap(m); err != nil {
  92. return errors.Wrap(err, `failed to populate header values`)
  93. }
  94. const kKey = `k`
  95. m[kKey] = base64.EncodeToString(s.key)
  96. return nil
  97. }