github.com/lestrrat-go/jwx/v2@v2.0.21/cert/chain.go (about) 1 package cert 2 3 import ( 4 "bytes" 5 "encoding/json" 6 "fmt" 7 ) 8 9 // Chain represents a certificate chain as used in the `x5c` field of 10 // various objects within JOSE. 11 // 12 // It stores the certificates as a list of base64 encoded []byte 13 // sequence. By definition these values must PKIX encoded. 14 type Chain struct { 15 certificates [][]byte 16 } 17 18 func (cc Chain) MarshalJSON() ([]byte, error) { 19 var buf bytes.Buffer 20 buf.WriteByte('[') 21 for i, cert := range cc.certificates { 22 if i > 0 { 23 buf.WriteByte(',') 24 } 25 buf.WriteByte('"') 26 buf.Write(cert) 27 buf.WriteByte('"') 28 } 29 buf.WriteByte(']') 30 return buf.Bytes(), nil 31 } 32 33 func (cc *Chain) UnmarshalJSON(data []byte) error { 34 var tmp []string 35 if err := json.Unmarshal(data, &tmp); err != nil { 36 return fmt.Errorf(`failed to unmarshal certificate chain: %w`, err) 37 } 38 39 certs := make([][]byte, len(tmp)) 40 for i, cert := range tmp { 41 certs[i] = []byte(cert) 42 } 43 cc.certificates = certs 44 return nil 45 } 46 47 // Get returns the n-th ASN.1 DER + base64 encoded certificate 48 // stored. `false` will be returned in the second argument if 49 // the corresponding index is out of range. 50 func (cc *Chain) Get(index int) ([]byte, bool) { 51 if index < 0 || index >= len(cc.certificates) { 52 return nil, false 53 } 54 55 return cc.certificates[index], true 56 } 57 58 // Len returns the number of certificates stored in this Chain 59 func (cc *Chain) Len() int { 60 return len(cc.certificates) 61 } 62 63 var pemStart = []byte("----- BEGIN CERTIFICATE -----") 64 var pemEnd = []byte("----- END CERTIFICATE -----") 65 66 func (cc *Chain) AddString(der string) error { 67 return cc.Add([]byte(der)) 68 } 69 70 func (cc *Chain) Add(der []byte) error { 71 // We're going to be nice and remove marker lines if they 72 // give it to us 73 der = bytes.TrimPrefix(der, pemStart) 74 der = bytes.TrimSuffix(der, pemEnd) 75 der = bytes.TrimSpace(der) 76 cc.certificates = append(cc.certificates, der) 77 return nil 78 }