From bb12383db79a8e3ce97419d3af0f4c51fef22c36 Mon Sep 17 00:00:00 2001 From: Viacheslav Biriukov Date: Mon, 18 Aug 2014 12:05:12 +0000 Subject: [PATCH 1/4] init sni functionality --- ctx.go | 1 + sni.c | 23 ++++++++++++++++ sni.go | 85 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 109 insertions(+) create mode 100644 sni.c create mode 100644 sni.go diff --git a/ctx.go b/ctx.go index 458291c7..e2af9674 100644 --- a/ctx.go +++ b/ctx.go @@ -98,6 +98,7 @@ var ( type Ctx struct { ctx *C.SSL_CTX verify_cb VerifyCallback + sni_cb TLSExtServernameCallback } //export get_ssl_ctx_idx diff --git a/sni.c b/sni.c new file mode 100644 index 00000000..5398da86 --- /dev/null +++ b/sni.c @@ -0,0 +1,23 @@ +// 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" +#include + +int sni_cb(SSL *con, int *ad, void *arg) { + SSL_CTX* ssl_ctx = ssl_ctx = SSL_get_SSL_CTX(con); + void* p = SSL_CTX_get_ex_data(ssl_ctx, get_ssl_ctx_idx()); + return sni_cb_thunk(p, con, ad, arg); +} diff --git a/sni.go b/sni.go new file mode 100644 index 00000000..dbc88421 --- /dev/null +++ b/sni.go @@ -0,0 +1,85 @@ +// 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 + +/* +#include +#include +#include +#include + +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); +} + +#if defined SSL_CTRL_SET_TLSEXT_HOSTNAME + extern int sni_cb(SSL *ssl_conn, int *ad, void *arg); +#endif +*/ +import "C" + +import ( + "os" + "unsafe" +) + +type SSLTLSExtErr int + +const ( + SSLTLSExtErrOK SSLTLSExtErr = C.SSL_TLSEXT_ERR_OK + SSLTLSExtErrAlertWarning SSLTLSExtErr = C.SSL_TLSEXT_ERR_ALERT_WARNING + SSLTLSEXTErrAlertFatal SSLTLSExtErr = C.SSL_TLSEXT_ERR_ALERT_FATAL + SSLTLSEXTErrNoAck SSLTLSExtErr = C.SSL_TLSEXT_ERR_NOACK +) + +type SSL struct { + ssl *C.SSL +} + +func (s *SSL) GetServername() (string, error) { + return C.GoString(C.SSL_get_servername(s.ssl, C.TLSEXT_NAMETYPE_host_name)), nil +} + +func (s *SSL) SetSSLCtx(ctx *Ctx) { + /* + * SSL_set_SSL_CTX() only changes certs as of 1.0.0d + * adjust other things we care about + */ + C.SSL_set_SSL_CTX(s.ssl, ctx.ctx) +} + +type TLSExtServernameCallback func(ssl *SSL) SSLTLSExtErr + +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)) +} + +//export sni_cb_thunk +func sni_cb_thunk(p unsafe.Pointer, con *C.SSL, ad unsafe.Pointer, arg unsafe.Pointer) C.int { + defer func() { + if err := recover(); err != nil { + logger.Critf("openssl: verify callback sni panic'd: %v", err) + os.Exit(1) + } + }() + + sni_cb := (*Ctx)(p).sni_cb + ssl := &SSL{ssl: con} + + return C.int(sni_cb(ssl)) +} From a3e1c417ca5f848345cb8000141970d9a0faa89e Mon Sep 17 00:00:00 2001 From: Viacheslav Biriukov Date: Tue, 19 Aug 2014 11:40:55 +0000 Subject: [PATCH 2/4] ssl verification functions --- ctx.go | 21 ++++++ sni.go | 85 ---------------------- ssl.go | 212 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ verify.c | 7 ++ 4 files changed, 240 insertions(+), 85 deletions(-) delete mode 100644 sni.go create mode 100644 ssl.go diff --git a/ctx.go b/ctx.go index e2af9674..a3fe45e2 100644 --- a/ctx.go +++ b/ctx.go @@ -26,6 +26,10 @@ 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_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); } @@ -370,6 +374,12 @@ func (c *Ctx) SetOptions(options Options) 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)) +} + type Modes int const ( @@ -440,6 +450,10 @@ func (c *Ctx) SetVerifyCallback(verify_cb VerifyCallback) { c.SetVerify(c.VerifyMode(), verify_cb) } +func (c *Ctx) GetVerifyCallback() VerifyCallback { + return c.verify_cb +} + func (c *Ctx) VerifyMode() VerifyOptions { return VerifyOptions(C.SSL_CTX_get_verify_mode(c.ctx)) } @@ -451,6 +465,13 @@ func (c *Ctx) SetVerifyDepth(depth int) { C.SSL_CTX_set_verify_depth(c.ctx, C.int(depth)) } +// GetVerifyDepth controls how many certificates deep the certificate +// verification logic is willing to follow a certificate chain. See +// https://www.openssl.org/docs/ssl/SSL_CTX_set_verify.html +func (c *Ctx) GetVerifyDepth() int { + return int(C.SSL_CTX_get_verify_depth(c.ctx)) +} + func (c *Ctx) SetSessionId(session_id []byte) error { runtime.LockOSThread() defer runtime.UnlockOSThread() diff --git a/sni.go b/sni.go deleted file mode 100644 index dbc88421..00000000 --- a/sni.go +++ /dev/null @@ -1,85 +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 - -/* -#include -#include -#include -#include - -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); -} - -#if defined SSL_CTRL_SET_TLSEXT_HOSTNAME - extern int sni_cb(SSL *ssl_conn, int *ad, void *arg); -#endif -*/ -import "C" - -import ( - "os" - "unsafe" -) - -type SSLTLSExtErr int - -const ( - SSLTLSExtErrOK SSLTLSExtErr = C.SSL_TLSEXT_ERR_OK - SSLTLSExtErrAlertWarning SSLTLSExtErr = C.SSL_TLSEXT_ERR_ALERT_WARNING - SSLTLSEXTErrAlertFatal SSLTLSExtErr = C.SSL_TLSEXT_ERR_ALERT_FATAL - SSLTLSEXTErrNoAck SSLTLSExtErr = C.SSL_TLSEXT_ERR_NOACK -) - -type SSL struct { - ssl *C.SSL -} - -func (s *SSL) GetServername() (string, error) { - return C.GoString(C.SSL_get_servername(s.ssl, C.TLSEXT_NAMETYPE_host_name)), nil -} - -func (s *SSL) SetSSLCtx(ctx *Ctx) { - /* - * SSL_set_SSL_CTX() only changes certs as of 1.0.0d - * adjust other things we care about - */ - C.SSL_set_SSL_CTX(s.ssl, ctx.ctx) -} - -type TLSExtServernameCallback func(ssl *SSL) SSLTLSExtErr - -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)) -} - -//export sni_cb_thunk -func sni_cb_thunk(p unsafe.Pointer, con *C.SSL, ad unsafe.Pointer, arg unsafe.Pointer) C.int { - defer func() { - if err := recover(); err != nil { - logger.Critf("openssl: verify callback sni panic'd: %v", err) - os.Exit(1) - } - }() - - sni_cb := (*Ctx)(p).sni_cb - ssl := &SSL{ssl: con} - - return C.int(sni_cb(ssl)) -} diff --git a/ssl.go b/ssl.go new file mode 100644 index 00000000..34728f19 --- /dev/null +++ b/ssl.go @@ -0,0 +1,212 @@ +// 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 + +/* +#include +#include +#include +#include + +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); +} + +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); +} + +#if defined SSL_CTRL_SET_TLSEXT_HOSTNAME + extern int sni_cb(SSL *ssl_conn, int *ad, void *arg); +#endif + +extern int verify_ssl_cb(int ok, X509_STORE_CTX* store); +*/ +import "C" + +import ( + "os" + "unsafe" +) + +type SSLTLSExtErr int + +const ( + SSLTLSExtErrOK SSLTLSExtErr = C.SSL_TLSEXT_ERR_OK + SSLTLSExtErrAlertWarning SSLTLSExtErr = C.SSL_TLSEXT_ERR_ALERT_WARNING + SSLTLSEXTErrAlertFatal SSLTLSExtErr = C.SSL_TLSEXT_ERR_ALERT_FATAL + SSLTLSEXTErrNoAck SSLTLSExtErr = C.SSL_TLSEXT_ERR_NOACK +) + +var ( + ssl_idx = C.SSL_get_ex_new_index(0, nil, nil, nil, nil) +) + +//export get_ssl_idx +func get_ssl_idx() C.int { + return ssl_idx +} + +type SSL struct { + ssl *C.SSL + 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 { + defer func() { + if err := recover(); err != nil { + logger.Critf("openssl: verify callback panic'd: %v", err) + os.Exit(1) + } + }() + verify_cb := (*SSL)(p).verify_cb + // set up defaults just in case verify_cb is nil + if verify_cb != nil { + store := &CertificateStoreCtx{ctx: ctx} + if verify_cb(ok == 1, store) { + ok = 1 + } else { + ok = 0 + } + } + return ok +} + +// Wrapper around SSL_get_servername. Returns server name according to rfc6066 +// Extension Definitions. +func (s *SSL) GetServername() string { + return C.GoString(C.SSL_get_servername(s.ssl, C.TLSEXT_NAMETYPE_host_name)) +} + +// 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)) +} + +// 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))) +} + +// 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))) +} + +// SetVerify controls peer verification settings. See +// http://www.openssl.org/docs/ssl/SSL_CTX_set_verify.html +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)) + } else { + C.SSL_set_verify(s.ssl, C.int(options), nil) + } +} + +// SetVerifyMode controls peer verification setting. See +// http://www.openssl.org/docs/ssl/SSL_CTX_set_verify.html +func (s *SSL) SetVerifyMode(options VerifyOptions) { + s.SetVerify(options, s.verify_cb) +} + +// SetVerifyCallback controls peer verification setting. See +// http://www.openssl.org/docs/ssl/SSL_CTX_set_verify.html +func (s *SSL) SetVerifyCallback(verify_cb VerifyCallback) { + s.SetVerify(s.VerifyMode(), s.verify_cb) +} + +// GetVerifyCallback returns callback function. See +// http://www.openssl.org/docs/ssl/SSL_CTX_set_verify.html +func (s *SSL) GetVerifyCallback() VerifyCallback { + return s.verify_cb +} + +// VerifyMode returns peer verification setting. See +// http://www.openssl.org/docs/ssl/SSL_CTX_set_verify.html +func (s *SSL) VerifyMode() VerifyOptions { + return VerifyOptions(C.SSL_get_verify_mode(s.ssl)) +} + +// SetVerifyDepth controls how many certificates deep the certificate +// verification logic is willing to follow a certificate chain. See +// https://www.openssl.org/docs/ssl/SSL_CTX_set_verify.html +func (s *SSL) SetVerifyDepth(depth int) { + C.SSL_set_verify_depth(s.ssl, C.int(depth)) +} + +// GetVerifyDepth controls how many certificates deep the certificate +// verification logic is willing to follow a certificate chain. See +// https://www.openssl.org/docs/ssl/SSL_CTX_set_verify.html +func (s *SSL) GetVerifyDepth() int { + return int(C.SSL_get_verify_depth(s.ssl)) +} + +// SetSSLCtx change context to new one. Useful for Server Name Indication (SNI) +// rfc6066. See +// http://stackoverflow.com/questions/22373332/serving-multiple-domains-in-one-box-with-sni +func (s *SSL) SetSSLCtx(ctx *Ctx) { + /* + * SSL_set_SSL_CTX() only changes certs as of 1.0.0d + * adjust other things we care about + */ + C.SSL_set_SSL_CTX(s.ssl, ctx.ctx) +} + +type TLSExtServernameCallback func(ssl *SSL) SSLTLSExtErr + +// SetTLSExtServernameCallback sets callback function for Server Name Indication +// (SNI) rfc6066. See +// 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)) +} + +//export sni_cb_thunk +func sni_cb_thunk(p unsafe.Pointer, con *C.SSL, ad unsafe.Pointer, arg unsafe.Pointer) C.int { + defer func() { + if err := recover(); err != nil { + logger.Critf("openssl: verify callback sni panic'd: %v", err) + os.Exit(1) + } + }() + + sni_cb := (*Ctx)(p).sni_cb + + s := &SSL{ssl: con} + C.SSL_set_ex_data(s.ssl, get_ssl_idx(), unsafe.Pointer(s)) + + // don't need finalizer because we have one in the connection code + //runtime.SetFinalizer(s, func(s *SSL) { + // C.SSL_free(s.ssl) + //}) + + return C.int(sni_cb(s)) +} diff --git a/verify.c b/verify.c index bfc62681..a4f81252 100644 --- a/verify.c +++ b/verify.c @@ -23,3 +23,10 @@ int verify_cb(int ok, X509_STORE_CTX* store) { // 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); +} From 8c73521f2a038776e5b5a4a9d85852754415b369 Mon Sep 17 00:00:00 2001 From: Viacheslav Biriukov Date: Tue, 19 Aug 2014 14:28:17 +0000 Subject: [PATCH 3/4] refactorig and add example --- ctx.go | 18 ++++++++++++++++++ sni_test.go | 23 +++++++++++++++++++++++ ssl.go | 22 ++-------------------- 3 files changed, 43 insertions(+), 20 deletions(-) create mode 100644 sni_test.go diff --git a/ctx.go b/ctx.go index a3fe45e2..845de6dd 100644 --- a/ctx.go +++ b/ctx.go @@ -54,6 +54,10 @@ 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 @@ -78,6 +82,10 @@ static const SSL_METHOD *OUR_TLSv1_2_method() { #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); */ import "C" @@ -472,6 +480,16 @@ func (c *Ctx) GetVerifyDepth() int { return int(C.SSL_CTX_get_verify_depth(c.ctx)) } +type TLSExtServernameCallback func(ssl *SSL) SSLTLSExtErr + +// SetTLSExtServernameCallback sets callback function for Server Name Indication +// (SNI) rfc6066 (http://tools.ietf.org/html/rfc6066). See +// 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)) +} + func (c *Ctx) SetSessionId(session_id []byte) error { runtime.LockOSThread() defer runtime.UnlockOSThread() diff --git a/sni_test.go b/sni_test.go new file mode 100644 index 00000000..ee3b1a8b --- /dev/null +++ b/sni_test.go @@ -0,0 +1,23 @@ +// 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. + +package openssl + +import "fmt" + +// We can implemant SNI rfc6066 (http://tools.ietf.org/html/rfc6066) on the server side using foolowing callback. +// You should implement context storage (tlsCtxStorage) by your self. +func ExampleSetTLSExtServernameCallback() { + fmt.Println("Hello") +} diff --git a/ssl.go b/ssl.go index 34728f19..fd856c78 100644 --- a/ssl.go +++ b/ssl.go @@ -22,10 +22,6 @@ package openssl #include #include -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); -} - static long SSL_set_options_not_a_macro(SSL* ssl, long options) { return SSL_set_options(ssl, options); } @@ -38,10 +34,6 @@ static long SSL_clear_options_not_a_macro(SSL* ssl, long options) { return SSL_clear_options(ssl, options); } -#if defined SSL_CTRL_SET_TLSEXT_HOSTNAME - extern int sni_cb(SSL *ssl_conn, int *ad, void *arg); -#endif - extern int verify_ssl_cb(int ok, X509_STORE_CTX* store); */ import "C" @@ -96,7 +88,7 @@ func verify_ssl_cb_thunk(p unsafe.Pointer, ok C.int, ctx *C.X509_STORE_CTX) C.in } // Wrapper around SSL_get_servername. Returns server name according to rfc6066 -// Extension Definitions. +// (http://tools.ietf.org/html/rfc6066) Extension Definitions. func (s *SSL) GetServername() string { return C.GoString(C.SSL_get_servername(s.ssl, C.TLSEXT_NAMETYPE_host_name)) } @@ -169,7 +161,7 @@ func (s *SSL) GetVerifyDepth() int { } // SetSSLCtx change context to new one. Useful for Server Name Indication (SNI) -// rfc6066. See +// rfc6066 (http://tools.ietf.org/html/rfc6066). See // http://stackoverflow.com/questions/22373332/serving-multiple-domains-in-one-box-with-sni func (s *SSL) SetSSLCtx(ctx *Ctx) { /* @@ -179,16 +171,6 @@ func (s *SSL) SetSSLCtx(ctx *Ctx) { C.SSL_set_SSL_CTX(s.ssl, ctx.ctx) } -type TLSExtServernameCallback func(ssl *SSL) SSLTLSExtErr - -// SetTLSExtServernameCallback sets callback function for Server Name Indication -// (SNI) rfc6066. See -// 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)) -} - //export sni_cb_thunk func sni_cb_thunk(p unsafe.Pointer, con *C.SSL, ad unsafe.Pointer, arg unsafe.Pointer) C.int { defer func() { From 9f697402fefb8e3259281736cc08936904c06fad Mon Sep 17 00:00:00 2001 From: Viacheslav Biriukov Date: Tue, 19 Aug 2014 14:44:48 +0000 Subject: [PATCH 4/4] doc refactoring --- ssl.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ssl.go b/ssl.go index fd856c78..fec3daca 100644 --- a/ssl.go +++ b/ssl.go @@ -88,7 +88,7 @@ func verify_ssl_cb_thunk(p unsafe.Pointer, ok C.int, ctx *C.X509_STORE_CTX) C.in } // Wrapper around SSL_get_servername. Returns server name according to rfc6066 -// (http://tools.ietf.org/html/rfc6066) Extension Definitions. +// http://tools.ietf.org/html/rfc6066. func (s *SSL) GetServername() string { return C.GoString(C.SSL_get_servername(s.ssl, C.TLSEXT_NAMETYPE_host_name)) } @@ -161,7 +161,7 @@ func (s *SSL) GetVerifyDepth() int { } // SetSSLCtx change context to new one. Useful for Server Name Indication (SNI) -// rfc6066 (http://tools.ietf.org/html/rfc6066). See +// rfc6066 http://tools.ietf.org/html/rfc6066. See // http://stackoverflow.com/questions/22373332/serving-multiple-domains-in-one-box-with-sni func (s *SSL) SetSSLCtx(ctx *Ctx) { /*