package nebula import ( "fmt" "reflect" "github.com/slackhq/nebula/cert" ) // Certificate wraps a NebulaCertificate to provide convenient (and consistent) // text (un)marshaling methods as well as normalization for equality checking. type Certificate struct { inner cert.NebulaCertificate } // NewCertificate returns a Certificate wrapping the given one. func NewCertificate(inner cert.NebulaCertificate) (Certificate, error) { // normalize the inner cert by marshaling to and unmarshaling from the PEM. // This allows equality checking in tests to work between certs which have // never been written to disk and those which have. b, err := inner.MarshalToPEM() if err != nil { return Certificate{}, fmt.Errorf("marshaling to PEM: %w", err) } normInner, _, err := cert.UnmarshalNebulaCertificateFromPEM(b) if err != nil { return Certificate{}, fmt.Errorf("unmarshaling from PEM: %w", err) } return Certificate{inner: *normInner}, nil } // Unwrap returns the wrapped NebulaCertificate type. func (c Certificate) Unwrap() *cert.NebulaCertificate { return &c.inner } // MarshalText implements the encoding.TextMarshaler interface. func (c Certificate) MarshalText() ([]byte, error) { if reflect.DeepEqual(c, Certificate{}) { return []byte(""), nil } return c.inner.MarshalToPEM() } // UnmarshalText implements the encoding.TextUnmarshaler interface. func (c *Certificate) UnmarshalText(b []byte) error { if len(b) == 0 { *c = Certificate{} return nil } nebCrt, _, err := cert.UnmarshalNebulaCertificateFromPEM(b) if err != nil { return fmt.Errorf("unmarshaling nebula certificate from PEM: %w", err) } c.inner = *nebCrt return nil }