diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..805d350 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +openssl.test diff --git a/bio.go b/bio.go index 8d0da89..b8d32e0 100644 --- a/bio.go +++ b/bio.go @@ -16,52 +16,7 @@ package openssl -/* -#include -#include - -extern int cbioNew(BIO *b); -static int cbioFree(BIO *b) { - return 1; -} - -extern int writeBioWrite(BIO *b, char *buf, int size); -extern long writeBioCtrl(BIO *b, int cmd, long arg1, void *arg2); -static int writeBioPuts(BIO *b, const char *str) { - return writeBioWrite(b, (char*)str, (int)strlen(str)); -} - -extern int readBioRead(BIO *b, char *buf, int size); -extern long readBioCtrl(BIO *b, int cmd, long arg1, void *arg2); - -static BIO_METHOD writeBioMethod = { - BIO_TYPE_SOURCE_SINK, - "Go Write BIO", - (int (*)(BIO *, const char *, int))writeBioWrite, - NULL, - writeBioPuts, - NULL, - writeBioCtrl, - cbioNew, - cbioFree, - NULL}; - -static BIO_METHOD* BIO_s_writeBio() { return &writeBioMethod; } - -static BIO_METHOD readBioMethod = { - BIO_TYPE_SOURCE_SINK, - "Go Read BIO", - NULL, - readBioRead, - NULL, - NULL, - readBioCtrl, - cbioNew, - cbioFree, - NULL}; - -static BIO_METHOD* BIO_s_readBio() { return &readBioMethod; } -*/ +// #include "shim.h" import "C" import ( @@ -89,16 +44,6 @@ func nonCopyCString(data *C.char, size C.int) []byte { return nonCopyGoBytes(uintptr(unsafe.Pointer(data)), int(size)) } -//export cbioNew -func cbioNew(b *C.BIO) C.int { - b.shutdown = 1 - b.init = 1 - b.num = -1 - b.ptr = nil - b.flags = 0 - return 1 -} - var writeBioMapping = newMapping() type writeBio struct { @@ -109,21 +54,20 @@ type writeBio struct { } func loadWritePtr(b *C.BIO) *writeBio { - return (*writeBio)(writeBioMapping.Get(token(b.ptr))) + t := token(C.X_BIO_get_data(b)) + return (*writeBio)(writeBioMapping.Get(t)) } func bioClearRetryFlags(b *C.BIO) { - // from BIO_clear_retry_flags and BIO_clear_flags - b.flags &= ^(C.BIO_FLAGS_RWS | C.BIO_FLAGS_SHOULD_RETRY) + C.X_BIO_clear_flags(b, C.BIO_FLAGS_RWS|C.BIO_FLAGS_SHOULD_RETRY) } func bioSetRetryRead(b *C.BIO) { - // from BIO_set_retry_read and BIO_set_flags - b.flags |= (C.BIO_FLAGS_READ | C.BIO_FLAGS_SHOULD_RETRY) + C.X_BIO_set_flags(b, C.BIO_FLAGS_READ|C.BIO_FLAGS_SHOULD_RETRY) } -//export writeBioWrite -func writeBioWrite(b *C.BIO, data *C.char, size C.int) (rc C.int) { +//export go_write_bio_write +func go_write_bio_write(b *C.BIO, data *C.char, size C.int) (rc C.int) { defer func() { if err := recover(); err != nil { logger.Critf("openssl: writeBioWrite panic'd: %v", err) @@ -141,8 +85,8 @@ func writeBioWrite(b *C.BIO, data *C.char, size C.int) (rc C.int) { return size } -//export writeBioCtrl -func writeBioCtrl(b *C.BIO, cmd C.int, arg1 C.long, arg2 unsafe.Pointer) ( +//export go_write_bio_ctrl +func go_write_bio_ctrl(b *C.BIO, cmd C.int, arg1 C.long, arg2 unsafe.Pointer) ( rc C.long) { defer func() { if err := recover(); err != nil { @@ -197,15 +141,15 @@ func (b *writeBio) WriteTo(w io.Writer) (rv int64, err error) { func (self *writeBio) Disconnect(b *C.BIO) { if loadWritePtr(b) == self { - writeBioMapping.Del(token(b.ptr)) - b.ptr = nil + writeBioMapping.Del(token(C.X_BIO_get_data(b))) + C.X_BIO_set_data(b, nil) } } func (b *writeBio) MakeCBIO() *C.BIO { - rv := C.BIO_new(C.BIO_s_writeBio()) + rv := C.X_BIO_new_write_bio() token := writeBioMapping.Add(unsafe.Pointer(b)) - rv.ptr = unsafe.Pointer(token) + C.X_BIO_set_data(rv, unsafe.Pointer(token)) return rv } @@ -220,14 +164,14 @@ type readBio struct { } func loadReadPtr(b *C.BIO) *readBio { - return (*readBio)(readBioMapping.Get(token(b.ptr))) + return (*readBio)(readBioMapping.Get(token(C.X_BIO_get_data(b)))) } -//export readBioRead -func readBioRead(b *C.BIO, data *C.char, size C.int) (rc C.int) { +//export go_read_bio_read +func go_read_bio_read(b *C.BIO, data *C.char, size C.int) (rc C.int) { defer func() { if err := recover(); err != nil { - logger.Critf("openssl: readBioRead panic'd: %v", err) + logger.Critf("openssl: go_read_bio_read panic'd: %v", err) rc = -1 } }() @@ -256,8 +200,8 @@ func readBioRead(b *C.BIO, data *C.char, size C.int) (rc C.int) { return C.int(n) } -//export readBioCtrl -func readBioCtrl(b *C.BIO, cmd C.int, arg1 C.long, arg2 unsafe.Pointer) ( +//export go_read_bio_ctrl +func go_read_bio_ctrl(b *C.BIO, cmd C.int, arg1 C.long, arg2 unsafe.Pointer) ( rc C.long) { defer func() { @@ -316,16 +260,16 @@ func (b *readBio) ReadFromOnce(r io.Reader) (n int, err error) { } func (b *readBio) MakeCBIO() *C.BIO { - rv := C.BIO_new(C.BIO_s_readBio()) + rv := C.X_BIO_new_read_bio() token := readBioMapping.Add(unsafe.Pointer(b)) - rv.ptr = unsafe.Pointer(token) + C.X_BIO_set_data(rv, unsafe.Pointer(token)) return rv } func (self *readBio) Disconnect(b *C.BIO) { if loadReadPtr(b) == self { - readBioMapping.Del(token(b.ptr)) - b.ptr = nil + readBioMapping.Del(token(C.X_BIO_get_data(b))) + C.X_BIO_set_data(b, nil) } } @@ -343,7 +287,7 @@ func (b *anyBio) Read(buf []byte) (n int, err error) { if len(buf) == 0 { return 0, nil } - n = int(C.BIO_read((*C.BIO)(b), unsafe.Pointer(&buf[0]), C.int(len(buf)))) + n = int(C.X_BIO_read((*C.BIO)(b), unsafe.Pointer(&buf[0]), C.int(len(buf)))) if n <= 0 { return 0, io.EOF } @@ -354,7 +298,7 @@ func (b *anyBio) Write(buf []byte) (written int, err error) { if len(buf) == 0 { return 0, nil } - n := int(C.BIO_write((*C.BIO)(b), unsafe.Pointer(&buf[0]), + n := int(C.X_BIO_write((*C.BIO)(b), unsafe.Pointer(&buf[0]), C.int(len(buf)))) if n != len(buf) { return n, errors.New("BIO write failed") diff --git a/build.go b/build.go index f676b7b..94720e3 100644 --- a/build.go +++ b/build.go @@ -17,7 +17,8 @@ package openssl // #cgo pkg-config: libssl libcrypto +// #cgo linux CFLAGS: -Wno-deprecated-declarations +// #cgo darwin CFLAGS: -I/usr/local/opt/openssl@1.1/include -I/usr/local/opt/openssl/include -Wno-deprecated-declarations +// #cgo darwin LDFLAGS: -L/usr/local/opt/openssl@1.1/lib -L/usr/local/opt/openssl/lib // #cgo windows CFLAGS: -DWIN32_LEAN_AND_MEAN -// #cgo darwin CFLAGS: -Wno-deprecated-declarations -I/usr/local/opt/openssl/include -// #cgo darwin LDFLAGS: -L/usr/local/opt/openssl/lib import "C" diff --git a/cert.go b/cert.go index e84e8b7..45754ac 100644 --- a/cert.go +++ b/cert.go @@ -16,12 +16,7 @@ package openssl -// #include -// #include -// #include -// -// void OPENSSL_free_not_a_macro(void *ref) { OPENSSL_free(ref); } -// +// #include "shim.h" import "C" import ( @@ -229,7 +224,7 @@ func (c *Certificate) SetSerial(serial *big.Int) error { // SetIssueDate sets the certificate issue date relative to the current time. func (c *Certificate) SetIssueDate(when time.Duration) error { offset := C.long(when / time.Second) - result := C.X509_gmtime_adj(c.x.cert_info.validity.notBefore, offset) + result := C.X509_gmtime_adj(C.X_X509_get0_notBefore(c.x), offset) if result == nil { return errors.New("failed to set issue date") } @@ -239,7 +234,7 @@ func (c *Certificate) SetIssueDate(when time.Duration) error { // SetExpireDate sets the certificate issue date relative to the current time. func (c *Certificate) SetExpireDate(when time.Duration) error { offset := C.long(when / time.Second) - result := C.X509_gmtime_adj(c.x.cert_info.validity.notAfter, offset) + result := C.X509_gmtime_adj(C.X_X509_get0_notAfter(c.x), offset) if result == nil { return errors.New("failed to set expire date") } @@ -281,30 +276,30 @@ func getDigestFunction(digest EVP_MD) (md *C.EVP_MD) { switch digest { // please don't use these digest functions case EVP_NULL: - md = C.EVP_md_null() + md = C.X_EVP_md_null() case EVP_MD5: - md = C.EVP_md5() + md = C.X_EVP_md5() case EVP_SHA: - md = C.EVP_sha() + md = C.X_EVP_sha() case EVP_SHA1: - md = C.EVP_sha1() + md = C.X_EVP_sha1() case EVP_DSS: - md = C.EVP_dss() + md = C.X_EVP_dss() case EVP_DSS1: - md = C.EVP_dss1() + md = C.X_EVP_dss1() case EVP_RIPEMD160: - md = C.EVP_ripemd160() + md = C.X_EVP_ripemd160() case EVP_SHA224: - md = C.EVP_sha224() + md = C.X_EVP_sha224() // you actually want one of these case EVP_SHA256: - md = C.EVP_sha256() + md = C.X_EVP_sha256() case EVP_SHA384: - md = C.EVP_sha384() + md = C.X_EVP_sha384() case EVP_SHA512: - md = C.EVP_sha512() + md = C.X_EVP_sha512() } - return + return md } // Add an extension to a certificate. @@ -392,6 +387,6 @@ func (c *Certificate) GetSerialNumberHex() (serial string) { hex := C.BN_bn2hex(bignum) serial = C.GoString(hex) C.BN_free(bignum) - C.OPENSSL_free_not_a_macro(unsafe.Pointer(hex)) + C.X_OPENSSL_free(unsafe.Pointer(hex)) return } diff --git a/ciphers.go b/ciphers.go index 1266270..f916b4c 100644 --- a/ciphers.go +++ b/ciphers.go @@ -16,39 +16,7 @@ package openssl -// #include -// -// int EVP_CIPHER_block_size_not_a_macro(EVP_CIPHER *c) { -// return EVP_CIPHER_block_size(c); -// } -// -// int EVP_CIPHER_key_length_not_a_macro(EVP_CIPHER *c) { -// return EVP_CIPHER_key_length(c); -// } -// -// int EVP_CIPHER_iv_length_not_a_macro(EVP_CIPHER *c) { -// return EVP_CIPHER_iv_length(c); -// } -// -// int EVP_CIPHER_nid_not_a_macro(EVP_CIPHER *c) { -// return EVP_CIPHER_nid(c); -// } -// -// int EVP_CIPHER_CTX_block_size_not_a_macro(EVP_CIPHER_CTX *ctx) { -// return EVP_CIPHER_CTX_block_size(ctx); -// } -// -// int EVP_CIPHER_CTX_key_length_not_a_macro(EVP_CIPHER_CTX *ctx) { -// return EVP_CIPHER_CTX_key_length(ctx); -// } -// -// int EVP_CIPHER_CTX_iv_length_not_a_macro(EVP_CIPHER_CTX *ctx) { -// return EVP_CIPHER_CTX_iv_length(ctx); -// } -// -// const EVP_CIPHER *EVP_CIPHER_CTX_cipher_not_a_macro(EVP_CIPHER_CTX *ctx) { -// return EVP_CIPHER_CTX_cipher(ctx); -// } +// #include "shim.h" import "C" import ( @@ -74,7 +42,7 @@ type Cipher struct { } func (c *Cipher) Nid() NID { - return NID(C.EVP_CIPHER_nid_not_a_macro(c.ptr)) + return NID(C.X_EVP_CIPHER_nid(c.ptr)) } func (c *Cipher) ShortName() (string, error) { @@ -82,15 +50,15 @@ func (c *Cipher) ShortName() (string, error) { } func (c *Cipher) BlockSize() int { - return int(C.EVP_CIPHER_block_size_not_a_macro(c.ptr)) + return int(C.X_EVP_CIPHER_block_size(c.ptr)) } func (c *Cipher) KeySize() int { - return int(C.EVP_CIPHER_key_length_not_a_macro(c.ptr)) + return int(C.X_EVP_CIPHER_key_length(c.ptr)) } func (c *Cipher) IVSize() int { - return int(C.EVP_CIPHER_iv_length_not_a_macro(c.ptr)) + return int(C.X_EVP_CIPHER_iv_length(c.ptr)) } func Nid2ShortName(nid NID) (string, error) { @@ -154,7 +122,7 @@ func (ctx *cipherCtx) applyKeyAndIV(key, iv []byte) error { } if kptr != nil || iptr != nil { var res C.int - if ctx.ctx.encrypt != 0 { + if C.X_EVP_CIPHER_CTX_encrypting(ctx.ctx) != 0 { res = C.EVP_EncryptInit_ex(ctx.ctx, nil, nil, kptr, iptr) } else { res = C.EVP_DecryptInit_ex(ctx.ctx, nil, nil, kptr, iptr) @@ -167,19 +135,19 @@ func (ctx *cipherCtx) applyKeyAndIV(key, iv []byte) error { } func (ctx *cipherCtx) Cipher() *Cipher { - return &Cipher{ptr: C.EVP_CIPHER_CTX_cipher_not_a_macro(ctx.ctx)} + return &Cipher{ptr: C.X_EVP_CIPHER_CTX_cipher(ctx.ctx)} } func (ctx *cipherCtx) BlockSize() int { - return int(C.EVP_CIPHER_CTX_block_size_not_a_macro(ctx.ctx)) + return int(C.X_EVP_CIPHER_CTX_block_size(ctx.ctx)) } func (ctx *cipherCtx) KeySize() int { - return int(C.EVP_CIPHER_CTX_key_length_not_a_macro(ctx.ctx)) + return int(C.X_EVP_CIPHER_CTX_key_length(ctx.ctx)) } func (ctx *cipherCtx) IVSize() int { - return int(C.EVP_CIPHER_CTX_iv_length_not_a_macro(ctx.ctx)) + return int(C.X_EVP_CIPHER_CTX_iv_length(ctx.ctx)) } func (ctx *cipherCtx) setCtrl(code, arg int) error { diff --git a/conn.go b/conn.go index ff0bb17..3022829 100644 --- a/conn.go +++ b/conn.go @@ -16,26 +16,7 @@ package openssl -/* -#include -#include -#include -#include - -int sk_X509_num_not_a_macro(STACK_OF(X509) *sk) { return sk_X509_num(sk); } -X509 *sk_X509_value_not_a_macro(STACK_OF(X509)* sk, int i) { - return sk_X509_value(sk, i); -} -long SSL_set_tlsext_host_name_not_a_macro(SSL *ssl, const char *name) { - return SSL_set_tlsext_host_name(ssl, name); -} -const char * SSL_get_cipher_name_not_a_macro(const SSL *ssl) { - return SSL_get_cipher_name(ssl); -} -static int SSL_session_reused_not_a_macro(SSL *ssl) { - return SSL_session_reused(ssl); -} -*/ +// #include "shim.h" import "C" import ( @@ -211,7 +192,7 @@ func Server(conn net.Conn, ctx *Ctx) (*Conn, error) { func (c *Conn) GetCtx() *Ctx { return c.ctx } func (c *Conn) CurrentCipher() (string, error) { - p := C.SSL_get_cipher_name_not_a_macro(c.ssl) + p := C.X_SSL_get_cipher_name(c.ssl) if p == nil { return "", errors.New("Session not established") } @@ -356,10 +337,10 @@ func (c *Conn) PeerCertificate() (*Certificate, error) { func (c *Conn) loadCertificateStack(sk *C.struct_stack_st_X509) ( rv []*Certificate) { - sk_num := int(C.sk_X509_num_not_a_macro(sk)) + sk_num := int(C.X_sk_X509_num(sk)) rv = make([]*Certificate, 0, sk_num) for i := 0; i < sk_num; i++ { - x := C.sk_X509_value_not_a_macro(sk, C.int(i)) + x := C.X_sk_X509_value(sk, C.int(i)) // ref holds on to the underlying connection memory so we don't need to // worry about incrementing refcounts manually or freeing the X509 rv = append(rv, &Certificate{x: x, ref: c}) @@ -580,7 +561,7 @@ func (c *Conn) SetTlsExtHostName(name string) error { defer C.free(unsafe.Pointer(cname)) runtime.LockOSThread() defer runtime.UnlockOSThread() - if C.SSL_set_tlsext_host_name_not_a_macro(c.ssl, cname) == 0 { + if C.X_SSL_set_tlsext_host_name(c.ssl, cname) == 0 { return errorFromErrorQueue() } return nil @@ -591,7 +572,7 @@ func (c *Conn) VerifyResult() VerifyResult { } func (c *Conn) SessionReused() bool { - return C.SSL_session_reused_not_a_macro(c.ssl) == 1 + return C.X_SSL_session_reused(c.ssl) == 1 } func (c *Conn) GetSession() ([]byte, error) { diff --git a/ctx.go b/ctx.go index 2c9efc4..ee6a3f8 100644 --- a/ctx.go +++ b/ctx.go @@ -16,99 +16,7 @@ package openssl -/* -#include -#include -#include -#include - -static long SSL_CTX_set_options_not_a_macro(SSL_CTX* ctx, long options) { - return SSL_CTX_set_options(ctx, options); -} - -static long SSL_CTX_clear_options_not_a_macro(SSL_CTX* ctx, long options) { - return SSL_CTX_clear_options(ctx, options); -} - -static long SSL_CTX_get_options_not_a_macro(SSL_CTX* ctx) { - return SSL_CTX_get_options(ctx); -} - -static long SSL_CTX_set_mode_not_a_macro(SSL_CTX* ctx, long modes) { - return SSL_CTX_set_mode(ctx, modes); -} - -static long SSL_CTX_get_mode_not_a_macro(SSL_CTX* ctx) { - return SSL_CTX_get_mode(ctx); -} - -static long SSL_CTX_set_session_cache_mode_not_a_macro(SSL_CTX* ctx, long modes) { - return SSL_CTX_set_session_cache_mode(ctx, modes); -} - -static long SSL_CTX_sess_set_cache_size_not_a_macro(SSL_CTX* ctx, long t) { - return SSL_CTX_sess_set_cache_size(ctx, t); -} - -static long SSL_CTX_sess_get_cache_size_not_a_macro(SSL_CTX* ctx) { - return SSL_CTX_sess_get_cache_size(ctx); -} - -static long SSL_CTX_set_timeout_not_a_macro(SSL_CTX* ctx, long t) { - return SSL_CTX_set_timeout(ctx, t); -} - -static long SSL_CTX_get_timeout_not_a_macro(SSL_CTX* ctx) { - return SSL_CTX_get_timeout(ctx); -} - -static int CRYPTO_add_not_a_macro(int *pointer,int amount,int type) { - return CRYPTO_add(pointer, amount, type); -} - -static long SSL_CTX_add_extra_chain_cert_not_a_macro(SSL_CTX* ctx, X509 *cert) { - return SSL_CTX_add_extra_chain_cert(ctx, cert); -} - -static long SSL_CTX_set_tmp_ecdh_not_a_macro(SSL_CTX* ctx, EC_KEY *key) { - return SSL_CTX_set_tmp_ecdh(ctx, key); -} - -static long SSL_CTX_set_tlsext_servername_callback_not_a_macro( - SSL_CTX* ctx, int (*cb)(SSL *con, int *ad, void *args)) { - return SSL_CTX_set_tlsext_servername_callback(ctx, cb); -} - -#ifndef SSL_MODE_RELEASE_BUFFERS -#define SSL_MODE_RELEASE_BUFFERS 0 -#endif - -#ifndef SSL_OP_NO_COMPRESSION -#define SSL_OP_NO_COMPRESSION 0 -#endif - -static const SSL_METHOD *OUR_TLSv1_1_method() { -#if defined(TLS1_1_VERSION) && !defined(OPENSSL_SYSNAME_MACOSX) - return TLSv1_1_method(); -#else - return NULL; -#endif -} - -static const SSL_METHOD *OUR_TLSv1_2_method() { -#if defined(TLS1_2_VERSION) && !defined(OPENSSL_SYSNAME_MACOSX) - return TLSv1_2_method(); -#else - return NULL; -#endif -} - -#if defined SSL_CTRL_SET_TLSEXT_HOSTNAME - extern int sni_cb(SSL *ssl_conn, int *ad, void *arg); -#endif - -extern int verify_cb(int ok, X509_STORE_CTX* store); -*/ +// #include "shim.h" import "C" import ( @@ -125,7 +33,7 @@ import ( ) var ( - ssl_ctx_idx = C.SSL_CTX_get_ex_new_index(0, nil, nil, nil, nil) + ssl_ctx_idx = C.X_SSL_CTX_new_index() logger = spacelog.GetLogger() ) @@ -181,15 +89,15 @@ func NewCtxWithVersion(version SSLVersion) (*Ctx, error) { var method *C.SSL_METHOD switch version { case SSLv3: - method = C.SSLv3_method() + method = C.X_SSLv3_method() case TLSv1: - method = C.TLSv1_method() + method = C.X_TLSv1_method() case TLSv1_1: - method = C.OUR_TLSv1_1_method() + method = C.X_TLSv1_1_method() case TLSv1_2: - method = C.OUR_TLSv1_2_method() + method = C.X_TLSv1_2_method() case AnyVersion: - method = C.SSLv23_method() + method = C.X_SSLv23_method() } if method == nil { return nil, errors.New("unknown ssl/tls version") @@ -286,7 +194,7 @@ func (c *Ctx) SetEllipticCurve(curve EllipticCurve) error { } defer C.EC_KEY_free(k) - if int(C.SSL_CTX_set_tmp_ecdh_not_a_macro(c.ctx, k)) != 1 { + if int(C.X_SSL_CTX_set_tmp_ecdh(c.ctx, k)) != 1 { return errorFromErrorQueue() } @@ -311,7 +219,7 @@ func (c *Ctx) AddChainCertificate(cert *Certificate) error { runtime.LockOSThread() defer runtime.UnlockOSThread() c.chain = append(c.chain, cert) - if int(C.SSL_CTX_add_extra_chain_cert_not_a_macro(c.ctx, cert.x)) != 1 { + if int(C.X_SSL_CTX_add_extra_chain_cert(c.ctx, cert.x)) != 1 { return errorFromErrorQueue() } // OpenSSL takes ownership via SSL_CTX_add_extra_chain_cert @@ -419,7 +327,9 @@ func (self *CertificateStoreCtx) GetCurrentCert() *Certificate { return nil } // add a ref - C.CRYPTO_add_not_a_macro(&x509.references, 1, C.CRYPTO_LOCK_X509) + if 1 != C.X_X509_add_ref(x509) { + return nil + } cert := &Certificate{ x: x509, } @@ -467,19 +377,19 @@ const ( // SetOptions sets context options. See // http://www.openssl.org/docs/ssl/SSL_CTX_set_options.html func (c *Ctx) SetOptions(options Options) Options { - return Options(C.SSL_CTX_set_options_not_a_macro( + return Options(C.X_SSL_CTX_set_options( c.ctx, C.long(options))) } func (c *Ctx) ClearOptions(options Options) Options { - return Options(C.SSL_CTX_clear_options_not_a_macro( + return Options(C.X_SSL_CTX_clear_options( c.ctx, C.long(options))) } // GetOptions returns context options. See // https://www.openssl.org/docs/ssl/SSL_CTX_set_options.html func (c *Ctx) GetOptions() Options { - return Options(C.SSL_CTX_get_options_not_a_macro(c.ctx)) + return Options(C.X_SSL_CTX_get_options(c.ctx)) } type Modes int @@ -492,13 +402,13 @@ const ( // SetMode sets context modes. See // http://www.openssl.org/docs/ssl/SSL_CTX_set_mode.html func (c *Ctx) SetMode(modes Modes) Modes { - return Modes(C.SSL_CTX_set_mode_not_a_macro(c.ctx, C.long(modes))) + return Modes(C.X_SSL_CTX_set_mode(c.ctx, C.long(modes))) } // GetMode returns context modes. See // http://www.openssl.org/docs/ssl/SSL_CTX_set_mode.html func (c *Ctx) GetMode() Modes { - return Modes(C.SSL_CTX_get_mode_not_a_macro(c.ctx)) + return Modes(C.X_SSL_CTX_get_mode(c.ctx)) } type VerifyOptions int @@ -512,8 +422,8 @@ const ( type VerifyCallback func(ok bool, store *CertificateStoreCtx) bool -//export verify_cb_thunk -func verify_cb_thunk(p unsafe.Pointer, ok C.int, ctx *C.X509_STORE_CTX) C.int { +//export go_ssl_ctx_verify_cb_thunk +func go_ssl_ctx_verify_cb_thunk(p unsafe.Pointer, ok C.int, ctx *C.X509_STORE_CTX) C.int { defer func() { if err := recover(); err != nil { logger.Critf("openssl: verify callback panic'd: %v", err) @@ -538,7 +448,7 @@ func verify_cb_thunk(p unsafe.Pointer, ok C.int, ctx *C.X509_STORE_CTX) C.int { func (c *Ctx) SetVerify(options VerifyOptions, verify_cb VerifyCallback) { c.verify_cb = verify_cb if verify_cb != nil { - C.SSL_CTX_set_verify(c.ctx, C.int(options), (*[0]byte)(C.verify_cb)) + C.SSL_CTX_set_verify(c.ctx, C.int(options), (*[0]byte)(C.X_SSL_CTX_verify_cb)) } else { C.SSL_CTX_set_verify(c.ctx, C.int(options), nil) } @@ -581,7 +491,7 @@ type TLSExtServernameCallback func(ssl *SSL) SSLTLSExtErr // http://stackoverflow.com/questions/22373332/serving-multiple-domains-in-one-box-with-sni func (c *Ctx) SetTLSExtServernameCallback(sni_cb TLSExtServernameCallback) { c.sni_cb = sni_cb - C.SSL_CTX_set_tlsext_servername_callback_not_a_macro(c.ctx, (*[0]byte)(C.sni_cb)) + C.X_SSL_CTX_set_tlsext_servername_callback(c.ctx, (*[0]byte)(C.sni_cb)) } func (c *Ctx) SetSessionId(session_id []byte) error { @@ -629,30 +539,30 @@ const ( // http://www.openssl.org/docs/ssl/SSL_CTX_set_session_cache_mode.html func (c *Ctx) SetSessionCacheMode(modes SessionCacheModes) SessionCacheModes { return SessionCacheModes( - C.SSL_CTX_set_session_cache_mode_not_a_macro(c.ctx, C.long(modes))) + C.X_SSL_CTX_set_session_cache_mode(c.ctx, C.long(modes))) } // Set session cache timeout. Returns previously set value. // See https://www.openssl.org/docs/ssl/SSL_CTX_set_timeout.html func (c *Ctx) SetTimeout(t time.Duration) time.Duration { - prev := C.SSL_CTX_set_timeout_not_a_macro(c.ctx, C.long(t/time.Second)) + prev := C.X_SSL_CTX_set_timeout(c.ctx, C.long(t/time.Second)) return time.Duration(prev) * time.Second } // Get session cache timeout. // See https://www.openssl.org/docs/ssl/SSL_CTX_set_timeout.html func (c *Ctx) GetTimeout() time.Duration { - return time.Duration(C.SSL_CTX_get_timeout_not_a_macro(c.ctx)) * time.Second + return time.Duration(C.X_SSL_CTX_get_timeout(c.ctx)) * time.Second } // Set session cache size. Returns previously set value. // https://www.openssl.org/docs/ssl/SSL_CTX_sess_set_cache_size.html func (c *Ctx) SessSetCacheSize(t int) int { - return int(C.SSL_CTX_sess_set_cache_size_not_a_macro(c.ctx, C.long(t))) + return int(C.X_SSL_CTX_sess_set_cache_size(c.ctx, C.long(t))) } // Get session cache size. // https://www.openssl.org/docs/ssl/SSL_CTX_sess_set_cache_size.html func (c *Ctx) SessGetCacheSize() int { - return int(C.SSL_CTX_sess_get_cache_size_not_a_macro(c.ctx)) + return int(C.X_SSL_CTX_sess_get_cache_size(c.ctx)) } diff --git a/dhparam.go b/dhparam.go index a698645..23b939f 100644 --- a/dhparam.go +++ b/dhparam.go @@ -2,20 +2,7 @@ package openssl -/* -#include -#include -#include -#include -#include - -static long SSL_CTX_set_tmp_dh_not_a_macro(SSL_CTX* ctx, DH *dh) { - return SSL_CTX_set_tmp_dh(ctx, dh); -} -static long PEM_read_DHparams_not_a_macro(SSL_CTX* ctx, DH *dh) { - return SSL_CTX_set_tmp_dh(ctx, dh); -} -*/ +// #include "shim.h" import "C" import ( @@ -58,7 +45,7 @@ func (c *Ctx) SetDHParameters(dh *DH) error { runtime.LockOSThread() defer runtime.UnlockOSThread() - if int(C.SSL_CTX_set_tmp_dh_not_a_macro(c.ctx, dh.dh)) != 1 { + if int(C.X_SSL_CTX_set_tmp_dh(c.ctx, dh.dh)) != 1 { return errorFromErrorQueue() } return nil diff --git a/digest.go b/digest.go index 44d4d00..77f159c 100644 --- a/digest.go +++ b/digest.go @@ -16,7 +16,7 @@ package openssl -// #include +// #include "shim.h" import "C" import ( @@ -34,7 +34,7 @@ type Digest struct { func GetDigestByName(name string) (*Digest, error) { cname := C.CString(name) defer C.free(unsafe.Pointer(cname)) - p := C.EVP_get_digestbyname(cname) + p := C.X_EVP_get_digestbyname(cname) if p == nil { return nil, fmt.Errorf("Digest %v not found", name) } diff --git a/hmac.go b/hmac.go index e47f2e6..e12d5d9 100644 --- a/hmac.go +++ b/hmac.go @@ -16,24 +16,17 @@ package openssl -/* -#include -#include -#include -#include - -#include "openssl/evp.h" -#include "openssl/hmac.h" -*/ +// #include "shim.h" import "C" import ( + "errors" "runtime" "unsafe" ) type HMAC struct { - ctx C.HMAC_CTX + ctx *C.HMAC_CTX engine *Engine md *C.EVP_MD } @@ -44,38 +37,57 @@ func NewHMAC(key []byte, digestAlgorithm EVP_MD) (*HMAC, error) { func NewHMACWithEngine(key []byte, digestAlgorithm EVP_MD, e *Engine) (*HMAC, error) { var md *C.EVP_MD = getDigestFunction(digestAlgorithm) - hmac := &HMAC{engine: e, md: md} - C.HMAC_CTX_init(&hmac.ctx) - C.HMAC_Init_ex(&hmac.ctx, + h := &HMAC{engine: e, md: md} + h.ctx = C.X_HMAC_CTX_new() + if h.ctx == nil { + return nil, errors.New("unable to allocate HMAC_CTX") + } + + var c_e *C.ENGINE + if e != nil { + c_e = e.e + } + if rc := C.X_HMAC_Init_ex(h.ctx, unsafe.Pointer(&key[0]), C.int(len(key)), md, - nil) + c_e); rc != 1 { + C.X_HMAC_CTX_free(h.ctx) + return nil, errors.New("failed to initialize HMAC_CTX") + } - runtime.SetFinalizer(hmac, func(hmac *HMAC) { hmac.Close() }) - return hmac, nil + runtime.SetFinalizer(h, func(h *HMAC) { h.Close() }) + return h, nil } func (h *HMAC) Close() { - C.HMAC_CTX_cleanup(&h.ctx) + C.X_HMAC_CTX_free(h.ctx) } -func (s *HMAC) Write(data []byte) (n int, err error) { +func (h *HMAC) Write(data []byte) (n int, err error) { if len(data) == 0 { return 0, nil } - C.HMAC_Update(&s.ctx, (*C.uchar)(unsafe.Pointer(&data[0])), C.size_t(len(data))) + if rc := C.X_HMAC_Update(h.ctx, (*C.uchar)(unsafe.Pointer(&data[0])), + C.size_t(len(data))); rc != 1 { + return 0, errors.New("failed to update HMAC") + } return len(data), nil } func (h *HMAC) Reset() error { - C.HMAC_Init_ex(&h.ctx, nil, 0, nil, nil) + if 1 != C.X_HMAC_Init_ex(h.ctx, nil, 0, nil, nil) { + return errors.New("failed to reset HMAC_CTX") + } return nil } func (h *HMAC) Final() (result []byte, err error) { - mdLength := C.EVP_MD_size(h.md) + mdLength := C.X_EVP_MD_size(h.md) result = make([]byte, mdLength) - C.HMAC_Final(&h.ctx, (*C.uchar)(unsafe.Pointer(&result[0])), (*C.uint)(unsafe.Pointer(&mdLength))) + if rc := C.X_HMAC_Final(h.ctx, (*C.uchar)(unsafe.Pointer(&result[0])), + (*C.uint)(unsafe.Pointer(&mdLength))); rc != 1 { + return nil, errors.New("failed to finalized HMAC") + } return result, h.Reset() } diff --git a/hmac_test.go b/hmac_test.go index 3caa276..03b5d46 100644 --- a/hmac_test.go +++ b/hmac_test.go @@ -26,10 +26,15 @@ import ( func TestSHA256HMAC(t *testing.T) { key := []byte("d741787cc61851af045ccd37") data := []byte("5912EEFD-59EC-43E3-ADB8-D5325AEC3271") - h, _ := NewHMAC(key, EVP_SHA256) - h.Write(data) - var err error + h, err := NewHMAC(key, EVP_SHA256) + if err != nil { + t.Fatalf("Unable to create new HMAC: %s", err) + } + if _, err := h.Write(data); err != nil { + t.Fatalf("Unable to write data into HMAC: %s", err) + } + var actualHMACBytes []byte if actualHMACBytes, err = h.Final(); err != nil { t.Fatalf("Error while finalizing HMAC: %s", err) @@ -47,10 +52,19 @@ func TestSHA256HMAC(t *testing.T) { } func BenchmarkSHA256HMAC(b *testing.B) { - h, _ := NewHMAC([]byte("d741787cc61851af045ccd37"), EVP_SHA256) + key := []byte("d741787cc61851af045ccd37") + data := []byte("5912EEFD-59EC-43E3-ADB8-D5325AEC3271") + + h, err := NewHMAC(key, EVP_SHA256) + if err != nil { + b.Fatalf("Unable to create new HMAC: %s", err) + } + b.ResetTimer() for i := 0; i < b.N; i++ { - h.Write([]byte("5912EEFD-59EC-43E3-ADB8-D5325AEC3271")) + if _, err := h.Write(data); err != nil { + b.Fatalf("Unable to write data into HMAC: %s", err) + } var err error if _, err = h.Final(); err != nil { diff --git a/hostname.c b/hostname.c index 15670c4..262cb5f 100644 --- a/hostname.c +++ b/hostname.c @@ -67,6 +67,7 @@ */ /* X509 v3 extension utilities */ +#include #include #include #include diff --git a/init.go b/init.go index 9cd810a..48c71f2 100644 --- a/init.go +++ b/init.go @@ -86,32 +86,7 @@ supported the generality needed to use OpenSSL instead of crypto/tls. */ package openssl -/* -#include -#include -#include -#include -#include - -extern int Goopenssl_init_locks(); -extern void Goopenssl_thread_locking_callback(int, int, const char*, int); - -static int Goopenssl_init_threadsafety() { - // Set up OPENSSL thread safety callbacks. We only set the locking - // callback because the default id callback implementation is good - // enough for us. - int rc = Goopenssl_init_locks(); - if (rc == 0) { - CRYPTO_set_locking_callback(Goopenssl_thread_locking_callback); - } - return rc; -} - -static void OpenSSL_add_all_algorithms_not_a_macro() { - OpenSSL_add_all_algorithms(); -} - -*/ +// #include "shim.h" import "C" import ( @@ -121,14 +96,8 @@ import ( ) func init() { - C.OPENSSL_config(nil) - C.ENGINE_load_builtin_engines() - C.SSL_load_error_strings() - C.SSL_library_init() - C.OpenSSL_add_all_algorithms_not_a_macro() - rc := C.Goopenssl_init_threadsafety() - if rc != 0 { - panic(fmt.Errorf("Goopenssl_init_locks failed with %d", rc)) + if rc := C.X_shim_init(); rc != 0 { + panic(fmt.Errorf("X_shim_init failed with %d", rc)) } } diff --git a/init_posix.go b/init_posix.go index 03ed0f0..559ac1e 100644 --- a/init_posix.go +++ b/init_posix.go @@ -24,7 +24,7 @@ package openssl pthread_mutex_t* goopenssl_locks; -int Goopenssl_init_locks() { +int go_init_locks() { int rc = 0; int nlock; int i; @@ -52,7 +52,7 @@ int Goopenssl_init_locks() { return rc; } -void Goopenssl_thread_locking_callback(int mode, int n, const char *file, +void go_thread_locking_callback(int mode, int n, const char *file, int line) { if (mode & CRYPTO_LOCK) { pthread_mutex_lock(&goopenssl_locks[n]); diff --git a/init_windows.go b/init_windows.go index dc5b3b6..6006996 100644 --- a/init_windows.go +++ b/init_windows.go @@ -29,7 +29,7 @@ package openssl CRITICAL_SECTION* goopenssl_locks; -int Goopenssl_init_locks() { +int go_init_locks() { int rc = 0; int nlock; int i; @@ -47,7 +47,7 @@ int Goopenssl_init_locks() { return 0; } -void Goopenssl_thread_locking_callback(int mode, int n, const char *file, +void go_thread_locking_callback(int mode, int n, const char *file, int line) { if (mode & CRYPTO_LOCK) { EnterCriticalSection(&goopenssl_locks[n]); diff --git a/key.go b/key.go index 58fb120..e6f08c6 100644 --- a/key.go +++ b/key.go @@ -16,31 +16,7 @@ package openssl -// #include -// #include -// #include -// -// int EVP_SignInit_not_a_macro(EVP_MD_CTX *ctx, const EVP_MD *type) { -// return EVP_SignInit(ctx, type); -// } -// -// int EVP_SignUpdate_not_a_macro(EVP_MD_CTX *ctx, const void *d, -// unsigned int cnt) { -// return EVP_SignUpdate(ctx, d, cnt); -// } -// -// int EVP_VerifyInit_not_a_macro(EVP_MD_CTX *ctx, const EVP_MD *type) { -// return EVP_VerifyInit(ctx, type); -// } -// -// int EVP_VerifyUpdate_not_a_macro(EVP_MD_CTX *ctx, const void *d, -// unsigned int cnt) { -// return EVP_VerifyUpdate(ctx, d, cnt); -// } -// -// int EVP_PKEY_assign_charp(EVP_PKEY *pkey, int type, char *key) { -// return EVP_PKEY_assign(pkey, type, key); -// } +// #include "shim.h" import "C" import ( @@ -53,9 +29,9 @@ import ( type Method *C.EVP_MD var ( - SHA1_Method Method = C.EVP_sha1() - SHA256_Method Method = C.EVP_sha256() - SHA512_Method Method = C.EVP_sha512() + SHA1_Method Method = C.X_EVP_sha1() + SHA256_Method Method = C.X_EVP_sha256() + SHA512_Method Method = C.X_EVP_sha512() ) type PublicKey interface { @@ -95,22 +71,21 @@ type pKey struct { func (key *pKey) evpPKey() *C.EVP_PKEY { return key.key } func (key *pKey) SignPKCS1v15(method Method, data []byte) ([]byte, error) { - var ctx C.EVP_MD_CTX - C.EVP_MD_CTX_init(&ctx) - defer C.EVP_MD_CTX_cleanup(&ctx) + ctx := C.X_EVP_MD_CTX_new() + defer C.X_EVP_MD_CTX_free(ctx) - if 1 != C.EVP_SignInit_not_a_macro(&ctx, method) { + if 1 != C.X_EVP_SignInit(ctx, method) { return nil, errors.New("signpkcs1v15: failed to init signature") } if len(data) > 0 { - if 1 != C.EVP_SignUpdate_not_a_macro( - &ctx, unsafe.Pointer(&data[0]), C.uint(len(data))) { + if 1 != C.X_EVP_SignUpdate( + ctx, unsafe.Pointer(&data[0]), C.uint(len(data))) { return nil, errors.New("signpkcs1v15: failed to update signature") } } - sig := make([]byte, C.EVP_PKEY_size(key.key)) + sig := make([]byte, C.X_EVP_PKEY_size(key.key)) var sigblen C.uint - if 1 != C.EVP_SignFinal(&ctx, + if 1 != C.X_EVP_SignFinal(ctx, ((*C.uchar)(unsafe.Pointer(&sig[0]))), &sigblen, key.key) { return nil, errors.New("signpkcs1v15: failed to finalize signature") } @@ -118,20 +93,19 @@ func (key *pKey) SignPKCS1v15(method Method, data []byte) ([]byte, error) { } func (key *pKey) VerifyPKCS1v15(method Method, data, sig []byte) error { - var ctx C.EVP_MD_CTX - C.EVP_MD_CTX_init(&ctx) - defer C.EVP_MD_CTX_cleanup(&ctx) + ctx := C.X_EVP_MD_CTX_new() + defer C.X_EVP_MD_CTX_free(ctx) - if 1 != C.EVP_VerifyInit_not_a_macro(&ctx, method) { + if 1 != C.X_EVP_VerifyInit(ctx, method) { return errors.New("verifypkcs1v15: failed to init verify") } if len(data) > 0 { - if 1 != C.EVP_VerifyUpdate_not_a_macro( - &ctx, unsafe.Pointer(&data[0]), C.uint(len(data))) { + if 1 != C.X_EVP_VerifyUpdate( + ctx, unsafe.Pointer(&data[0]), C.uint(len(data))) { return errors.New("verifypkcs1v15: failed to update verify") } } - if 1 != C.EVP_VerifyFinal(&ctx, + if 1 != C.X_EVP_VerifyFinal(ctx, ((*C.uchar)(unsafe.Pointer(&sig[0]))), C.uint(len(sig)), key.key) { return errors.New("verifypkcs1v15: failed to finalize verify") } @@ -145,7 +119,7 @@ func (key *pKey) MarshalPKCS1PrivateKeyPEM() (pem_block []byte, return nil, errors.New("failed to allocate memory BIO") } defer C.BIO_free(bio) - rsa := (*C.RSA)(C.EVP_PKEY_get1_RSA(key.key)) + rsa := (*C.RSA)(C.X_EVP_PKEY_get1_RSA(key.key)) if rsa == nil { return nil, errors.New("failed getting rsa key") } @@ -164,7 +138,7 @@ func (key *pKey) MarshalPKCS1PrivateKeyDER() (der_block []byte, return nil, errors.New("failed to allocate memory BIO") } defer C.BIO_free(bio) - rsa := (*C.RSA)(C.EVP_PKEY_get1_RSA(key.key)) + rsa := (*C.RSA)(C.X_EVP_PKEY_get1_RSA(key.key)) if rsa == nil { return nil, errors.New("failed getting rsa key") } @@ -182,7 +156,7 @@ func (key *pKey) MarshalPKIXPublicKeyPEM() (pem_block []byte, return nil, errors.New("failed to allocate memory BIO") } defer C.BIO_free(bio) - rsa := (*C.RSA)(C.EVP_PKEY_get1_RSA(key.key)) + rsa := (*C.RSA)(C.X_EVP_PKEY_get1_RSA(key.key)) if rsa == nil { return nil, errors.New("failed getting rsa key") } @@ -200,7 +174,7 @@ func (key *pKey) MarshalPKIXPublicKeyDER() (der_block []byte, return nil, errors.New("failed to allocate memory BIO") } defer C.BIO_free(bio) - rsa := (*C.RSA)(C.EVP_PKEY_get1_RSA(key.key)) + rsa := (*C.RSA)(C.X_EVP_PKEY_get1_RSA(key.key)) if rsa == nil { return nil, errors.New("failed getting rsa key") } @@ -230,18 +204,18 @@ func LoadPrivateKeyFromPEM(pem_block []byte) (PrivateKey, error) { defer C.RSA_free(rsakey) // convert to PKEY - key := C.EVP_PKEY_new() + key := C.X_EVP_PKEY_new() if key == nil { return nil, errors.New("failed converting to evp_pkey") } - if C.EVP_PKEY_set1_RSA(key, (*C.struct_rsa_st)(rsakey)) != 1 { - C.EVP_PKEY_free(key) + if C.X_EVP_PKEY_set1_RSA(key, (*C.struct_rsa_st)(rsakey)) != 1 { + C.X_EVP_PKEY_free(key) return nil, errors.New("failed converting to evp_pkey") } p := &pKey{key: key} runtime.SetFinalizer(p, func(p *pKey) { - C.EVP_PKEY_free(p.key) + C.X_EVP_PKEY_free(p.key) }) return p, nil } @@ -267,18 +241,18 @@ func LoadPrivateKeyFromPEMWithPassword(pem_block []byte, password string) ( defer C.RSA_free(rsakey) // convert to PKEY - key := C.EVP_PKEY_new() + key := C.X_EVP_PKEY_new() if key == nil { return nil, errors.New("failed converting to evp_pkey") } - if C.EVP_PKEY_set1_RSA(key, (*C.struct_rsa_st)(rsakey)) != 1 { - C.EVP_PKEY_free(key) + if C.X_EVP_PKEY_set1_RSA(key, (*C.struct_rsa_st)(rsakey)) != 1 { + C.X_EVP_PKEY_free(key) return nil, errors.New("failed converting to evp_pkey") } p := &pKey{key: key} runtime.SetFinalizer(p, func(p *pKey) { - C.EVP_PKEY_free(p.key) + C.X_EVP_PKEY_free(p.key) }) return p, nil } @@ -302,18 +276,18 @@ func LoadPrivateKeyFromDER(der_block []byte) (PrivateKey, error) { defer C.RSA_free(rsakey) // convert to PKEY - key := C.EVP_PKEY_new() + key := C.X_EVP_PKEY_new() if key == nil { return nil, errors.New("failed converting to evp_pkey") } - if C.EVP_PKEY_set1_RSA(key, (*C.struct_rsa_st)(rsakey)) != 1 { - C.EVP_PKEY_free(key) + if C.X_EVP_PKEY_set1_RSA(key, (*C.struct_rsa_st)(rsakey)) != 1 { + C.X_EVP_PKEY_free(key) return nil, errors.New("failed converting to evp_pkey") } p := &pKey{key: key} runtime.SetFinalizer(p, func(p *pKey) { - C.EVP_PKEY_free(p.key) + C.X_EVP_PKEY_free(p.key) }) return p, nil } @@ -344,18 +318,18 @@ func LoadPublicKeyFromPEM(pem_block []byte) (PublicKey, error) { defer C.RSA_free(rsakey) // convert to PKEY - key := C.EVP_PKEY_new() + key := C.X_EVP_PKEY_new() if key == nil { return nil, errors.New("failed converting to evp_pkey") } - if C.EVP_PKEY_set1_RSA(key, (*C.struct_rsa_st)(rsakey)) != 1 { - C.EVP_PKEY_free(key) + if C.X_EVP_PKEY_set1_RSA(key, (*C.struct_rsa_st)(rsakey)) != 1 { + C.X_EVP_PKEY_free(key) return nil, errors.New("failed converting to evp_pkey") } p := &pKey{key: key} runtime.SetFinalizer(p, func(p *pKey) { - C.EVP_PKEY_free(p.key) + C.X_EVP_PKEY_free(p.key) }) return p, nil } @@ -379,18 +353,18 @@ func LoadPublicKeyFromDER(der_block []byte) (PublicKey, error) { defer C.RSA_free(rsakey) // convert to PKEY - key := C.EVP_PKEY_new() + key := C.X_EVP_PKEY_new() if key == nil { return nil, errors.New("failed converting to evp_pkey") } - if C.EVP_PKEY_set1_RSA(key, (*C.struct_rsa_st)(rsakey)) != 1 { - C.EVP_PKEY_free(key) + if C.X_EVP_PKEY_set1_RSA(key, (*C.struct_rsa_st)(rsakey)) != 1 { + C.X_EVP_PKEY_free(key) return nil, errors.New("failed converting to evp_pkey") } p := &pKey{key: key} runtime.SetFinalizer(p, func(p *pKey) { - C.EVP_PKEY_free(p.key) + C.X_EVP_PKEY_free(p.key) }) return p, nil } @@ -406,17 +380,17 @@ func GenerateRSAKeyWithExponent(bits int, exponent int) (PrivateKey, error) { if rsa == nil { return nil, errors.New("failed to generate RSA key") } - key := C.EVP_PKEY_new() + key := C.X_EVP_PKEY_new() if key == nil { return nil, errors.New("failed to allocate EVP_PKEY") } - if C.EVP_PKEY_assign_charp(key, C.EVP_PKEY_RSA, (*C.char)(unsafe.Pointer(rsa))) != 1 { - C.EVP_PKEY_free(key) + if C.X_EVP_PKEY_assign_charp(key, C.EVP_PKEY_RSA, (*C.char)(unsafe.Pointer(rsa))) != 1 { + C.X_EVP_PKEY_free(key) return nil, errors.New("failed to assign RSA key") } p := &pKey{key: key} runtime.SetFinalizer(p, func(p *pKey) { - C.EVP_PKEY_free(p.key) + C.X_EVP_PKEY_free(p.key) }) return p, nil } diff --git a/oracle_stubs.go b/oracle_stubs.go deleted file mode 100644 index 30492f3..0000000 --- a/oracle_stubs.go +++ /dev/null @@ -1,162 +0,0 @@ -// Copyright (C) 2014 Space Monkey, Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// +build !cgo - -package openssl - -import ( - "errors" - "net" - "time" -) - -const ( - SSLRecordSize = 16 * 1024 -) - -type Conn struct{} - -func Client(conn net.Conn, ctx *Ctx) (*Conn, error) -func Server(conn net.Conn, ctx *Ctx) (*Conn, error) - -func (c *Conn) Handshake() error -func (c *Conn) PeerCertificate() (*Certificate, error) -func (c *Conn) Close() error -func (c *Conn) Read(b []byte) (n int, err error) -func (c *Conn) Write(b []byte) (written int, err error) - -func (c *Conn) VerifyHostname(host string) error - -func (c *Conn) LocalAddr() net.Addr -func (c *Conn) RemoteAddr() net.Addr -func (c *Conn) SetDeadline(t time.Time) error -func (c *Conn) SetReadDeadline(t time.Time) error -func (c *Conn) SetWriteDeadline(t time.Time) error - -type Ctx struct{} - -type SSLVersion int - -const ( - SSLv3 SSLVersion = 0x02 - TLSv1 SSLVersion = 0x03 - TLSv1_1 SSLVersion = 0x04 - TLSv1_2 SSLVersion = 0x05 - AnyVersion SSLVersion = 0x06 -) - -func NewCtxWithVersion(version SSLVersion) (*Ctx, error) -func NewCtx() (*Ctx, error) -func NewCtxFromFiles(cert_file string, key_file string) (*Ctx, error) -func (c *Ctx) UseCertificate(cert *Certificate) error -func (c *Ctx) UsePrivateKey(key PrivateKey) error - -type CertificateStore struct{} - -func (c *Ctx) GetCertificateStore() *CertificateStore - -func (s *CertificateStore) AddCertificate(cert *Certificate) error - -func (c *Ctx) LoadVerifyLocations(ca_file string, ca_path string) error - -type Options int - -const ( - NoCompression Options = 0 - NoSSLv2 Options = 0 - NoSSLv3 Options = 0 - NoTLSv1 Options = 0 - CipherServerPreference Options = 0 - NoSessionResumptionOrRenegotiation Options = 0 - NoTicket Options = 0 -) - -func (c *Ctx) SetOptions(options Options) Options - -type Modes int - -const ( - ReleaseBuffers Modes = 0 -) - -func (c *Ctx) SetMode(modes Modes) Modes - -type VerifyOptions int - -const ( - VerifyNone VerifyOptions = 0 - VerifyPeer VerifyOptions = 0 - VerifyFailIfNoPeerCert VerifyOptions = 0 - VerifyClientOnce VerifyOptions = 0 -) - -func (c *Ctx) SetVerify(options VerifyOptions) -func (c *Ctx) SetVerifyDepth(depth int) -func (c *Ctx) SetSessionId(session_id []byte) error - -func (c *Ctx) SetCipherList(list string) error - -type SessionCacheModes int - -const ( - SessionCacheOff SessionCacheModes = 0 - SessionCacheClient SessionCacheModes = 0 - SessionCacheServer SessionCacheModes = 0 - SessionCacheBoth SessionCacheModes = 0 - NoAutoClear SessionCacheModes = 0 - NoInternalLookup SessionCacheModes = 0 - NoInternalStore SessionCacheModes = 0 - NoInternal SessionCacheModes = 0 -) - -func (c *Ctx) SetSessionCacheMode(modes SessionCacheModes) SessionCacheModes - -var ( - ValidationError = errors.New("Host validation error") -) - -type CheckFlags int - -const ( - AlwaysCheckSubject CheckFlags = 0 - NoWildcards CheckFlags = 0 -) - -func (c *Certificate) CheckHost(host string, flags CheckFlags) error -func (c *Certificate) CheckEmail(email string, flags CheckFlags) error -func (c *Certificate) CheckIP(ip net.IP, flags CheckFlags) error -func (c *Certificate) VerifyHostname(host string) error - -type PublicKey interface { - MarshalPKIXPublicKeyPEM() (pem_block []byte, err error) - MarshalPKIXPublicKeyDER() (der_block []byte, err error) - evpPKey() struct{} -} - -type PrivateKey interface { - PublicKey - MarshalPKCS1PrivateKeyPEM() (pem_block []byte, err error) - MarshalPKCS1PrivateKeyDER() (der_block []byte, err error) -} - -func LoadPrivateKeyFromPEM(pem_block []byte) (PrivateKey, error) - -type Certificate struct{} - -func LoadCertificateFromPEM(pem_block []byte) (*Certificate, error) - -func (c *Certificate) MarshalPEM() (pem_block []byte, err error) - -func (c *Certificate) PublicKey() (PublicKey, error) diff --git a/sha1.go b/sha1.go index 2592b66..e479b80 100644 --- a/sha1.go +++ b/sha1.go @@ -16,14 +16,7 @@ package openssl -/* -#include -#include -#include -#include - -#include "openssl/evp.h" -*/ +// #include "shim.h" import "C" import ( @@ -33,7 +26,7 @@ import ( ) type SHA1Hash struct { - ctx C.EVP_MD_CTX + ctx *C.EVP_MD_CTX engine *Engine } @@ -41,7 +34,10 @@ func NewSHA1Hash() (*SHA1Hash, error) { return NewSHA1HashWithEngine(nil) } func NewSHA1HashWithEngine(e *Engine) (*SHA1Hash, error) { hash := &SHA1Hash{engine: e} - C.EVP_MD_CTX_init(&hash.ctx) + hash.ctx = C.X_EVP_MD_CTX_new() + if hash.ctx == nil { + return nil, errors.New("openssl: sha1: unable to allocate ctx") + } runtime.SetFinalizer(hash, func(hash *SHA1Hash) { hash.Close() }) if err := hash.Reset(); err != nil { return nil, err @@ -50,7 +46,10 @@ func NewSHA1HashWithEngine(e *Engine) (*SHA1Hash, error) { } func (s *SHA1Hash) Close() { - C.EVP_MD_CTX_cleanup(&s.ctx) + if s.ctx != nil { + C.X_EVP_MD_CTX_free(s.ctx) + s.ctx = nil + } } func engineRef(e *Engine) *C.ENGINE { @@ -61,7 +60,7 @@ func engineRef(e *Engine) *C.ENGINE { } func (s *SHA1Hash) Reset() error { - if 1 != C.EVP_DigestInit_ex(&s.ctx, C.EVP_sha1(), engineRef(s.engine)) { + if 1 != C.X_EVP_DigestInit_ex(s.ctx, C.X_EVP_sha1(), engineRef(s.engine)) { return errors.New("openssl: sha1: cannot init digest ctx") } return nil @@ -71,7 +70,7 @@ func (s *SHA1Hash) Write(p []byte) (n int, err error) { if len(p) == 0 { return 0, nil } - if 1 != C.EVP_DigestUpdate(&s.ctx, unsafe.Pointer(&p[0]), + if 1 != C.X_EVP_DigestUpdate(s.ctx, unsafe.Pointer(&p[0]), C.size_t(len(p))) { return 0, errors.New("openssl: sha1: cannot update digest") } @@ -79,7 +78,7 @@ func (s *SHA1Hash) Write(p []byte) (n int, err error) { } func (s *SHA1Hash) Sum() (result [20]byte, err error) { - if 1 != C.EVP_DigestFinal_ex(&s.ctx, + if 1 != C.X_EVP_DigestFinal_ex(s.ctx, (*C.uchar)(unsafe.Pointer(&result[0])), nil) { return result, errors.New("openssl: sha1: cannot finalize ctx") } diff --git a/sha256.go b/sha256.go index 6785b32..922f2f3 100644 --- a/sha256.go +++ b/sha256.go @@ -16,14 +16,7 @@ package openssl -/* -#include -#include -#include -#include - -#include "openssl/evp.h" -*/ +// #include "shim.h" import "C" import ( @@ -33,7 +26,7 @@ import ( ) type SHA256Hash struct { - ctx C.EVP_MD_CTX + ctx *C.EVP_MD_CTX engine *Engine } @@ -41,7 +34,10 @@ func NewSHA256Hash() (*SHA256Hash, error) { return NewSHA256HashWithEngine(nil) func NewSHA256HashWithEngine(e *Engine) (*SHA256Hash, error) { hash := &SHA256Hash{engine: e} - C.EVP_MD_CTX_init(&hash.ctx) + hash.ctx = C.X_EVP_MD_CTX_new() + if hash.ctx == nil { + return nil, errors.New("openssl: sha256: unable to allocate ctx") + } runtime.SetFinalizer(hash, func(hash *SHA256Hash) { hash.Close() }) if err := hash.Reset(); err != nil { return nil, err @@ -50,11 +46,14 @@ func NewSHA256HashWithEngine(e *Engine) (*SHA256Hash, error) { } func (s *SHA256Hash) Close() { - C.EVP_MD_CTX_cleanup(&s.ctx) + if s.ctx != nil { + C.X_EVP_MD_CTX_free(s.ctx) + s.ctx = nil + } } func (s *SHA256Hash) Reset() error { - if 1 != C.EVP_DigestInit_ex(&s.ctx, C.EVP_sha256(), engineRef(s.engine)) { + if 1 != C.X_EVP_DigestInit_ex(s.ctx, C.X_EVP_sha256(), engineRef(s.engine)) { return errors.New("openssl: sha256: cannot init digest ctx") } return nil @@ -64,7 +63,7 @@ func (s *SHA256Hash) Write(p []byte) (n int, err error) { if len(p) == 0 { return 0, nil } - if 1 != C.EVP_DigestUpdate(&s.ctx, unsafe.Pointer(&p[0]), + if 1 != C.X_EVP_DigestUpdate(s.ctx, unsafe.Pointer(&p[0]), C.size_t(len(p))) { return 0, errors.New("openssl: sha256: cannot update digest") } @@ -72,7 +71,7 @@ func (s *SHA256Hash) Write(p []byte) (n int, err error) { } func (s *SHA256Hash) Sum() (result [32]byte, err error) { - if 1 != C.EVP_DigestFinal_ex(&s.ctx, + if 1 != C.X_EVP_DigestFinal_ex(s.ctx, (*C.uchar)(unsafe.Pointer(&result[0])), nil) { return result, errors.New("openssl: sha256: cannot finalize ctx") } diff --git a/shim.c b/shim.c new file mode 100644 index 0000000..64f2b81 --- /dev/null +++ b/shim.c @@ -0,0 +1,667 @@ +/* + * Copyright (C) 2014 Space Monkey, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef SSL_MODE_RELEASE_BUFFERS +#define SSL_MODE_RELEASE_BUFFERS 0 +#endif + +#ifndef SSL_OP_NO_COMPRESSION +#define SSL_OP_NO_COMPRESSION 0 +#endif + +#include + +#include + +#include +#include +#include +#include +#include +#include + +#include "_cgo_export.h" + +/* + * Functions defined in other .c files + */ +extern int go_init_locks(); +extern void go_thread_locking_callback(int, int, const char*, int); +static int go_write_bio_puts(BIO *b, const char *str) { + return go_write_bio_write(b, (char*)str, (int)strlen(str)); +} + +/* + ************************************************ + * v1.1.X and later implementation + ************************************************ + */ +#if OPENSSL_VERSION_NUMBER >= 0x1010000fL + +void X_BIO_set_data(BIO* bio, void* data) { + BIO_set_data(bio, data); +} + +void* X_BIO_get_data(BIO* bio) { + return BIO_get_data(bio); +} + +EVP_MD_CTX* X_EVP_MD_CTX_new() { + return EVP_MD_CTX_new(); +} + +void X_EVP_MD_CTX_free(EVP_MD_CTX* ctx) { + EVP_MD_CTX_free(ctx); +} + +static int x_bio_create(BIO *b) { + BIO_set_shutdown(b, 1); + BIO_set_init(b, 1); + BIO_set_data(b, NULL); + BIO_clear_flags(b, ~0); + return 1; +} + +static int x_bio_free(BIO *b) { + return 1; +} + +static BIO_METHOD *writeBioMethod; +static BIO_METHOD *readBioMethod; + +BIO_METHOD* BIO_s_readBio() { return readBioMethod; } +BIO_METHOD* BIO_s_writeBio() { return writeBioMethod; } + +int x_bio_init_methods() { + writeBioMethod = BIO_meth_new(BIO_TYPE_SOURCE_SINK, "Go Write BIO"); + if (!writeBioMethod) { + return 1; + } + if (1 != BIO_meth_set_write(writeBioMethod, + (int (*)(BIO *, const char *, int))go_write_bio_write)) { + return 2; + } + if (1 != BIO_meth_set_puts(writeBioMethod, go_write_bio_puts)) { + return 3; + } + if (1 != BIO_meth_set_ctrl(writeBioMethod, go_write_bio_ctrl)) { + return 4; + } + if (1 != BIO_meth_set_create(writeBioMethod, x_bio_create)) { + return 5; + } + if (1 != BIO_meth_set_destroy(writeBioMethod, x_bio_free)) { + return 6; + } + + readBioMethod = BIO_meth_new(BIO_TYPE_SOURCE_SINK, "Go Read BIO"); + if (!readBioMethod) { + return 7; + } + if (1 != BIO_meth_set_read(readBioMethod, go_read_bio_read)) { + return 8; + } + if (1 != BIO_meth_set_ctrl(readBioMethod, go_read_bio_ctrl)) { + return 9; + } + if (1 != BIO_meth_set_create(readBioMethod, x_bio_create)) { + return 10; + } + if (1 != BIO_meth_set_destroy(readBioMethod, x_bio_free)) { + return 11; + } + + return 0; +} + +const EVP_MD *X_EVP_dss() { + return NULL; +} + +const EVP_MD *X_EVP_dss1() { + return NULL; +} + +const EVP_MD *X_EVP_sha() { + return NULL; +} + +int X_EVP_CIPHER_CTX_encrypting(const EVP_CIPHER_CTX *ctx) { + return EVP_CIPHER_CTX_encrypting(ctx); +} + +int X_X509_add_ref(X509* x509) { + return X509_up_ref(x509); +} + +const ASN1_TIME *X_X509_get0_notBefore(const X509 *x) { + return X509_get0_notBefore(x); +} + +const ASN1_TIME *X_X509_get0_notAfter(const X509 *x) { + return X509_get0_notAfter(x); +} + +HMAC_CTX *X_HMAC_CTX_new(void) { + return HMAC_CTX_new(); +} + +void X_HMAC_CTX_free(HMAC_CTX *ctx) { + HMAC_CTX_free(ctx); +} + +#endif + + + +/* + ************************************************ + * v1.0.X implementation + ************************************************ + */ +#if OPENSSL_VERSION_NUMBER < 0x1010000fL + +static int x_bio_create(BIO *b) { + b->shutdown = 1; + b->init = 1; + b->num = -1; + b->ptr = NULL; + b->flags = 0; + return 1; +} + +static int x_bio_free(BIO *b) { + return 1; +} + +static BIO_METHOD writeBioMethod = { + BIO_TYPE_SOURCE_SINK, + "Go Write BIO", + (int (*)(BIO *, const char *, int))go_write_bio_write, + NULL, + go_write_bio_puts, + NULL, + go_write_bio_ctrl, + x_bio_create, + x_bio_free, + NULL}; + +static BIO_METHOD* BIO_s_writeBio() { return &writeBioMethod; } + +static BIO_METHOD readBioMethod = { + BIO_TYPE_SOURCE_SINK, + "Go Read BIO", + NULL, + go_read_bio_read, + NULL, + NULL, + go_read_bio_ctrl, + x_bio_create, + x_bio_free, + NULL}; + +static BIO_METHOD* BIO_s_readBio() { return &readBioMethod; } + +int x_bio_init_methods() { + /* statically initialized above */ + return 0; +} + +void X_BIO_set_data(BIO* bio, void* data) { + bio->ptr = data; +} + +void* X_BIO_get_data(BIO* bio) { + return bio->ptr; +} + +EVP_MD_CTX* X_EVP_MD_CTX_new() { + return EVP_MD_CTX_create(); +} + +void X_EVP_MD_CTX_free(EVP_MD_CTX* ctx) { + EVP_MD_CTX_destroy(ctx); +} + +int X_X509_add_ref(X509* x509) { + CRYPTO_add(&x509->references, 1, CRYPTO_LOCK_X509); + return 1; +} + +const ASN1_TIME *X_X509_get0_notBefore(const X509 *x) { + return x->cert_info->validity->notBefore; +} + +const ASN1_TIME *X_X509_get0_notAfter(const X509 *x) { + return x->cert_info->validity->notAfter; +} + +const EVP_MD *X_EVP_dss() { + return EVP_dss(); +} + +const EVP_MD *X_EVP_dss1() { + return EVP_dss1(); +} + +const EVP_MD *X_EVP_sha() { + return EVP_sha(); +} + +int X_EVP_CIPHER_CTX_encrypting(const EVP_CIPHER_CTX *ctx) { + return ctx->encrypt; +} + +HMAC_CTX *X_HMAC_CTX_new(void) { + /* v1.1.0 uses a OPENSSL_zalloc to allocate the memory which does not exist + * in previous versions. malloc+memset to get the same behavior */ + HMAC_CTX *ctx = (HMAC_CTX *)OPENSSL_malloc(sizeof(HMAC_CTX)); + if (ctx) { + memset(ctx, 0, sizeof(HMAC_CTX)); + HMAC_CTX_init(ctx); + } + return ctx; +} + +void X_HMAC_CTX_free(HMAC_CTX *ctx) { + if (ctx) { + HMAC_CTX_cleanup(ctx); + OPENSSL_free(ctx); + } +} + +#endif + + + +/* + ************************************************ + * common implementation + ************************************************ + */ + +int X_shim_init() { + int rc = 0; + + OPENSSL_config(NULL); + ENGINE_load_builtin_engines(); + SSL_load_error_strings(); + SSL_library_init(); + OpenSSL_add_all_algorithms(); + // + // Set up OPENSSL thread safety callbacks. We only set the locking + // callback because the default id callback implementation is good + // enough for us. + rc = go_init_locks(); + if (rc != 0) { + return rc; + } + CRYPTO_set_locking_callback(go_thread_locking_callback); + + rc = x_bio_init_methods(); + if (rc != 0) { + return rc; + } + + return 0; +} + +void X_OPENSSL_free(void *ref) { + OPENSSL_free(ref); +} + +long X_SSL_set_options(SSL* ssl, long options) { + return SSL_set_options(ssl, options); +} + +long X_SSL_get_options(SSL* ssl) { + return SSL_get_options(ssl); +} + +long X_SSL_clear_options(SSL* ssl, long options) { + return SSL_clear_options(ssl, options); +} + +long X_SSL_set_tlsext_host_name(SSL *ssl, const char *name) { + return SSL_set_tlsext_host_name(ssl, name); +} +const char * X_SSL_get_cipher_name(const SSL *ssl) { + return SSL_get_cipher_name(ssl); +} +int X_SSL_session_reused(SSL *ssl) { + return SSL_session_reused(ssl); +} + +int X_SSL_new_index() { + return SSL_get_ex_new_index(0, NULL, NULL, NULL, NULL); +} + +int X_SSL_verify_cb(int ok, X509_STORE_CTX* store) { + SSL* ssl = (SSL *)X509_STORE_CTX_get_ex_data(store, + SSL_get_ex_data_X509_STORE_CTX_idx()); + void* p = SSL_get_ex_data(ssl, get_ssl_idx()); + // get the pointer to the go Ctx object and pass it back into the thunk + return go_ssl_verify_cb_thunk(p, ok, store); +} + +const SSL_METHOD *X_SSLv23_method() { + return SSLv23_method(); +} + +const SSL_METHOD *X_SSLv3_method() { +#ifndef OPENSSL_NO_SSL3_METHOD + return SSLv3_method(); +#else + return NULL; +#endif +} + +const SSL_METHOD *X_TLSv1_method() { + return TLSv1_method(); +} + +const SSL_METHOD *X_TLSv1_1_method() { +#if defined(TLS1_1_VERSION) && !defined(OPENSSL_SYSNAME_MACOSX) + return TLSv1_1_method(); +#else + return NULL; +#endif +} + +const SSL_METHOD *X_TLSv1_2_method() { +#if defined(TLS1_2_VERSION) && !defined(OPENSSL_SYSNAME_MACOSX) + return TLSv1_2_method(); +#else + return NULL; +#endif +} + +int X_SSL_CTX_new_index() { + return SSL_CTX_get_ex_new_index(0, NULL, NULL, NULL, NULL); +} + +long X_SSL_CTX_set_options(SSL_CTX* ctx, long options) { + return SSL_CTX_set_options(ctx, options); +} + +long X_SSL_CTX_clear_options(SSL_CTX* ctx, long options) { + return SSL_CTX_clear_options(ctx, options); +} + +long X_SSL_CTX_get_options(SSL_CTX* ctx) { + return SSL_CTX_get_options(ctx); +} + +long X_SSL_CTX_set_mode(SSL_CTX* ctx, long modes) { + return SSL_CTX_set_mode(ctx, modes); +} + +long X_SSL_CTX_get_mode(SSL_CTX* ctx) { + return SSL_CTX_get_mode(ctx); +} + +long X_SSL_CTX_set_session_cache_mode(SSL_CTX* ctx, long modes) { + return SSL_CTX_set_session_cache_mode(ctx, modes); +} + +long X_SSL_CTX_sess_set_cache_size(SSL_CTX* ctx, long t) { + return SSL_CTX_sess_set_cache_size(ctx, t); +} + +long X_SSL_CTX_sess_get_cache_size(SSL_CTX* ctx) { + return SSL_CTX_sess_get_cache_size(ctx); +} + +long X_SSL_CTX_set_timeout(SSL_CTX* ctx, long t) { + return SSL_CTX_set_timeout(ctx, t); +} + +long X_SSL_CTX_get_timeout(SSL_CTX* ctx) { + return SSL_CTX_get_timeout(ctx); +} + +long X_SSL_CTX_add_extra_chain_cert(SSL_CTX* ctx, X509 *cert) { + return SSL_CTX_add_extra_chain_cert(ctx, cert); +} + +long X_SSL_CTX_set_tmp_ecdh(SSL_CTX* ctx, EC_KEY *key) { + return SSL_CTX_set_tmp_ecdh(ctx, key); +} + +long X_SSL_CTX_set_tlsext_servername_callback( + SSL_CTX* ctx, int (*cb)(SSL *con, int *ad, void *args)) { + return SSL_CTX_set_tlsext_servername_callback(ctx, cb); +} + +int X_SSL_CTX_verify_cb(int ok, X509_STORE_CTX* store) { + SSL* ssl = (SSL *)X509_STORE_CTX_get_ex_data(store, + SSL_get_ex_data_X509_STORE_CTX_idx()); + SSL_CTX* ssl_ctx = SSL_get_SSL_CTX(ssl); + void* p = SSL_CTX_get_ex_data(ssl_ctx, get_ssl_ctx_idx()); + // get the pointer to the go Ctx object and pass it back into the thunk + return go_ssl_ctx_verify_cb_thunk(p, ok, store); +} + +long X_SSL_CTX_set_tmp_dh(SSL_CTX* ctx, DH *dh) { + return SSL_CTX_set_tmp_dh(ctx, dh); +} + +long X_PEM_read_DHparams(SSL_CTX* ctx, DH *dh) { + return SSL_CTX_set_tmp_dh(ctx, dh); +} + +int X_SSL_CTX_set_tlsext_ticket_key_cb(SSL_CTX *sslctx, + int (*cb)(SSL *s, unsigned char key_name[16], + unsigned char iv[EVP_MAX_IV_LENGTH], + EVP_CIPHER_CTX *ctx, HMAC_CTX *hctx, int enc)) { + return SSL_CTX_set_tlsext_ticket_key_cb(sslctx, cb); +} + +int X_SSL_CTX_ticket_key_cb(SSL *s, unsigned char key_name[16], + unsigned char iv[EVP_MAX_IV_LENGTH], + EVP_CIPHER_CTX *cctx, HMAC_CTX *hctx, int enc) { + + SSL_CTX* ssl_ctx = SSL_get_SSL_CTX(s); + void* p = SSL_CTX_get_ex_data(ssl_ctx, get_ssl_ctx_idx()); + // get the pointer to the go Ctx object and pass it back into the thunk + return go_ticket_key_cb_thunk(p, s, key_name, iv, cctx, hctx, enc); +} + +int X_BIO_get_flags(BIO *b) { + return BIO_get_flags(b); +} + +void X_BIO_set_flags(BIO *b, int flags) { + return BIO_set_flags(b, flags); +} + +void X_BIO_clear_flags(BIO *b, int flags) { + BIO_clear_flags(b, flags); +} + +int X_BIO_read(BIO *b, void *buf, int len) { + return BIO_read(b, buf, len); +} + +int X_BIO_write(BIO *b, const void *buf, int len) { + return BIO_write(b, buf, len); +} + +BIO *X_BIO_new_write_bio() { + return BIO_new(BIO_s_writeBio()); +} + +BIO *X_BIO_new_read_bio() { + return BIO_new(BIO_s_readBio()); +} + +const EVP_MD *X_EVP_get_digestbyname(const char *name) { + return EVP_get_digestbyname(name); +} + +const EVP_MD *X_EVP_md_null() { + return EVP_md_null(); +} + +const EVP_MD *X_EVP_md5() { + return EVP_md5(); +} + +const EVP_MD *X_EVP_ripemd160() { + return EVP_ripemd160(); +} + +const EVP_MD *X_EVP_sha224() { + return EVP_sha224(); +} + +const EVP_MD *X_EVP_sha1() { + return EVP_sha1(); +} + +const EVP_MD *X_EVP_sha256() { + return EVP_sha256(); +} + +const EVP_MD *X_EVP_sha384() { + return EVP_sha384(); +} + +const EVP_MD *X_EVP_sha512() { + return EVP_sha512(); +} + +int X_EVP_MD_size(const EVP_MD *md) { + return EVP_MD_size(md); +} + +int X_EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *impl) { + return EVP_DigestInit_ex(ctx, type, impl); +} + +int X_EVP_DigestUpdate(EVP_MD_CTX *ctx, const void *d, size_t cnt) { + return EVP_DigestUpdate(ctx, d, cnt); +} + +int X_EVP_DigestFinal_ex(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *s) { + return EVP_DigestFinal_ex(ctx, md, s); +} + +int X_EVP_SignInit(EVP_MD_CTX *ctx, const EVP_MD *type) { + return EVP_SignInit(ctx, type); +} + +int X_EVP_SignUpdate(EVP_MD_CTX *ctx, const void *d, unsigned int cnt) { + return EVP_SignUpdate(ctx, d, cnt); +} + +EVP_PKEY *X_EVP_PKEY_new(void) { + return EVP_PKEY_new(); +} + +void X_EVP_PKEY_free(EVP_PKEY *pkey) { + EVP_PKEY_free(pkey); +} + +int X_EVP_PKEY_size(EVP_PKEY *pkey) { + return EVP_PKEY_size(pkey); +} + +struct rsa_st *X_EVP_PKEY_get1_RSA(EVP_PKEY *pkey) { + return EVP_PKEY_get1_RSA(pkey); +} + +int X_EVP_PKEY_set1_RSA(EVP_PKEY *pkey, struct rsa_st *key) { + return EVP_PKEY_set1_RSA(pkey, key); +} + +int X_EVP_PKEY_assign_charp(EVP_PKEY *pkey, int type, char *key) { + return EVP_PKEY_assign(pkey, type, key); +} + +int X_EVP_SignFinal(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *s, EVP_PKEY *pkey) { + return EVP_SignFinal(ctx, md, s, pkey); +} + +int X_EVP_VerifyInit(EVP_MD_CTX *ctx, const EVP_MD *type) { + return EVP_VerifyInit(ctx, type); +} + +int X_EVP_VerifyUpdate(EVP_MD_CTX *ctx, const void *d, + unsigned int cnt) { + return EVP_VerifyUpdate(ctx, d, cnt); +} + +int X_EVP_VerifyFinal(EVP_MD_CTX *ctx, const unsigned char *sigbuf, unsigned int siglen, EVP_PKEY *pkey) { + return EVP_VerifyFinal(ctx, sigbuf, siglen, pkey); +} + +int X_EVP_CIPHER_block_size(EVP_CIPHER *c) { + return EVP_CIPHER_block_size(c); +} + +int X_EVP_CIPHER_key_length(EVP_CIPHER *c) { + return EVP_CIPHER_key_length(c); +} + +int X_EVP_CIPHER_iv_length(EVP_CIPHER *c) { + return EVP_CIPHER_iv_length(c); +} + +int X_EVP_CIPHER_nid(EVP_CIPHER *c) { + return EVP_CIPHER_nid(c); +} + +int X_EVP_CIPHER_CTX_block_size(EVP_CIPHER_CTX *ctx) { + return EVP_CIPHER_CTX_block_size(ctx); +} + +int X_EVP_CIPHER_CTX_key_length(EVP_CIPHER_CTX *ctx) { + return EVP_CIPHER_CTX_key_length(ctx); +} + +int X_EVP_CIPHER_CTX_iv_length(EVP_CIPHER_CTX *ctx) { + return EVP_CIPHER_CTX_iv_length(ctx); +} + +const EVP_CIPHER *X_EVP_CIPHER_CTX_cipher(EVP_CIPHER_CTX *ctx) { + return EVP_CIPHER_CTX_cipher(ctx); +} + +size_t X_HMAC_size(const HMAC_CTX *e) { + return HMAC_size(e); +} + +int X_HMAC_Init_ex(HMAC_CTX *ctx, const void *key, int len, const EVP_MD *md, ENGINE *impl) { + return HMAC_Init_ex(ctx, key, len, md, impl); +} + +int X_HMAC_Update(HMAC_CTX *ctx, const unsigned char *data, size_t len) { + return HMAC_Update(ctx, data, len); +} + +int X_HMAC_Final(HMAC_CTX *ctx, unsigned char *md, unsigned int *len) { + return HMAC_Final(ctx, md, len); +} + +int X_sk_X509_num(STACK_OF(X509) *sk) { + return sk_X509_num(sk); +} + +X509 *X_sk_X509_value(STACK_OF(X509)* sk, int i) { + return sk_X509_value(sk, i); +} diff --git a/shim.h b/shim.h new file mode 100644 index 0000000..65705b7 --- /dev/null +++ b/shim.h @@ -0,0 +1,149 @@ +/* + * Copyright (C) 2014 Space Monkey, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* shim methods */ +extern int X_shim_init(); + +/* Library methods */ +extern void X_OPENSSL_free(void *ref); + +/* SSL methods */ +extern long X_SSL_set_options(SSL* ssl, long options); +extern long X_SSL_get_options(SSL* ssl); +extern long X_SSL_clear_options(SSL* ssl, long options); +extern long X_SSL_set_tlsext_host_name(SSL *ssl, const char *name); +extern const char * X_SSL_get_cipher_name(const SSL *ssl); +extern int X_SSL_session_reused(SSL *ssl); +extern int X_SSL_new_index(); + +extern const SSL_METHOD *X_SSLv23_method(); +extern const SSL_METHOD *X_SSLv3_method(); +extern const SSL_METHOD *X_TLSv1_method(); +extern const SSL_METHOD *X_TLSv1_1_method(); +extern const SSL_METHOD *X_TLSv1_2_method(); + +#if defined SSL_CTRL_SET_TLSEXT_HOSTNAME +extern int sni_cb(SSL *ssl_conn, int *ad, void *arg); +#endif +extern int X_SSL_verify_cb(int ok, X509_STORE_CTX* store); + +/* SSL_CTX methods */ +extern int X_SSL_CTX_new_index(); +extern long X_SSL_CTX_set_options(SSL_CTX* ctx, long options); +extern long X_SSL_CTX_clear_options(SSL_CTX* ctx, long options); +extern long X_SSL_CTX_get_options(SSL_CTX* ctx); +extern long X_SSL_CTX_set_mode(SSL_CTX* ctx, long modes); +extern long X_SSL_CTX_get_mode(SSL_CTX* ctx); +extern long X_SSL_CTX_set_session_cache_mode(SSL_CTX* ctx, long modes); +extern long X_SSL_CTX_sess_set_cache_size(SSL_CTX* ctx, long t); +extern long X_SSL_CTX_sess_get_cache_size(SSL_CTX* ctx); +extern long X_SSL_CTX_set_timeout(SSL_CTX* ctx, long t); +extern long X_SSL_CTX_get_timeout(SSL_CTX* ctx); +extern long X_SSL_CTX_add_extra_chain_cert(SSL_CTX* ctx, X509 *cert); +extern long X_SSL_CTX_set_tmp_ecdh(SSL_CTX* ctx, EC_KEY *key); +extern long X_SSL_CTX_set_tlsext_servername_callback(SSL_CTX* ctx, int (*cb)(SSL *con, int *ad, void *args)); +extern int X_SSL_CTX_verify_cb(int ok, X509_STORE_CTX* store); +extern long X_SSL_CTX_set_tmp_dh(SSL_CTX* ctx, DH *dh); +extern long X_PEM_read_DHparams(SSL_CTX* ctx, DH *dh); +extern int X_SSL_CTX_set_tlsext_ticket_key_cb(SSL_CTX *sslctx, + int (*cb)(SSL *s, unsigned char key_name[16], + unsigned char iv[EVP_MAX_IV_LENGTH], + EVP_CIPHER_CTX *ctx, HMAC_CTX *hctx, int enc)); +extern int X_SSL_CTX_ticket_key_cb(SSL *s, unsigned char key_name[16], + unsigned char iv[EVP_MAX_IV_LENGTH], + EVP_CIPHER_CTX *cctx, HMAC_CTX *hctx, int enc); + +/* BIO methods */ +extern int X_BIO_get_flags(BIO *b); +extern void X_BIO_set_flags(BIO *bio, int flags); +extern void X_BIO_clear_flags(BIO *bio, int flags); +extern void X_BIO_set_data(BIO *bio, void* data); +extern void *X_BIO_get_data(BIO *bio); +extern int X_BIO_read(BIO *b, void *buf, int len); +extern int X_BIO_write(BIO *b, const void *buf, int len); +extern BIO *X_BIO_new_write_bio(); +extern BIO *X_BIO_new_read_bio(); + +/* EVP methods */ +extern const EVP_MD *X_EVP_get_digestbyname(const char *name); +extern EVP_MD_CTX *X_EVP_MD_CTX_new(); +extern void X_EVP_MD_CTX_free(EVP_MD_CTX *ctx); +extern const EVP_MD *X_EVP_md_null(); +extern const EVP_MD *X_EVP_md5(); +extern const EVP_MD *X_EVP_sha(); +extern const EVP_MD *X_EVP_sha1(); +extern const EVP_MD *X_EVP_dss(); +extern const EVP_MD *X_EVP_dss1(); +extern const EVP_MD *X_EVP_ripemd160(); +extern const EVP_MD *X_EVP_sha224(); +extern const EVP_MD *X_EVP_sha256(); +extern const EVP_MD *X_EVP_sha384(); +extern const EVP_MD *X_EVP_sha512(); +extern int X_EVP_MD_size(const EVP_MD *md); +extern int X_EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *impl); +extern int X_EVP_DigestUpdate(EVP_MD_CTX *ctx, const void *d, size_t cnt); +extern int X_EVP_DigestFinal_ex(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *s); +extern int X_EVP_SignInit(EVP_MD_CTX *ctx, const EVP_MD *type); +extern int X_EVP_SignUpdate(EVP_MD_CTX *ctx, const void *d, unsigned int cnt); +extern EVP_PKEY *X_EVP_PKEY_new(void); +extern void X_EVP_PKEY_free(EVP_PKEY *pkey); +extern int X_EVP_PKEY_size(EVP_PKEY *pkey); +extern struct rsa_st *X_EVP_PKEY_get1_RSA(EVP_PKEY *pkey); +extern int X_EVP_PKEY_set1_RSA(EVP_PKEY *pkey, struct rsa_st *key); +extern int X_EVP_PKEY_assign_charp(EVP_PKEY *pkey, int type, char *key); +extern int X_EVP_SignFinal(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *s, EVP_PKEY *pkey); +extern int X_EVP_VerifyInit(EVP_MD_CTX *ctx, const EVP_MD *type); +extern int X_EVP_VerifyUpdate(EVP_MD_CTX *ctx, const void *d, unsigned int cnt); +extern int X_EVP_VerifyFinal(EVP_MD_CTX *ctx, const unsigned char *sigbuf, unsigned int siglen, EVP_PKEY *pkey); +extern int X_EVP_CIPHER_block_size(EVP_CIPHER *c); +extern int X_EVP_CIPHER_key_length(EVP_CIPHER *c); +extern int X_EVP_CIPHER_iv_length(EVP_CIPHER *c); +extern int X_EVP_CIPHER_nid(EVP_CIPHER *c); +extern int X_EVP_CIPHER_CTX_block_size(EVP_CIPHER_CTX *ctx); +extern int X_EVP_CIPHER_CTX_key_length(EVP_CIPHER_CTX *ctx); +extern int X_EVP_CIPHER_CTX_iv_length(EVP_CIPHER_CTX *ctx); +extern const EVP_CIPHER *X_EVP_CIPHER_CTX_cipher(EVP_CIPHER_CTX *ctx); +extern int X_EVP_CIPHER_CTX_encrypting(const EVP_CIPHER_CTX *ctx); + +/* HMAC methods */ +extern size_t X_HMAC_size(const HMAC_CTX *e); +extern HMAC_CTX *X_HMAC_CTX_new(void); +extern void X_HMAC_CTX_free(HMAC_CTX *ctx); +extern int X_HMAC_Init_ex(HMAC_CTX *ctx, const void *key, int len, const EVP_MD *md, ENGINE *impl); +extern int X_HMAC_Update(HMAC_CTX *ctx, const unsigned char *data, size_t len); +extern int X_HMAC_Final(HMAC_CTX *ctx, unsigned char *md, unsigned int *len); + +/* X509 methods */ +extern int X_X509_add_ref(X509* x509); +extern const ASN1_TIME *X_X509_get0_notBefore(const X509 *x); +extern const ASN1_TIME *X_X509_get0_notAfter(const X509 *x); +extern int X_sk_X509_num(STACK_OF(X509) *sk); +extern X509 *X_sk_X509_value(STACK_OF(X509)* sk, int i); + diff --git a/ssl.go b/ssl.go index 201c51a..eda530a 100644 --- a/ssl.go +++ b/ssl.go @@ -16,26 +16,7 @@ package openssl -/* -#include -#include -#include -#include - -static long SSL_set_options_not_a_macro(SSL* ssl, long options) { - return SSL_set_options(ssl, options); -} - -static long SSL_get_options_not_a_macro(SSL* ssl) { - return SSL_get_options(ssl); -} - -static long SSL_clear_options_not_a_macro(SSL* ssl, long options) { - return SSL_clear_options(ssl, options); -} - -extern int verify_ssl_cb(int ok, X509_STORE_CTX* store); -*/ +// #include "shim.h" import "C" import ( @@ -53,7 +34,7 @@ const ( ) var ( - ssl_idx = C.SSL_get_ex_new_index(0, nil, nil, nil, nil) + ssl_idx = C.X_SSL_new_index() ) //export get_ssl_idx @@ -66,8 +47,8 @@ type SSL struct { verify_cb VerifyCallback } -//export verify_ssl_cb_thunk -func verify_ssl_cb_thunk(p unsafe.Pointer, ok C.int, ctx *C.X509_STORE_CTX) C.int { +//export go_ssl_verify_cb_thunk +func go_ssl_verify_cb_thunk(p unsafe.Pointer, ok C.int, ctx *C.X509_STORE_CTX) C.int { defer func() { if err := recover(); err != nil { logger.Critf("openssl: verify callback panic'd: %v", err) @@ -96,19 +77,19 @@ func (s *SSL) GetServername() string { // GetOptions returns SSL options. See // https://www.openssl.org/docs/ssl/SSL_CTX_set_options.html func (s *SSL) GetOptions() Options { - return Options(C.SSL_get_options_not_a_macro(s.ssl)) + return Options(C.X_SSL_get_options(s.ssl)) } // SetOptions sets SSL options. See // https://www.openssl.org/docs/ssl/SSL_CTX_set_options.html func (s *SSL) SetOptions(options Options) Options { - return Options(C.SSL_set_options_not_a_macro(s.ssl, C.long(options))) + return Options(C.X_SSL_set_options(s.ssl, C.long(options))) } // ClearOptions clear SSL options. See // https://www.openssl.org/docs/ssl/SSL_CTX_set_options.html func (s *SSL) ClearOptions(options Options) Options { - return Options(C.SSL_clear_options_not_a_macro(s.ssl, C.long(options))) + return Options(C.X_SSL_clear_options(s.ssl, C.long(options))) } // SetVerify controls peer verification settings. See @@ -116,7 +97,7 @@ func (s *SSL) ClearOptions(options Options) Options { func (s *SSL) SetVerify(options VerifyOptions, verify_cb VerifyCallback) { s.verify_cb = verify_cb if verify_cb != nil { - C.SSL_set_verify(s.ssl, C.int(options), (*[0]byte)(C.verify_ssl_cb)) + C.SSL_set_verify(s.ssl, C.int(options), (*[0]byte)(C.X_SSL_verify_cb)) } else { C.SSL_set_verify(s.ssl, C.int(options), nil) } diff --git a/tickets.c b/tickets.c deleted file mode 100644 index 894c267..0000000 --- a/tickets.c +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright (C) 2015 Space Monkey, Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include -#include -#include "_cgo_export.h" - -int ticket_key_cb(SSL *s, unsigned char key_name[16], - unsigned char iv[EVP_MAX_IV_LENGTH], - EVP_CIPHER_CTX *cctx, HMAC_CTX *hctx, int enc) { - - SSL_CTX* ssl_ctx = SSL_get_SSL_CTX(s); - void* p = SSL_CTX_get_ex_data(ssl_ctx, get_ssl_ctx_idx()); - // get the pointer to the go Ctx object and pass it back into the thunk - return ticket_key_cb_thunk(p, s, key_name, iv, cctx, hctx, enc); -} diff --git a/tickets.go b/tickets.go index 23dc3e0..6000d27 100644 --- a/tickets.go +++ b/tickets.go @@ -16,22 +16,7 @@ package openssl -/* -#include -#include - -static int SSL_CTX_set_tlsext_ticket_key_cb_not_a_macro(SSL_CTX *sslctx, - int (*cb)(SSL *s, unsigned char key_name[16], - unsigned char iv[EVP_MAX_IV_LENGTH], - EVP_CIPHER_CTX *ctx, HMAC_CTX *hctx, int enc)) { - - return SSL_CTX_set_tlsext_ticket_key_cb(sslctx, cb); -} - -extern int ticket_key_cb(SSL *s, unsigned char key_name[16], - unsigned char iv[EVP_MAX_IV_LENGTH], - EVP_CIPHER_CTX *cctx, HMAC_CTX *hctx, int enc); -*/ +// #include "shim.h" import "C" import ( @@ -131,8 +116,8 @@ const ( ticket_req_lookupSession = 0 ) -//export ticket_key_cb_thunk -func ticket_key_cb_thunk(p unsafe.Pointer, s *C.SSL, key_name *C.uchar, +//export go_ticket_key_cb_thunk +func go_ticket_key_cb_thunk(p unsafe.Pointer, s *C.SSL, key_name *C.uchar, iv *C.uchar, cctx *C.EVP_CIPHER_CTX, hctx *C.HMAC_CTX, enc C.int) C.int { // no panic's allowed. it's super hard to guarantee any state at this point @@ -231,9 +216,9 @@ func (c *Ctx) SetTicketStore(store *TicketStore) { c.ticket_store = store if store == nil { - C.SSL_CTX_set_tlsext_ticket_key_cb_not_a_macro(c.ctx, nil) + C.X_SSL_CTX_set_tlsext_ticket_key_cb(c.ctx, nil) } else { - C.SSL_CTX_set_tlsext_ticket_key_cb_not_a_macro(c.ctx, - (*[0]byte)(C.ticket_key_cb)) + C.X_SSL_CTX_set_tlsext_ticket_key_cb(c.ctx, + (*[0]byte)(C.X_SSL_CTX_ticket_key_cb)) } } diff --git a/verify.c b/verify.c deleted file mode 100644 index d55866c..0000000 --- a/verify.c +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright (C) 2014 Space Monkey, Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include -#include "_cgo_export.h" - -int verify_cb(int ok, X509_STORE_CTX* store) { - SSL* ssl = (SSL *)X509_STORE_CTX_get_app_data(store); - SSL_CTX* ssl_ctx = SSL_get_SSL_CTX(ssl); - void* p = SSL_CTX_get_ex_data(ssl_ctx, get_ssl_ctx_idx()); - // get the pointer to the go Ctx object and pass it back into the thunk - return verify_cb_thunk(p, ok, store); -} - -int verify_ssl_cb(int ok, X509_STORE_CTX* store) { - SSL* ssl = (SSL *)X509_STORE_CTX_get_app_data(store); - void* p = SSL_get_ex_data(ssl, get_ssl_idx()); - // get the pointer to the go Ctx object and pass it back into the thunk - return verify_ssl_cb_thunk(p, ok, store); -}