microsoft / go-crypto-openssl

Go crypto backend for Linux using OpenSSL
MIT License
55 stars 14 forks source link

checkheader: check constant values #22

Closed qmuntal closed 2 years ago

qmuntal commented 2 years ago

The checkheader tool currently only checks for mismatching function definitions between our headers and OpenSSL development headers.

There is one remaining weak spot in our setup: we are using many constants defined in OpenSSL headers, i.e. EVP_CTRL_GCM_SET_TAG, and any of this constants value could be modified from one OpenSSL version to another. If the build-time and run-time OpenSSL versions do not agree on a particular constant value, then we would be using the build-time value in the runtime-environment, as constant values are burned into the binary when compiling.

Luckily this does not happen today, but I've already seen several constants (which we don't use) changing from OpenSSL 1 to OpenSSL 3, so better don't play with fire and teach checkheader to verify all constant values.

In order to do so, this PR removes all constants coming from OpenSSL headers and change them for enums defined in our headers. The checkheader tool will translate all enums whose name starts with GO_ to an _Static_assert, for example:

// #include <openssl/evp.h>
enum {
  GO_EVP_CTRL_GCM_SET_TAG = 0x11
}

// Translated to
#include <openssl/evp.h>
_Static_assert(EVP_CTRL_GCM_SET_TAG == 0x11) // Notice that the identifier no longer starts with GO_, it comes from evp.h!

Bonus feature: there is no remaining OpenSSL headers after removing all OpenSSL constants uses, so we can now build this library, to Go toolchain and any application without having to have the OpenSSL development headers installed 🎈

PD: I've also deleted the go.mod in the checkheader package. I initially added it so this tool was not imported when vendoring the module in the Go repo, but it seems that Go is smart enough to not vendor packages which are not used.