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