| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170 |
- // Copyright (C) 2017. See AUTHORS.
- //
- // 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
- // #include "shim.h"
- 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.X_SSL_new_index()
- )
- //export get_ssl_idx
- func get_ssl_idx() C.int {
- return ssl_idx
- }
- type SSL struct {
- ssl *C.SSL
- verify_cb VerifyCallback
- }
- //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)
- 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
- // 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))
- }
- // GetOptions returns SSL options. See
- // https://www.openssl.org/docs/ssl/SSL_CTX_set_options.html
- func (s *SSL) GetOptions() Options {
- 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.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.X_SSL_clear_options(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.X_SSL_verify_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(), 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 changes context to new one. Useful 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 (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)
- }
- //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}
- // This attaches a pointer to our SSL struct into the SNI callback.
- C.SSL_set_ex_data(s.ssl, get_ssl_idx(), unsafe.Pointer(s))
- // Note: this is ctx.sni_cb, not C.sni_cb
- return C.int(sni_cb(s))
- }
|