github.com/hellobchain/third_party@v0.0.0-20230331131523-deb0478a2e52/cloudflare/cfssl/errors/error.go (about)

     1  package errors
     2  
     3  import (
     4  	"encoding/json"
     5  	"fmt"
     6  	"github.com/hellobchain/newcryptosm/x509"
     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  	// CTClientConstructionFailed occurs when the construction of a new
   195  	// github.com/google/certificate-transparency client fails.
   196  	CTClientConstructionFailed
   197  )
   198  
   199  // Certificate persistence related errors specified with CertStoreError
   200  const (
   201  	// InsertionFailed occurs when a SQL insert query failes to complete.
   202  	InsertionFailed = 100 * (iota + 1)
   203  	// RecordNotFound occurs when a SQL query targeting on one unique
   204  	// record failes to update the specified row in the table.
   205  	RecordNotFound
   206  )
   207  
   208  // The error interface implementation, which formats to a JSON object string.
   209  func (e *Error) Error() string {
   210  	marshaled, err := json.Marshal(e)
   211  	if err != nil {
   212  		panic(err)
   213  	}
   214  	return string(marshaled)
   215  
   216  }
   217  
   218  // New returns an error that contains  an error code and message derived from
   219  // the given category, reason. Currently, to avoid confusion, it is not
   220  // allowed to create an error of category Success
   221  func New(category Category, reason Reason) *Error {
   222  	errorCode := int(category) + int(reason)
   223  	var msg string
   224  	switch category {
   225  	case OCSPError:
   226  		switch reason {
   227  		case ReadFailed:
   228  			msg = "No certificate provided"
   229  		case IssuerMismatch:
   230  			msg = "Certificate not issued by this issuer"
   231  		case InvalidStatus:
   232  			msg = "Invalid revocation status"
   233  		}
   234  	case CertificateError:
   235  		switch reason {
   236  		case Unknown:
   237  			msg = "Unknown certificate error"
   238  		case ReadFailed:
   239  			msg = "Failed to read certificate"
   240  		case DecodeFailed:
   241  			msg = "Failed to decode certificate"
   242  		case ParseFailed:
   243  			msg = "Failed to parse certificate"
   244  		case SelfSigned:
   245  			msg = "Certificate is self signed"
   246  		case VerifyFailed:
   247  			msg = "Unable to verify certificate"
   248  		case BadRequest:
   249  			msg = "Invalid certificate request"
   250  		case MissingSerial:
   251  			msg = "Missing serial number in request"
   252  		default:
   253  			panic(fmt.Sprintf("Unsupported CFSSL error reason %d under category CertificateError.",
   254  				reason))
   255  
   256  		}
   257  	case PrivateKeyError:
   258  		switch reason {
   259  		case Unknown:
   260  			msg = "Unknown private key error"
   261  		case ReadFailed:
   262  			msg = "Failed to read private key"
   263  		case DecodeFailed:
   264  			msg = "Failed to decode private key"
   265  		case ParseFailed:
   266  			msg = "Failed to parse private key"
   267  		case Encrypted:
   268  			msg = "Private key is encrypted."
   269  		case NotRSAOrECC:
   270  			msg = "Private key algorithm is not RSA or ECC"
   271  		case KeyMismatch:
   272  			msg = "Private key does not match public key"
   273  		case GenerationFailed:
   274  			msg = "Failed to new private key"
   275  		case Unavailable:
   276  			msg = "Private key is unavailable"
   277  		default:
   278  			panic(fmt.Sprintf("Unsupported CFSSL error reason %d under category PrivateKeyError.",
   279  				reason))
   280  		}
   281  	case IntermediatesError:
   282  		switch reason {
   283  		case Unknown:
   284  			msg = "Unknown intermediate certificate error"
   285  		case ReadFailed:
   286  			msg = "Failed to read intermediate certificate"
   287  		case DecodeFailed:
   288  			msg = "Failed to decode intermediate certificate"
   289  		case ParseFailed:
   290  			msg = "Failed to parse intermediate certificate"
   291  		default:
   292  			panic(fmt.Sprintf("Unsupported CFSSL error reason %d under category IntermediatesError.",
   293  				reason))
   294  		}
   295  	case RootError:
   296  		switch reason {
   297  		case Unknown:
   298  			msg = "Unknown root certificate error"
   299  		case ReadFailed:
   300  			msg = "Failed to read root certificate"
   301  		case DecodeFailed:
   302  			msg = "Failed to decode root certificate"
   303  		case ParseFailed:
   304  			msg = "Failed to parse root certificate"
   305  		default:
   306  			panic(fmt.Sprintf("Unsupported CFSSL error reason %d under category RootError.",
   307  				reason))
   308  		}
   309  	case PolicyError:
   310  		switch reason {
   311  		case Unknown:
   312  			msg = "Unknown policy error"
   313  		case NoKeyUsages:
   314  			msg = "Invalid policy: no key usage available"
   315  		case InvalidPolicy:
   316  			msg = "Invalid or unknown policy"
   317  		case InvalidRequest:
   318  			msg = "Policy violation request"
   319  		case UnknownProfile:
   320  			msg = "Unknown policy profile"
   321  		case UnmatchedWhitelist:
   322  			msg = "Request does not match policy whitelist"
   323  		default:
   324  			panic(fmt.Sprintf("Unsupported CFSSL error reason %d under category PolicyError.",
   325  				reason))
   326  		}
   327  	case DialError:
   328  		switch reason {
   329  		case Unknown:
   330  			msg = "Failed to dial remote server"
   331  		default:
   332  			panic(fmt.Sprintf("Unsupported CFSSL error reason %d under category DialError.",
   333  				reason))
   334  		}
   335  	case APIClientError:
   336  		switch reason {
   337  		case AuthenticationFailure:
   338  			msg = "API client authentication failure"
   339  		case JSONError:
   340  			msg = "API client JSON config error"
   341  		case ClientHTTPError:
   342  			msg = "API client HTTP error"
   343  		case IOError:
   344  			msg = "API client IO error"
   345  		case ServerRequestFailed:
   346  			msg = "API client error: Server request failed"
   347  		default:
   348  			panic(fmt.Sprintf("Unsupported CFSSL error reason %d under category APIClientError.",
   349  				reason))
   350  		}
   351  	case CSRError:
   352  		switch reason {
   353  		case Unknown:
   354  			msg = "CSR parsing failed due to unknown error"
   355  		case ReadFailed:
   356  			msg = "CSR file read failed"
   357  		case ParseFailed:
   358  			msg = "CSR Parsing failed"
   359  		case DecodeFailed:
   360  			msg = "CSR Decode failed"
   361  		case BadRequest:
   362  			msg = "CSR Bad request"
   363  		default:
   364  			panic(fmt.Sprintf("Unsupported CF-SSL error reason %d under category APIClientError.", reason))
   365  		}
   366  	case CTError:
   367  		switch reason {
   368  		case Unknown:
   369  			msg = "Certificate transparency parsing failed due to unknown error"
   370  		case PrecertSubmissionFailed:
   371  			msg = "Certificate transparency precertificate submission failed"
   372  		default:
   373  			panic(fmt.Sprintf("Unsupported CF-SSL error reason %d under category CTError.", reason))
   374  		}
   375  	case CertStoreError:
   376  		switch reason {
   377  		case Unknown:
   378  			msg = "Certificate store action failed due to unknown error"
   379  		default:
   380  			panic(fmt.Sprintf("Unsupported CF-SSL error reason %d under category CertStoreError.", reason))
   381  		}
   382  
   383  	default:
   384  		panic(fmt.Sprintf("Unsupported CFSSL error type: %d.",
   385  			category))
   386  	}
   387  	return &Error{ErrorCode: errorCode, Message: msg}
   388  }
   389  
   390  // Wrap returns an error that contains the given error and an error code derived from
   391  // the given category, reason and the error. Currently, to avoid confusion, it is not
   392  // allowed to create an error of category Success
   393  func Wrap(category Category, reason Reason, err error) *Error {
   394  	errorCode := int(category) + int(reason)
   395  	if err == nil {
   396  		panic("Wrap needs a supplied error to initialize.")
   397  	}
   398  
   399  	// do not double wrap a error
   400  	switch err.(type) {
   401  	case *Error:
   402  		panic("Unable to wrap a wrapped error.")
   403  	}
   404  
   405  	switch category {
   406  	case CertificateError:
   407  		// given VerifyFailed , report the status with more detailed status code
   408  		// for some certificate errors we care.
   409  		if reason == VerifyFailed {
   410  			switch errorType := err.(type) {
   411  			case x509.CertificateInvalidError:
   412  				errorCode += certificateInvalid + int(errorType.Reason)
   413  			case x509.UnknownAuthorityError:
   414  				errorCode += unknownAuthority
   415  			}
   416  		}
   417  	case PrivateKeyError, IntermediatesError, RootError, PolicyError, DialError,
   418  		APIClientError, CSRError, CTError, CertStoreError:
   419  	// no-op, just use the error
   420  	default:
   421  		panic(fmt.Sprintf("Unsupported CFSSL error type: %d.",
   422  			category))
   423  	}
   424  
   425  	return &Error{ErrorCode: errorCode, Message: err.Error()}
   426  
   427  }