...
1 package x509
2
3 import (
4 "bytes"
5 "fmt"
6 "strconv"
7 "strings"
8 )
9
10
11 type Error struct {
12 ID ErrorID
13 Category ErrCategory
14 Summary string
15 Field string
16 SpecRef string
17 SpecText string
18
19 Fatal bool
20 }
21
22 func (err Error) Error() string {
23 var msg bytes.Buffer
24 if err.ID != ErrInvalidID {
25 if err.Fatal {
26 msg.WriteRune('E')
27 } else {
28 msg.WriteRune('W')
29 }
30 msg.WriteString(fmt.Sprintf("%03d: ", err.ID))
31 }
32 msg.WriteString(err.Summary)
33 return msg.String()
34 }
35
36
37 func (err Error) VerboseError() string {
38 var msg bytes.Buffer
39 msg.WriteString(err.Error())
40 if len(err.Field) > 0 || err.Category != UnknownCategory || len(err.SpecRef) > 0 || len(err.SpecText) > 0 {
41 msg.WriteString(" (")
42 needSep := false
43 if len(err.Field) > 0 {
44 msg.WriteString(err.Field)
45 needSep = true
46 }
47 if err.Category != UnknownCategory {
48 if needSep {
49 msg.WriteString(": ")
50 }
51 msg.WriteString(err.Category.String())
52 needSep = true
53 }
54 if len(err.SpecRef) > 0 {
55 if needSep {
56 msg.WriteString(": ")
57 }
58 msg.WriteString(err.SpecRef)
59 needSep = true
60 }
61 if len(err.SpecText) > 0 {
62 if needSep {
63 if len(err.SpecRef) > 0 {
64 msg.WriteString(", ")
65 } else {
66 msg.WriteString(": ")
67 }
68 }
69 msg.WriteString("'")
70 msg.WriteString(err.SpecText)
71 msg.WriteString("'")
72 }
73 msg.WriteString(")")
74 }
75
76 return msg.String()
77 }
78
79
80 type ErrCategory int
81
82
83 const (
84 UnknownCategory ErrCategory = iota
85
86 InvalidASN1Encoding
87 InvalidASN1Content
88 InvalidASN1DER
89
90 InvalidValueRange
91 InvalidASN1Type
92 UnexpectedAdditionalData
93
94 PoorlyFormedCertificate
95 MalformedCertificate
96 PoorlyFormedCRL
97 MalformedCRL
98
99 BaselineRequirementsFailure
100 EVRequirementsFailure
101
102 InsecureAlgorithm
103 UnrecognizedValue
104 )
105
106 func (category ErrCategory) String() string {
107 switch category {
108 case InvalidASN1Encoding:
109 return "Invalid ASN.1 encoding"
110 case InvalidASN1Content:
111 return "Invalid ASN.1 content"
112 case InvalidASN1DER:
113 return "Invalid ASN.1 distinguished encoding"
114 case InvalidValueRange:
115 return "Invalid value for range given in schema"
116 case InvalidASN1Type:
117 return "Invalid ASN.1 type for schema"
118 case UnexpectedAdditionalData:
119 return "Unexpected additional data present"
120 case PoorlyFormedCertificate:
121 return "Certificate does not comply with SHOULD clause in spec"
122 case MalformedCertificate:
123 return "Certificate does not comply with MUST clause in spec"
124 case PoorlyFormedCRL:
125 return "Certificate Revocation List does not comply with SHOULD clause in spec"
126 case MalformedCRL:
127 return "Certificate Revocation List does not comply with MUST clause in spec"
128 case BaselineRequirementsFailure:
129 return "Certificate does not comply with CA/BF baseline requirements"
130 case EVRequirementsFailure:
131 return "Certificate does not comply with CA/BF EV requirements"
132 case InsecureAlgorithm:
133 return "Certificate uses an insecure algorithm"
134 case UnrecognizedValue:
135 return "Certificate uses an unrecognized value"
136 default:
137 return fmt.Sprintf("Unknown (%d)", category)
138 }
139 }
140
141
142 type ErrorID int
143
144
145 type Errors struct {
146 Errs []Error
147 }
148
149
150 func (e *Errors) Error() string {
151 return e.combineErrors(Error.Error)
152 }
153
154
155 func (e *Errors) VerboseError() string {
156 return e.combineErrors(Error.VerboseError)
157 }
158
159
160 func (e *Errors) Fatal() bool {
161 return (e.FirstFatal() != nil)
162 }
163
164
165 func (e *Errors) Empty() bool {
166 if e == nil {
167 return true
168 }
169 return len(e.Errs) == 0
170 }
171
172
173
174 func (e *Errors) FirstFatal() error {
175 if e == nil {
176 return nil
177 }
178 for _, err := range e.Errs {
179 if err.Fatal {
180 return err
181 }
182 }
183 return nil
184
185 }
186
187
188 func (e *Errors) AddID(id ErrorID, args ...interface{}) {
189 e.Errs = append(e.Errs, NewError(id, args...))
190 }
191
192 func (e Errors) combineErrors(errfn func(Error) string) string {
193 if len(e.Errs) == 0 {
194 return ""
195 }
196 if len(e.Errs) == 1 {
197 return errfn((e.Errs)[0])
198 }
199 var msg bytes.Buffer
200 msg.WriteString("Errors:")
201 for _, err := range e.Errs {
202 msg.WriteString("\n ")
203 msg.WriteString(errfn(err))
204 }
205 return msg.String()
206 }
207
208
209
210 func (e Errors) Filter(filtered []ErrorID) Errors {
211 var results Errors
212 eloop:
213 for _, v := range e.Errs {
214 for _, f := range filtered {
215 if v.ID == f {
216 break eloop
217 }
218 }
219 results.Errs = append(results.Errs, v)
220 }
221 return results
222 }
223
224
225 func ErrorFilter(ignore string) []ErrorID {
226 var ids []ErrorID
227 filters := strings.Split(ignore, ",")
228 for _, f := range filters {
229 v, err := strconv.Atoi(f)
230 if err != nil {
231 continue
232 }
233 ids = append(ids, ErrorID(v))
234 }
235 return ids
236 }
237
View as plain text