certchain.go 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. package jwk
  2. import (
  3. "crypto/x509"
  4. "github.com/lestrrat-go/jwx/internal/json"
  5. "github.com/lestrrat-go/jwx/internal/base64"
  6. "github.com/pkg/errors"
  7. )
  8. func (c CertificateChain) MarshalJSON() ([]byte, error) {
  9. certs := c.Get()
  10. encoded := make([]string, len(certs))
  11. for i := 0; i < len(certs); i++ {
  12. encoded[i] = base64.EncodeToStringStd(certs[i].Raw)
  13. }
  14. return json.Marshal(encoded)
  15. }
  16. func (c *CertificateChain) UnmarshalJSON(buf []byte) error {
  17. var list []string
  18. if err := json.Unmarshal(buf, &list); err != nil {
  19. return errors.Wrap(err, `failed to unmarshal JSON into []string`)
  20. }
  21. var tmp CertificateChain
  22. if err := tmp.Accept(list); err != nil {
  23. return err
  24. }
  25. *c = tmp
  26. return nil
  27. }
  28. func (c CertificateChain) Get() []*x509.Certificate {
  29. return c.certs
  30. }
  31. func (c *CertificateChain) Accept(v interface{}) error {
  32. var list []string
  33. switch x := v.(type) {
  34. case string:
  35. list = []string{x}
  36. case []interface{}:
  37. list = make([]string, len(x))
  38. for i, e := range x {
  39. if es, ok := e.(string); ok {
  40. list[i] = es
  41. continue
  42. }
  43. return errors.Errorf(`invalid list element type: expected string, got %T at element %d`, e, i)
  44. }
  45. case []string:
  46. list = x
  47. case CertificateChain:
  48. certs := make([]*x509.Certificate, len(x.certs))
  49. copy(certs, x.certs)
  50. *c = CertificateChain{
  51. certs: certs,
  52. }
  53. return nil
  54. default:
  55. return errors.Errorf(`invalid type for CertificateChain: %T`, v)
  56. }
  57. certs := make([]*x509.Certificate, len(list))
  58. for i, e := range list {
  59. buf, err := base64.DecodeString(e)
  60. if err != nil {
  61. return errors.Wrap(err, `failed to base64 decode list element`)
  62. }
  63. cert, err := x509.ParseCertificate(buf)
  64. if err != nil {
  65. return errors.Wrap(err, `failed to parse certificate`)
  66. }
  67. certs[i] = cert
  68. }
  69. *c = CertificateChain{
  70. certs: certs,
  71. }
  72. return nil
  73. }