@@ -42,6 +42,7 @@ type Authority interface {
42
42
GetEncryptedKey (kid string ) (string , error )
43
43
GetRoots () (federation []* x509.Certificate , err error )
44
44
GetFederation () ([]* x509.Certificate , error )
45
+ Version () authority.Version
45
46
}
46
47
47
48
// TimeDuration is an alias of provisioner.TimeDuration
@@ -71,6 +72,13 @@ func NewCertificate(cr *x509.Certificate) Certificate {
71
72
}
72
73
}
73
74
75
+ // reset sets the inner x509.CertificateRequest to nil
76
+ func (c * Certificate ) reset () {
77
+ if c != nil {
78
+ c .Certificate = nil
79
+ }
80
+ }
81
+
74
82
// MarshalJSON implements the json.Marshaler interface. The certificate is
75
83
// quoted string using the PEM encoding.
76
84
func (c Certificate ) MarshalJSON () ([]byte , error ) {
@@ -91,6 +99,13 @@ func (c *Certificate) UnmarshalJSON(data []byte) error {
91
99
if err := json .Unmarshal (data , & s ); err != nil {
92
100
return errors .Wrap (err , "error decoding certificate" )
93
101
}
102
+
103
+ // Make sure the inner x509.Certificate is nil
104
+ if s == "null" || s == "" {
105
+ c .reset ()
106
+ return nil
107
+ }
108
+
94
109
block , _ := pem .Decode ([]byte (s ))
95
110
if block == nil {
96
111
return errors .New ("error decoding certificate" )
@@ -117,6 +132,13 @@ func NewCertificateRequest(cr *x509.CertificateRequest) CertificateRequest {
117
132
}
118
133
}
119
134
135
+ // reset sets the inner x509.CertificateRequest to nil
136
+ func (c * CertificateRequest ) reset () {
137
+ if c != nil {
138
+ c .CertificateRequest = nil
139
+ }
140
+ }
141
+
120
142
// MarshalJSON implements the json.Marshaler interface. The certificate request
121
143
// is a quoted string using the PEM encoding.
122
144
func (c CertificateRequest ) MarshalJSON () ([]byte , error ) {
@@ -137,6 +159,13 @@ func (c *CertificateRequest) UnmarshalJSON(data []byte) error {
137
159
if err := json .Unmarshal (data , & s ); err != nil {
138
160
return errors .Wrap (err , "error decoding csr" )
139
161
}
162
+
163
+ // Make sure the inner x509.CertificateRequest is nil
164
+ if s == "null" || s == "" {
165
+ c .reset ()
166
+ return nil
167
+ }
168
+
140
169
block , _ := pem .Decode ([]byte (s ))
141
170
if block == nil {
142
171
return errors .New ("error decoding csr" )
@@ -162,6 +191,13 @@ type RouterHandler interface {
162
191
Route (r Router )
163
192
}
164
193
194
+ // VersionResponse is the response object that returns the version of the
195
+ // server.
196
+ type VersionResponse struct {
197
+ Version string `json:"version"`
198
+ RequireClientAuthentication bool `json:"requireClientAuthentication,omitempty"`
199
+ }
200
+
165
201
// HealthResponse is the response object that returns the health of the server.
166
202
type HealthResponse struct {
167
203
Status string `json:"status"`
@@ -241,6 +277,7 @@ func New(authority Authority) RouterHandler {
241
277
}
242
278
243
279
func (h * caHandler ) Route (r Router ) {
280
+ r .MethodFunc ("GET" , "/version" , h .Version )
244
281
r .MethodFunc ("GET" , "/health" , h .Health )
245
282
r .MethodFunc ("GET" , "/root/{sha}" , h .Root )
246
283
r .MethodFunc ("POST" , "/sign" , h .Sign )
@@ -268,6 +305,15 @@ func (h *caHandler) Route(r Router) {
268
305
r .MethodFunc ("POST" , "/sign-ssh" , h .SSHSign )
269
306
}
270
307
308
+ // Version is an HTTP handler that returns the version of the server.
309
+ func (h * caHandler ) Version (w http.ResponseWriter , r * http.Request ) {
310
+ v := h .Authority .Version ()
311
+ JSON (w , VersionResponse {
312
+ Version : v .Version ,
313
+ RequireClientAuthentication : v .RequireClientAuthentication ,
314
+ })
315
+ }
316
+
271
317
// Health is an HTTP handler that returns the status of the server.
272
318
func (h * caHandler ) Health (w http.ResponseWriter , r * http.Request ) {
273
319
JSON (w , HealthResponse {Status : "ok" })
0 commit comments