gitee.com/Mydawng/fabric-ca@v2.0.0-alpha.0.20201214145411-9ea68369cb61+incompatible/lib/caerrors/servererror.go (about) 1 /* 2 Copyright IBM Corp. All Rights Reserved. 3 4 SPDX-License-Identifier: Apache-2.0 5 */ 6 7 package caerrors 8 9 import ( 10 "encoding/json" 11 "fmt" 12 "net/http" 13 "reflect" 14 15 cfsslapi "github.com/cloudflare/cfssl/api" 16 "github.com/cloudflare/cfssl/log" 17 "github.com/pkg/errors" 18 ) 19 20 // Error codes 21 const ( 22 // Unknown error code 23 ErrUnknown = 0 24 // HTTP method not allowed 25 ErrMethodNotAllowed = 1 26 // No authorization header was found in request 27 ErrNoAuthHdr = 2 28 // Failed reading the HTTP request body 29 ErrReadingReqBody = 3 30 // HTTP request body was empty but should not have been 31 ErrEmptyReqBody = 4 32 // HTTP request body was of the wrong format 33 ErrBadReqBody = 5 34 // The token in the authorization header was invalid 35 ErrBadReqToken = 6 36 // The caller does not have the "hf.Revoker" attibute 37 ErrNotRevoker = 7 38 // Certificate to be revoked was not found 39 ErrRevCertNotFound = 8 40 // Certificate to be revoked is not owned by expected user 41 ErrCertWrongOwner = 9 42 // Identity of certificate to be revoked was not found 43 ErrRevokeIDNotFound = 10 44 // User info was not found for issuee of revoked certificate 45 ErrRevokeUserInfoNotFound = 11 46 // Certificate revocation failed for another reason 47 ErrRevokeFailure = 12 48 // Failed to update user info when revoking identity 49 ErrRevokeUpdateUser = 13 50 // Failed to revoke any certificates by identity 51 ErrNoCertsRevoked = 14 52 // Missing fields in the revocation request 53 ErrMissingRevokeArgs = 15 54 // Failed to get user's affiliation 55 ErrGettingAffiliation = 16 56 // Revoker's affiliation not equal to or above revokee's affiliation 57 ErrRevokerNotAffiliated = 17 58 // Failed to send an HTTP response 59 ErrSendingResponse = 18 60 // The CA (Certificate Authority) name was not found 61 ErrCANotFound = 19 62 // Authorization failure 63 ErrAuthenticationFailure = 20 64 // No username and password were in the authorization header 65 ErrNoUserPass = 21 66 // Enrollment is currently disabled for the server 67 ErrEnrollDisabled = 22 68 // Invalid user name 69 ErrInvalidUser = 23 70 // Invalid password 71 ErrInvalidPass = 24 72 // Invalid token in authorization header 73 ErrInvalidToken = 25 74 // Certificate was not issued by a trusted authority 75 ErrUntrustedCertificate = 26 76 // Certificate has expired 77 ErrCertExpired = 27 78 // Certificate has been revoked 79 ErrCertRevoked = 28 80 // Failed trying to check if certificate is revoked 81 ErrCertRevokeCheckFailure = 29 82 // Certificate was not found 83 ErrCertNotFound = 30 84 // Bad certificate signing request 85 ErrBadCSR = 31 86 // Failed to get identity's prekey 87 ErrNoPreKey = 32 88 // The caller was not authenticated 89 ErrCallerIsNotAuthenticated = 33 90 // Invalid configuration setting 91 ErrConfig = 34 92 // The caller does not have authority to generate a CRL 93 ErrNoGenCRLAuth = 35 94 // Invalid RevokedAfter value in the GenCRL request 95 ErrInvalidRevokedAfter = 36 96 // Invalid ExpiredAfter value in the GenCRL request 97 ErrInvalidExpiredAfter = 37 98 // Failed to get revoked certs from the database 99 ErrRevokedCertsFromDB = 38 100 // Failed to get CA cert 101 ErrGetCACert = 39 102 // Failed to get CA signer 103 ErrGetCASigner = 40 104 // Failed to generate CRL 105 ErrGenCRL = 41 106 // Registrar does not have the authority to register an attribute 107 ErrRegAttrAuth = 42 108 // Registrar does not own 'hf.Registrar.Attributes' 109 ErrMissingRegAttr = 43 110 // Caller does not have appropriate affiliation to perform requested action 111 ErrCallerNotAffiliated = 44 112 // Failed to verify if caller has appropriate type 113 ErrGettingType = 45 114 // CA cert does not have 'crl sign' usage 115 ErrNoCrlSignAuth = 46 116 // Incorrect level of database 117 ErrDBLevel = 47 118 // Incorrect level of configuration file 119 ErrConfigFileLevel = 48 120 // Failed to get user from database 121 ErrGettingUser = 49 122 // Error processing HTTP request 123 ErrHTTPRequest = 50 124 // Error connecting to database 125 ErrConnectingDB = 51 126 // Failed to add identity 127 ErrAddIdentity = 52 128 // Unauthorized to perform update action 129 ErrUpdateConfigAuth = 53 130 // Registrar not authorized to act on type 131 ErrRegistrarInvalidType = 54 132 // Registrar not authorized to act on affiliation 133 ErrRegistrarNotAffiliated = 55 134 // Failed to remove identity 135 ErrRemoveIdentity = 56 136 // Failed to get boolean query parameter 137 ErrGettingBoolQueryParm = 57 138 // Failed to modify identity 139 ErrModifyingIdentity = 58 140 // Caller does not have the appropriate role 141 ErrMissingRole = 59 142 // Failed to add new affiliation 143 ErrUpdateConfigAddAff = 60 144 // Failed to remove affiliation 145 ErrUpdateConfigRemoveAff = 61 146 // Error occured while removing affiliation in database 147 ErrRemoveAffDB = 62 148 // Error occured when making a Get request to database 149 ErrDBGet = 63 150 // Failed to modiy affiliation 151 ErrUpdateConfigModifyAff = 64 152 // Error occured while deleting user 153 ErrDBDeleteUser = 65 154 // Certificate that is being revoked has already been revoked 155 ErrCertAlreadyRevoked = 66 156 // Failed to get requested certificate(s) 157 ErrGettingCert = 67 158 // Error occurred parsing variable as an integer 159 ErrParsingIntEnvVar = 68 160 // CA certificate file is not found warning message 161 ErrCACertFileNotFound = 69 162 // Error occurs when invoking a request revoked enrollment ID 163 ErrRevokedID = 70 164 // Authorization failure 165 ErrAuthorizationFailure = 71 166 // Action is not allowed when using LDAP 167 ErrInvalidLDAPAction = 72 168 // Incorrect password limit reached 169 ErrPasswordAttempts = 73 170 // Registering multiple identities with same name 171 ErrDupIdentityReg = 74 172 // Error occured registering identity 173 ErrRegisteringIdentity = 75 174 // Registrat does not have authority to register identity 175 ErrRegistrarRegAuth = 76 176 // Common name does not match username during enroll 177 ErrCNInvalidEnroll = 77 178 // Invoker does not have required attribute to perform function 179 ErrInvokerMissAttr = 78 180 // Invalid boolean value for attribute 181 ErrInvalidBool = 79 182 // Input validation failed on CSR 183 ErrInputValidCSR = 80 184 // Error occurred while generating attribute extension 185 ErrAttrExt = 81 186 // Error for invalid max enrolment registeration value 187 ErrInvalidMaxEnroll = 82 188 ) 189 190 // CreateHTTPErr constructs a new HTTP error. 191 func CreateHTTPErr(scode, code int, format string, args ...interface{}) *HTTPErr { 192 msg := fmt.Sprintf(format, args...) 193 return &HTTPErr{ 194 scode: scode, 195 lcode: code, 196 lmsg: msg, 197 rcode: code, 198 rmsg: msg, 199 } 200 } 201 202 // NewHTTPErr constructs a new HTTP error wrappered with pkg/errors error. 203 func NewHTTPErr(scode, code int, format string, args ...interface{}) error { 204 return CreateHTTPErr(scode, code, format, args...) 205 } 206 207 // NewAuthenticationErr constructs an HTTP error specifically indicating an authentication failure. 208 // The local code and message is specific, but the remote code and message is generic 209 // for security reasons. 210 func NewAuthenticationErr(code int, format string, args ...interface{}) error { 211 he := CreateHTTPErr(401, code, format, args...) 212 he.Remote(ErrAuthenticationFailure, "Authentication failure") 213 return he 214 } 215 216 // NewAuthorizationErr constructs an HTTP error specifically indicating an authorization failure. 217 // The local code and message is specific, but the remote code and message is generic 218 // for security reasons. 219 func NewAuthorizationErr(code int, format string, args ...interface{}) error { 220 he := CreateHTTPErr(403, code, format, args...) 221 he.Remote(ErrAuthorizationFailure, "Authorization failure") 222 return he 223 } 224 225 // Print prints a properly formatted http error string 226 func Print(err error) string { 227 he := GetCause(err) 228 if he != nil { 229 return he.Print() 230 } 231 return err.Error() 232 } 233 234 // HTTPErr is an HTTP error. 235 // "local" refers to errors as logged in the server (local to the server). 236 // "remote" refers to errors as returned to the client (remote to the server). 237 // This allows us to log a more specific error in the server logs while 238 // returning a more generic error to the client, as is done for authorization 239 // failures. 240 type HTTPErr struct { 241 scode int // HTTP status code 242 lcode int // local error code 243 lmsg string // local error message 244 rcode int // remote error code 245 rmsg string // remote error message 246 } 247 248 // Error returns the string representation 249 func (he *HTTPErr) Error() string { 250 return he.String() 251 } 252 253 // String returns a string representation of this augmented error 254 func (he *HTTPErr) String() string { 255 return he.lmsg 256 } 257 258 // Remote sets the remote code and message to something different from that of the local code and message 259 func (he *HTTPErr) Remote(code int, format string, args ...interface{}) *HTTPErr { 260 he.rcode = code 261 he.rmsg = fmt.Sprintf(format, args...) 262 return he 263 } 264 265 type errorWriter interface { 266 http.ResponseWriter 267 } 268 269 // Write the server's HTTP error response 270 func (he *HTTPErr) writeResponse(w errorWriter) error { 271 response := cfsslapi.NewErrorResponse(he.rmsg, he.rcode) 272 jsonMessage, err := json.Marshal(response) 273 if err != nil { 274 log.Errorf("Failed to marshal error to JSON: %v", err) 275 return err 276 } 277 msg := string(jsonMessage) 278 http.Error(w, msg, he.scode) 279 return nil 280 } 281 282 // GetRemoteCode returns the remote error code 283 func (he *HTTPErr) GetRemoteCode() int { 284 return he.rcode 285 } 286 287 // GetLocalCode returns the local error code 288 func (he *HTTPErr) GetLocalCode() int { 289 return he.lcode 290 } 291 292 // GetStatusCode returns the HTTP status code 293 func (he *HTTPErr) GetStatusCode() int { 294 return he.scode 295 } 296 297 // GetRemoteMsg returns the remote error message 298 func (he *HTTPErr) GetRemoteMsg() string { 299 return he.rmsg 300 } 301 302 // GetLocalMsg returns the local error message 303 func (he *HTTPErr) GetLocalMsg() string { 304 return he.lmsg 305 } 306 307 // Print will print a properly formated error message 308 func (he *HTTPErr) Print() string { 309 if he.lcode == he.rcode && he.lmsg == he.rmsg { 310 return fmt.Sprintf("scode: %d, code: %d, msg: %s", he.scode, he.lcode, he.lmsg) 311 } 312 return fmt.Sprintf("scode: %d, local code: %d, local msg: %s, remote code: %d, remote msg: %s", 313 he.scode, he.lcode, he.lmsg, he.rcode, he.rmsg) 314 } 315 316 // ServerErr contains error message with corresponding CA error code 317 type ServerErr struct { 318 code int 319 msg string 320 } 321 322 // FatalErr is a server error that is will prevent the server/CA from continuing to operate 323 type FatalErr struct { 324 ServerErr 325 } 326 327 // NewServerError constructs a server error 328 func NewServerError(code int, format string, args ...interface{}) *ServerErr { 329 msg := fmt.Sprintf(format, args...) 330 return &ServerErr{ 331 code: code, 332 msg: msg, 333 } 334 } 335 336 // NewFatalError constructs a fatal error 337 func NewFatalError(code int, format string, args ...interface{}) *FatalErr { 338 msg := fmt.Sprintf(format, args...) 339 return &FatalErr{ 340 ServerErr{ 341 code: code, 342 msg: msg, 343 }, 344 } 345 } 346 347 func (fe *FatalErr) Error() string { 348 return fe.String() 349 } 350 351 func (fe *FatalErr) String() string { 352 return fmt.Sprintf("Code: %d - %s", fe.code, fe.msg) 353 } 354 355 // IsFatalError return true if the error is of type 'FatalErr' 356 func IsFatalError(err error) bool { 357 causeErr := errors.Cause(err) 358 typ := reflect.TypeOf(causeErr) 359 // If a pointer to a struct is passe, get the type of the dereferenced object 360 if typ.Kind() == reflect.Ptr { 361 typ = typ.Elem() 362 } 363 364 if typ == reflect.TypeOf(FatalErr{}) { 365 return true 366 } 367 return false 368 } 369 370 type causer interface { 371 Cause() error 372 } 373 374 // GetCause gets the root cause of the error 375 func GetCause(err error) *HTTPErr { 376 for err != nil { 377 switch err.(type) { 378 case *HTTPErr: 379 return err.(*HTTPErr) 380 case causer: 381 err = err.(causer).Cause() 382 default: 383 return nil 384 } 385 } 386 return nil 387 }