Tizen_4.0 base
[platform/upstream/docker-engine.git] / vendor / github.com / cloudflare / cfssl / errors / error.go
1 package errors
2
3 import (
4         "crypto/x509"
5         "encoding/json"
6         "fmt"
7 )
8
9 // Error is the error type usually returned by functions in CF SSL package.
10 // It contains a 4-digit error code where the most significant digit
11 // describes the category where the error occurred and the rest 3 digits
12 // describe the specific error reason.
13 type Error struct {
14         ErrorCode int    `json:"code"`
15         Message   string `json:"message"`
16 }
17
18 // Category is the most significant digit of the error code.
19 type Category int
20
21 // Reason is the last 3 digits of the error code.
22 type Reason int
23
24 const (
25         // Success indicates no error occurred.
26         Success Category = 1000 * iota // 0XXX
27
28         // CertificateError indicates a fault in a certificate.
29         CertificateError // 1XXX
30
31         // PrivateKeyError indicates a fault in a private key.
32         PrivateKeyError // 2XXX
33
34         // IntermediatesError indicates a fault in an intermediate.
35         IntermediatesError // 3XXX
36
37         // RootError indicates a fault in a root.
38         RootError // 4XXX
39
40         // PolicyError indicates an error arising from a malformed or
41         // non-existent policy, or a breach of policy.
42         PolicyError // 5XXX
43
44         // DialError indicates a network fault.
45         DialError // 6XXX
46
47         // APIClientError indicates a problem with the API client.
48         APIClientError // 7XXX
49
50         // OCSPError indicates a problem with OCSP signing
51         OCSPError // 8XXX
52
53         // CSRError indicates a problem with CSR parsing
54         CSRError // 9XXX
55
56         // CTError indicates a problem with the certificate transparency process
57         CTError // 10XXX
58
59         // CertStoreError indicates a problem with the certificate store
60         CertStoreError // 11XXX
61 )
62
63 // None is a non-specified error.
64 const (
65         None Reason = iota
66 )
67
68 // Warning code for a success
69 const (
70         BundleExpiringBit      int = 1 << iota // 0x01
71         BundleNotUbiquitousBit                 // 0x02
72 )
73
74 // Parsing errors
75 const (
76         Unknown      Reason = iota // X000
77         ReadFailed                 // X001
78         DecodeFailed               // X002
79         ParseFailed                // X003
80 )
81
82 // The following represent certificate non-parsing errors, and must be
83 // specified along with CertificateError.
84 const (
85         // SelfSigned indicates that a certificate is self-signed and
86         // cannot be used in the manner being attempted.
87         SelfSigned Reason = 100 * (iota + 1) // Code 11XX
88
89         // VerifyFailed is an X.509 verification failure. The least two
90         // significant digits of 12XX is determined as the actual x509
91         // error is examined.
92         VerifyFailed // Code 12XX
93
94         // BadRequest indicates that the certificate request is invalid.
95         BadRequest // Code 13XX
96
97         // MissingSerial indicates that the profile specified
98         // 'ClientProvidesSerialNumbers', but the SignRequest did not include a serial
99         // number.
100         MissingSerial // Code 14XX
101 )
102
103 const (
104         certificateInvalid = 10 * (iota + 1) //121X
105         unknownAuthority                     //122x
106 )
107
108 // The following represent private-key non-parsing errors, and must be
109 // specified with PrivateKeyError.
110 const (
111         // Encrypted indicates that the private key is a PKCS #8 encrypted
112         // private key. At this time, CFSSL does not support decrypting
113         // these keys.
114         Encrypted Reason = 100 * (iota + 1) //21XX
115
116         // NotRSAOrECC indicates that they key is not an RSA or ECC
117         // private key; these are the only two private key types supported
118         // at this time by CFSSL.
119         NotRSAOrECC //22XX
120
121         // KeyMismatch indicates that the private key does not match
122         // the public key or certificate being presented with the key.
123         KeyMismatch //23XX
124
125         // GenerationFailed indicates that a private key could not
126         // be generated.
127         GenerationFailed //24XX
128
129         // Unavailable indicates that a private key mechanism (such as
130         // PKCS #11) was requested but support for that mechanism is
131         // not available.
132         Unavailable
133 )
134
135 // The following are policy-related non-parsing errors, and must be
136 // specified along with PolicyError.
137 const (
138         // NoKeyUsages indicates that the profile does not permit any
139         // key usages for the certificate.
140         NoKeyUsages Reason = 100 * (iota + 1) // 51XX
141
142         // InvalidPolicy indicates that policy being requested is not
143         // a valid policy or does not exist.
144         InvalidPolicy // 52XX
145
146         // InvalidRequest indicates a certificate request violated the
147         // constraints of the policy being applied to the request.
148         InvalidRequest // 53XX
149
150         // UnknownProfile indicates that the profile does not exist.
151         UnknownProfile // 54XX
152
153         UnmatchedWhitelist // 55xx
154 )
155
156 // The following are API client related errors, and should be
157 // specified with APIClientError.
158 const (
159         // AuthenticationFailure occurs when the client is unable
160         // to obtain an authentication token for the request.
161         AuthenticationFailure Reason = 100 * (iota + 1)
162
163         // JSONError wraps an encoding/json error.
164         JSONError
165
166         // IOError wraps an io/ioutil error.
167         IOError
168
169         // ClientHTTPError wraps a net/http error.
170         ClientHTTPError
171
172         // ServerRequestFailed covers any other failures from the API
173         // client.
174         ServerRequestFailed
175 )
176
177 // The following are OCSP related errors, and should be
178 // specified with OCSPError
179 const (
180         // IssuerMismatch ocurs when the certificate in the OCSP signing
181         // request was not issued by the CA that this responder responds for.
182         IssuerMismatch Reason = 100 * (iota + 1) // 81XX
183
184         // InvalidStatus occurs when the OCSP signing requests includes an
185         // invalid value for the certificate status.
186         InvalidStatus
187 )
188
189 // Certificate transparency related errors specified with CTError
190 const (
191         // PrecertSubmissionFailed occurs when submitting a precertificate to
192         // a log server fails
193         PrecertSubmissionFailed = 100 * (iota + 1)
194 )
195
196 // Certificate persistence related errors specified with CertStoreError
197 const (
198         // InsertionFailed occurs when a SQL insert query failes to complete.
199         InsertionFailed = 100 * (iota + 1)
200         // RecordNotFound occurs when a SQL query targeting on one unique
201         // record failes to update the specified row in the table.
202         RecordNotFound
203 )
204
205 // The error interface implementation, which formats to a JSON object string.
206 func (e *Error) Error() string {
207         marshaled, err := json.Marshal(e)
208         if err != nil {
209                 panic(err)
210         }
211         return string(marshaled)
212
213 }
214
215 // New returns an error that contains  an error code and message derived from
216 // the given category, reason. Currently, to avoid confusion, it is not
217 // allowed to create an error of category Success
218 func New(category Category, reason Reason) *Error {
219         errorCode := int(category) + int(reason)
220         var msg string
221         switch category {
222         case OCSPError:
223                 switch reason {
224                 case ReadFailed:
225                         msg = "No certificate provided"
226                 case IssuerMismatch:
227                         msg = "Certificate not issued by this issuer"
228                 case InvalidStatus:
229                         msg = "Invalid revocation status"
230                 }
231         case CertificateError:
232                 switch reason {
233                 case Unknown:
234                         msg = "Unknown certificate error"
235                 case ReadFailed:
236                         msg = "Failed to read certificate"
237                 case DecodeFailed:
238                         msg = "Failed to decode certificate"
239                 case ParseFailed:
240                         msg = "Failed to parse certificate"
241                 case SelfSigned:
242                         msg = "Certificate is self signed"
243                 case VerifyFailed:
244                         msg = "Unable to verify certificate"
245                 case BadRequest:
246                         msg = "Invalid certificate request"
247                 case MissingSerial:
248                         msg = "Missing serial number in request"
249                 default:
250                         panic(fmt.Sprintf("Unsupported CFSSL error reason %d under category CertificateError.",
251                                 reason))
252
253                 }
254         case PrivateKeyError:
255                 switch reason {
256                 case Unknown:
257                         msg = "Unknown private key error"
258                 case ReadFailed:
259                         msg = "Failed to read private key"
260                 case DecodeFailed:
261                         msg = "Failed to decode private key"
262                 case ParseFailed:
263                         msg = "Failed to parse private key"
264                 case Encrypted:
265                         msg = "Private key is encrypted."
266                 case NotRSAOrECC:
267                         msg = "Private key algorithm is not RSA or ECC"
268                 case KeyMismatch:
269                         msg = "Private key does not match public key"
270                 case GenerationFailed:
271                         msg = "Failed to new private key"
272                 case Unavailable:
273                         msg = "Private key is unavailable"
274                 default:
275                         panic(fmt.Sprintf("Unsupported CFSSL error reason %d under category PrivateKeyError.",
276                                 reason))
277                 }
278         case IntermediatesError:
279                 switch reason {
280                 case Unknown:
281                         msg = "Unknown intermediate certificate error"
282                 case ReadFailed:
283                         msg = "Failed to read intermediate certificate"
284                 case DecodeFailed:
285                         msg = "Failed to decode intermediate certificate"
286                 case ParseFailed:
287                         msg = "Failed to parse intermediate certificate"
288                 default:
289                         panic(fmt.Sprintf("Unsupported CFSSL error reason %d under category IntermediatesError.",
290                                 reason))
291                 }
292         case RootError:
293                 switch reason {
294                 case Unknown:
295                         msg = "Unknown root certificate error"
296                 case ReadFailed:
297                         msg = "Failed to read root certificate"
298                 case DecodeFailed:
299                         msg = "Failed to decode root certificate"
300                 case ParseFailed:
301                         msg = "Failed to parse root certificate"
302                 default:
303                         panic(fmt.Sprintf("Unsupported CFSSL error reason %d under category RootError.",
304                                 reason))
305                 }
306         case PolicyError:
307                 switch reason {
308                 case Unknown:
309                         msg = "Unknown policy error"
310                 case NoKeyUsages:
311                         msg = "Invalid policy: no key usage available"
312                 case InvalidPolicy:
313                         msg = "Invalid or unknown policy"
314                 case InvalidRequest:
315                         msg = "Policy violation request"
316                 case UnknownProfile:
317                         msg = "Unknown policy profile"
318                 case UnmatchedWhitelist:
319                         msg = "Request does not match policy whitelist"
320                 default:
321                         panic(fmt.Sprintf("Unsupported CFSSL error reason %d under category PolicyError.",
322                                 reason))
323                 }
324         case DialError:
325                 switch reason {
326                 case Unknown:
327                         msg = "Failed to dial remote server"
328                 default:
329                         panic(fmt.Sprintf("Unsupported CFSSL error reason %d under category DialError.",
330                                 reason))
331                 }
332         case APIClientError:
333                 switch reason {
334                 case AuthenticationFailure:
335                         msg = "API client authentication failure"
336                 case JSONError:
337                         msg = "API client JSON config error"
338                 case ClientHTTPError:
339                         msg = "API client HTTP error"
340                 case IOError:
341                         msg = "API client IO error"
342                 case ServerRequestFailed:
343                         msg = "API client error: Server request failed"
344                 default:
345                         panic(fmt.Sprintf("Unsupported CFSSL error reason %d under category APIClientError.",
346                                 reason))
347                 }
348         case CSRError:
349                 switch reason {
350                 case Unknown:
351                         msg = "CSR parsing failed due to unknown error"
352                 case ReadFailed:
353                         msg = "CSR file read failed"
354                 case ParseFailed:
355                         msg = "CSR Parsing failed"
356                 case DecodeFailed:
357                         msg = "CSR Decode failed"
358                 case BadRequest:
359                         msg = "CSR Bad request"
360                 default:
361                         panic(fmt.Sprintf("Unsupported CF-SSL error reason %d under category APIClientError.", reason))
362                 }
363         case CTError:
364                 switch reason {
365                 case Unknown:
366                         msg = "Certificate transparency parsing failed due to unknown error"
367                 case PrecertSubmissionFailed:
368                         msg = "Certificate transparency precertificate submission failed"
369                 default:
370                         panic(fmt.Sprintf("Unsupported CF-SSL error reason %d under category CTError.", reason))
371                 }
372         case CertStoreError:
373                 switch reason {
374                 case Unknown:
375                         msg = "Certificate store action failed due to unknown error"
376                 default:
377                         panic(fmt.Sprintf("Unsupported CF-SSL error reason %d under category CertStoreError.", reason))
378                 }
379
380         default:
381                 panic(fmt.Sprintf("Unsupported CFSSL error type: %d.",
382                         category))
383         }
384         return &Error{ErrorCode: errorCode, Message: msg}
385 }
386
387 // Wrap returns an error that contains the given error and an error code derived from
388 // the given category, reason and the error. Currently, to avoid confusion, it is not
389 // allowed to create an error of category Success
390 func Wrap(category Category, reason Reason, err error) *Error {
391         errorCode := int(category) + int(reason)
392         if err == nil {
393                 panic("Wrap needs a supplied error to initialize.")
394         }
395
396         // do not double wrap a error
397         switch err.(type) {
398         case *Error:
399                 panic("Unable to wrap a wrapped error.")
400         }
401
402         switch category {
403         case CertificateError:
404                 // given VerifyFailed , report the status with more detailed status code
405                 // for some certificate errors we care.
406                 if reason == VerifyFailed {
407                         switch errorType := err.(type) {
408                         case x509.CertificateInvalidError:
409                                 errorCode += certificateInvalid + int(errorType.Reason)
410                         case x509.UnknownAuthorityError:
411                                 errorCode += unknownAuthority
412                         }
413                 }
414         case PrivateKeyError, IntermediatesError, RootError, PolicyError, DialError,
415                 APIClientError, CSRError, CTError, CertStoreError:
416         // no-op, just use the error
417         default:
418                 panic(fmt.Sprintf("Unsupported CFSSL error type: %d.",
419                         category))
420         }
421
422         return &Error{ErrorCode: errorCode, Message: err.Error()}
423
424 }