Add custom error type for crypto backend errors
Nobody has claimed this yet.
- Dominant language
- Go
- Stars
- 431
- Forks
- 44
- Avg merge
- 21h 18m
- Merged PRs (30d)
- 30
Description
I would like to start a discussion about the need for typed errors from the crypto backends.
The use case I have is detecting whether an error was triggered by OpenSSL. Currently golang-fips/openssl extracts the error string from OpenSSL and then calls errors.New() to create the error. This means that the only way to find out if error was triggered by OpenSSL is to do matching on the error strings. I find that approach error prone and not future proof.
Instead, I would find the following very handy:
Firstly, in microsoft/go, define a CryptoBackendError interface:
src/crypto/boring/boring.go:
type CryptoBackendError interface {
error
CryptoBackend() string
}
Next, in golang-fips/openssl, define a OpenSSLError type and wrap errors to it (note: this is not a complete diff):
diff -urN go1.23.8-1.orig/src/vendor/github.com/golang-fips/openssl/v2/openssl.go go1.23.8-1.cryptobackend-error/src/vendor/github.com/golang-fips/openssl/v2/openssl.go
--- go1.23.8-1.orig/src/vendor/github.com/golang-fips/openssl/v2/openssl.go 2025-04-22 09:34:23.824810048 +0300
+++ go1.23.8-1.cryptobackend-error/src/vendor/github.com/golang-fips/openssl/v2/openssl.go 2025-04-22 14:20:40.295540401 +0300
@@ -74,12 +74,21 @@
}
func errUnsupportedVersion() error {
- return errors.New("openssl: OpenSSL version: " + utoa(vMajor) + "." + utoa(vMinor) + "." + utoa(vPatch))
+ return &openSSLError{err: errors.New("openssl: OpenSSL version: " + utoa(vMajor) + "." + utoa(vMinor) + "." + utoa(vPatch))}
}
type fail string
-func (e fail) Error() string { return "openssl: " + string(e) + " failed" }
+func (e fail) Error() string { return "openssl: " + string(e) + " failed" }
+func (e fail) CryptoBackend() string { return "opensslcrypto" }
+
+type openSSLError struct {
+ err error
+}
+
+func (e openSSLError) Error() string { return e.err.Error() }
+func (e openSSLError) Unwrap() error { return e.err }
+func (e openSSLError) CryptoBackend() string { return "opensslcrypto" }
// VersionText returns the version text of the OpenSSL currently loaded.
func VersionText() string {
@@ -260,7 +269,7 @@
C.go_openssl_ERR_error_string_n(e, (*C.char)(unsafe.Pointer(&buf[0])), C.size_t(len(buf)))
b.WriteString(string(buf[:]) + "\n\t" + C.GoString(file) + ":" + strconv.Itoa(int(line)))
}
- return errors.New(b.String())
+ return &openSSLError{err: errors.New(b.String())}
}
var unknownFile = "<go code>\000"
Finally, in the application use errors.As() to check if an error is from OpenSSL:
var cryptoBackendErr boring.CryptoBackendError
if errors.As(err, &cryptoBackendErr) {
...
This is not a trivial change, as a) more work would be needed to convert all errors returned in golang-fips/openssl and 2) microsoft/go-crypto-winnative should eventually be converted, for the sake of completeness. The bright side though is, that the work could be done in multiple phases and independently for each crypto backend.
Thoughts?
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Review src/crypto/boring/boring.go and the proposed vendored golang-fips/openssl/v2/openssl.go changes first. Inventory the backend errors that would need conversion, including the eventual microsoft/go-crypto-winnative work; completion would require a consistent typed-error approach across the crypto backends.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- go
- Domain
- cryptography, security
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 25/100