summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Godeps2
-rw-r--r--vendor/src/github.com/spacemonkeygo/openssl/cert.go32
-rw-r--r--vendor/src/github.com/spacemonkeygo/openssl/cert_test.go44
-rw-r--r--vendor/src/github.com/spacemonkeygo/openssl/conn.go90
-rw-r--r--vendor/src/github.com/spacemonkeygo/openssl/ctx.go80
-rw-r--r--vendor/src/github.com/spacemonkeygo/openssl/ctx_test.go48
-rw-r--r--vendor/src/github.com/spacemonkeygo/openssl/digest.go53
-rw-r--r--vendor/src/github.com/spacemonkeygo/openssl/key.go37
-rw-r--r--vendor/src/github.com/spacemonkeygo/openssl/net.go19
-rw-r--r--vendor/src/github.com/spacemonkeygo/openssl/old_openssl_compat.go44
-rw-r--r--vendor/src/github.com/spacemonkeygo/openssl/sni.c23
-rw-r--r--vendor/src/github.com/spacemonkeygo/openssl/sni_test.go23
-rw-r--r--vendor/src/github.com/spacemonkeygo/openssl/ssl.go167
-rw-r--r--vendor/src/github.com/spacemonkeygo/openssl/verify.c10
14 files changed, 594 insertions, 78 deletions
diff --git a/Godeps b/Godeps
index d2b16f7dee4..3981a4d9bfb 100644
--- a/Godeps
+++ b/Godeps
@@ -4,6 +4,6 @@ github.com/jacobsa/oglematchers 4fc24f97b5b74022c2a3f4ca7eed57ca29083d3e
github.com/smartystreets/goconvey 75bc4a2dad71e5c5b51c5009b33eba766ec57051
github.com/jessevdk/go-flags 1679536dcc895411a9f5848d9a0250be7856448c
github.com/3rf/mongo-lint 3550fdcf1f43b89aaeabaa4559eaae6dc4407e42
-github.com/spacemonkeygo/openssl 4c6dbafa5ec35b3ffc6a1b1e1fe29c3eba2053ec github.com/10gen/openssl
+github.com/spacemonkeygo/openssl 28e108cf76dcb7bd5aa445a0f4348b312464004e github.com/10gen/openssl
github.com/howeyc/gopass 2c70fa70727c953c51695f800f25d6b44abb368e
golang.org/x/crypto b7d6bf2c61544745a02f83dec90393985fc3a065
diff --git a/vendor/src/github.com/spacemonkeygo/openssl/cert.go b/vendor/src/github.com/spacemonkeygo/openssl/cert.go
index 673da8574bb..61637c649fa 100644
--- a/vendor/src/github.com/spacemonkeygo/openssl/cert.go
+++ b/vendor/src/github.com/spacemonkeygo/openssl/cert.go
@@ -27,6 +27,7 @@ import "C"
import (
"errors"
"io/ioutil"
+ "math/big"
"runtime"
"time"
"unsafe"
@@ -57,7 +58,7 @@ type Certificate struct {
}
type CertificateInfo struct {
- Serial int
+ Serial *big.Int
Issued time.Duration
Expires time.Duration
Country string
@@ -106,6 +107,19 @@ func (n *Name) AddTextEntries(entries map[string]string) error {
return nil
}
+// GetEntry returns a name entry based on NID. If no entry, then ("", false) is
+// returned.
+func (n *Name) GetEntry(nid NID) (entry string, ok bool) {
+ entrylen := C.X509_NAME_get_text_by_NID(n.name, C.int(nid), nil, 0)
+ if entrylen == -1 {
+ return "", false
+ }
+ buf := (*C.char)(C.malloc(C.size_t(entrylen + 1)))
+ defer C.free(unsafe.Pointer(buf))
+ C.X509_NAME_get_text_by_NID(n.name, C.int(nid), buf, entrylen+1)
+ return C.GoStringN(buf, entrylen), true
+}
+
// NewCertificate generates a basic certificate based
// on the provided CertificateInfo struct
func NewCertificate(info *CertificateInfo, key PublicKey) (*Certificate, error) {
@@ -193,8 +207,20 @@ func (c *Certificate) SetIssuerName(name *Name) error {
}
// SetSerial sets the serial of a certificate.
-func (c *Certificate) SetSerial(serial int) error {
- if C.ASN1_INTEGER_set(C.X509_get_serialNumber(c.x), C.long(serial)) != 1 {
+func (c *Certificate) SetSerial(serial *big.Int) error {
+ sno := C.ASN1_INTEGER_new()
+ defer C.ASN1_INTEGER_free(sno)
+ bn := C.BN_new()
+ defer C.BN_free(bn)
+
+ serialBytes := serial.Bytes()
+ if bn = C.BN_bin2bn((*C.uchar)(unsafe.Pointer(&serialBytes[0])), C.int(len(serialBytes)), bn); bn == nil {
+ return errors.New("failed to set serial")
+ }
+ if sno = C.BN_to_ASN1_INTEGER(bn, sno); sno == nil {
+ return errors.New("failed to set serial")
+ }
+ if C.X509_set_serialNumber(c.x, sno) != 1 {
return errors.New("failed to set serial")
}
return nil
diff --git a/vendor/src/github.com/spacemonkeygo/openssl/cert_test.go b/vendor/src/github.com/spacemonkeygo/openssl/cert_test.go
index 0dfac375ae7..c32883ba4eb 100644
--- a/vendor/src/github.com/spacemonkeygo/openssl/cert_test.go
+++ b/vendor/src/github.com/spacemonkeygo/openssl/cert_test.go
@@ -15,6 +15,7 @@
package openssl
import (
+ "math/big"
"testing"
"time"
)
@@ -25,7 +26,7 @@ func TestCertGenerate(t *testing.T) {
t.Fatal(err)
}
info := &CertificateInfo{
- Serial: 1,
+ Serial: big.NewInt(int64(1)),
Issued: 0,
Expires: 24 * time.Hour,
Country: "US",
@@ -47,7 +48,7 @@ func TestCAGenerate(t *testing.T) {
t.Fatal(err)
}
info := &CertificateInfo{
- Serial: 1,
+ Serial: big.NewInt(int64(1)),
Issued: 0,
Expires: 24 * time.Hour,
Country: "US",
@@ -74,7 +75,7 @@ func TestCAGenerate(t *testing.T) {
t.Fatal(err)
}
info = &CertificateInfo{
- Serial: 1,
+ Serial: big.NewInt(int64(1)),
Issued: 0,
Expires: 24 * time.Hour,
Country: "US",
@@ -99,3 +100,40 @@ func TestCAGenerate(t *testing.T) {
t.Fatal(err)
}
}
+
+func TestCertGetNameEntry(t *testing.T) {
+ key, err := GenerateRSAKey(2048)
+ if err != nil {
+ t.Fatal(err)
+ }
+ info := &CertificateInfo{
+ Serial: big.NewInt(int64(1)),
+ Issued: 0,
+ Expires: 24 * time.Hour,
+ Country: "US",
+ Organization: "Test",
+ CommonName: "localhost",
+ }
+ cert, err := NewCertificate(info, key)
+ if err != nil {
+ t.Fatal(err)
+ }
+ name, err := cert.GetSubjectName()
+ if err != nil {
+ t.Fatal(err)
+ }
+ entry, ok := name.GetEntry(NID_commonName)
+ if !ok {
+ t.Fatal("no common name")
+ }
+ if entry != "localhost" {
+ t.Fatalf("expected localhost; got %q", entry)
+ }
+ entry, ok = name.GetEntry(NID_localityName)
+ if ok {
+ t.Fatal("did not expect a locality name")
+ }
+ if entry != "" {
+ t.Fatalf("entry should be empty; got %q", entry)
+ }
+}
diff --git a/vendor/src/github.com/spacemonkeygo/openssl/conn.go b/vendor/src/github.com/spacemonkeygo/openssl/conn.go
index 55a4b6cb67c..afc73a50ae3 100644
--- a/vendor/src/github.com/spacemonkeygo/openssl/conn.go
+++ b/vendor/src/github.com/spacemonkeygo/openssl/conn.go
@@ -16,25 +16,28 @@
package openssl
-// #include <stdlib.h>
-// #include <openssl/ssl.h>
-// #include <openssl/conf.h>
-// #include <openssl/err.h>
-//
-// 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);
-// }
+/*
+#include <stdlib.h>
+#include <openssl/ssl.h>
+#include <openssl/conf.h>
+#include <openssl/err.h>
+
+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);
+}
+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);
+}
+*/
import "C"
import (
"errors"
+ "fmt"
"io"
"net"
"runtime"
@@ -381,11 +384,13 @@ type ConnectionState struct {
CertificateError error
CertificateChain []*Certificate
CertificateChainError error
+ SessionReused bool
}
func (c *Conn) ConnectionState() (rv ConnectionState) {
rv.Certificate, rv.CertificateError = c.PeerCertificate()
rv.CertificateChain, rv.CertificateChainError = c.PeerCertificateChain()
+ rv.SessionReused = c.SessionReused()
return
}
@@ -565,17 +570,56 @@ func (c *Conn) UnderlyingConn() net.Conn {
return c.conn
}
-func (c *Conn) SetTlsExtHostName(name string) error {
- cname := C.CString(name)
- defer C.free(unsafe.Pointer(cname))
+func (c *Conn) VerifyResult() VerifyResult {
+ return VerifyResult(C.SSL_get_verify_result(c.ssl))
+}
+
+func (c *Conn) SessionReused() bool {
+ return C.SSL_session_reused_not_a_macro(c.ssl) == 1
+}
+
+func (c *Conn) GetSession() ([]byte, error) {
runtime.LockOSThread()
defer runtime.UnlockOSThread()
- if C.SSL_set_tlsext_host_name_not_a_macro(c.ssl, cname) == 0 {
- return errorFromErrorQueue()
+
+ // get1 increases the refcount of the session, so we have to free it.
+ session := (*C.SSL_SESSION)(C.SSL_get1_session(c.ssl))
+ if session == nil {
+ return nil, errors.New("failed to get session")
}
- return nil
+ defer C.SSL_SESSION_free(session)
+
+ // get the size of the encoding
+ slen := C.i2d_SSL_SESSION(session, nil)
+
+ buf := (*C.uchar)(C.malloc(C.size_t(slen)))
+ defer C.free(unsafe.Pointer(buf))
+
+ // this modifies the value of buf (seriously), so we have to pass in a temp
+ // var so that we can actually read the bytes from buf.
+ tmp := buf
+ slen2 := C.i2d_SSL_SESSION(session, &tmp)
+ if slen != slen2 {
+ return nil, errors.New("session had different lengths")
+ }
+
+ return C.GoBytes(unsafe.Pointer(buf), slen), nil
}
-func (c *Conn) VerifyResult() VerifyResult {
- return VerifyResult(C.SSL_get_verify_result(c.ssl))
+func (c *Conn) setSession(session []byte) error {
+ runtime.LockOSThread()
+ defer runtime.UnlockOSThread()
+
+ ptr := (*C.uchar)(&session[0])
+ s := C.d2i_SSL_SESSION(nil, &ptr, C.long(len(session)))
+ if s == nil {
+ return fmt.Errorf("unable to load session: %s", errorFromErrorQueue())
+ }
+ defer C.SSL_SESSION_free(s)
+
+ ret := C.SSL_set_session(c.ssl, s)
+ if ret != 1 {
+ return fmt.Errorf("unable to set session: %s", errorFromErrorQueue())
+ }
+ return nil
}
diff --git a/vendor/src/github.com/spacemonkeygo/openssl/ctx.go b/vendor/src/github.com/spacemonkeygo/openssl/ctx.go
index c1aa4cc706a..e8c1824f808 100644
--- a/vendor/src/github.com/spacemonkeygo/openssl/ctx.go
+++ b/vendor/src/github.com/spacemonkeygo/openssl/ctx.go
@@ -31,6 +31,10 @@ 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);
}
@@ -43,6 +47,22 @@ 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);
}
@@ -60,7 +80,7 @@ static long SSL_CTX_add_extra_chain_cert_not_a_macro(SSL_CTX* ctx, X509 *cert) {
#endif
static const SSL_METHOD *OUR_TLSv1_1_method() {
-#if defined(TLS1_1_VERSION) && !defined(OPENSSL_SYSNAME_MACOSX)
+#if OPENSSL_VERSION_NUMBER > 0x1000100fL && defined(TLS1_1_VERSION) && !defined(OPENSSL_SYSNAME_MACOSX)
return TLSv1_1_method();
#else
return NULL;
@@ -68,13 +88,17 @@ static const SSL_METHOD *OUR_TLSv1_1_method() {
}
static const SSL_METHOD *OUR_TLSv1_2_method() {
-#if defined(TLS1_2_VERSION) && !defined(OPENSSL_SYSNAME_MACOSX)
+#if OPENSSL_VERSION_NUMBER > 0x1000100fL && 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);
typedef STACK_OF(X509_NAME) *STACK_OF_X509_NAME_not_a_macro;
@@ -93,6 +117,7 @@ import (
"io/ioutil"
"os"
"runtime"
+ "time"
"unsafe"
"github.com/spacemonkeygo/spacelog"
@@ -110,6 +135,7 @@ type Ctx struct {
chain []*Certificate
key PrivateKey
verify_cb VerifyCallback
+ sni_cb TLSExtServernameCallback
}
//export get_ssl_ctx_idx
@@ -376,6 +402,8 @@ func (c *Ctx) AddChainCertificate(cert *Certificate) error {
if int(C.SSL_CTX_add_extra_chain_cert_not_a_macro(c.ctx, cert.x)) != 1 {
return errorFromErrorQueue()
}
+ // OpenSSL takes ownership via SSL_CTX_add_extra_chain_cert
+ runtime.SetFinalizer(cert, nil)
return nil
}
@@ -541,6 +569,10 @@ type CertificateStoreCtx struct {
ssl_ctx *Ctx
}
+func (self *CertificateStoreCtx) VerifyResult() VerifyResult {
+ return VerifyResult(C.X509_STORE_CTX_get_error(self.ctx))
+}
+
func (self *CertificateStoreCtx) Err() error {
code := C.X509_STORE_CTX_get_error(self.ctx)
if code == C.X509_V_OK {
@@ -619,6 +651,12 @@ func (c *Ctx) ClearOptions(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 (
@@ -697,6 +735,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))
}
@@ -708,6 +750,15 @@ 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))
+}
+
+type TLSExtServernameCallback func(ssl *SSL) SSLTLSExtErr
+
func (c *Ctx) SetSessionId(session_id []byte) error {
runtime.LockOSThread()
defer runtime.UnlockOSThread()
@@ -755,3 +806,28 @@ func (c *Ctx) SetSessionCacheMode(modes SessionCacheModes) SessionCacheModes {
return SessionCacheModes(
C.SSL_CTX_set_session_cache_mode_not_a_macro(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))
+ 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
+}
+
+// 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)))
+}
+
+// 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))
+}
diff --git a/vendor/src/github.com/spacemonkeygo/openssl/ctx_test.go b/vendor/src/github.com/spacemonkeygo/openssl/ctx_test.go
new file mode 100644
index 00000000000..9644e518bf3
--- /dev/null
+++ b/vendor/src/github.com/spacemonkeygo/openssl/ctx_test.go
@@ -0,0 +1,48 @@
+// Copyright (C) 2014 Ryan Hileman
+//
+// 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 (
+ "testing"
+ "time"
+)
+
+func TestCtxTimeoutOption(t *testing.T) {
+ ctx, _ := NewCtx()
+ oldTimeout1 := ctx.GetTimeout()
+ newTimeout1 := oldTimeout1 + (time.Duration(99) * time.Second)
+ oldTimeout2 := ctx.SetTimeout(newTimeout1)
+ newTimeout2 := ctx.GetTimeout()
+ if oldTimeout1 != oldTimeout2 {
+ t.Error("SetTimeout() returns something undocumented")
+ }
+ if newTimeout1 != newTimeout2 {
+ t.Error("SetTimeout() does not save anything to ctx")
+ }
+}
+
+func TestCtxSessCacheSizeOption(t *testing.T) {
+ ctx, _ := NewCtx()
+ oldSize1 := ctx.SessGetCacheSize()
+ newSize1 := oldSize1 + 42
+ oldSize2 := ctx.SessSetCacheSize(newSize1)
+ newSize2 := ctx.SessGetCacheSize()
+ if oldSize1 != oldSize2 {
+ t.Error("SessSetCacheSize() returns something undocumented")
+ }
+ if newSize1 != newSize2 {
+ t.Error("SessSetCacheSize() does not save anything to ctx")
+ }
+}
diff --git a/vendor/src/github.com/spacemonkeygo/openssl/digest.go b/vendor/src/github.com/spacemonkeygo/openssl/digest.go
new file mode 100644
index 00000000000..44d4d001b13
--- /dev/null
+++ b/vendor/src/github.com/spacemonkeygo/openssl/digest.go
@@ -0,0 +1,53 @@
+// 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.
+
+// +build cgo
+
+package openssl
+
+// #include <openssl/evp.h>
+import "C"
+
+import (
+ "fmt"
+ "unsafe"
+)
+
+// Digest represents and openssl message digest.
+type Digest struct {
+ ptr *C.EVP_MD
+}
+
+// GetDigestByName returns the Digest with the name or nil and an error if the
+// digest was not found.
+func GetDigestByName(name string) (*Digest, error) {
+ cname := C.CString(name)
+ defer C.free(unsafe.Pointer(cname))
+ p := C.EVP_get_digestbyname(cname)
+ if p == nil {
+ return nil, fmt.Errorf("Digest %v not found", name)
+ }
+ // we can consider digests to use static mem; don't need to free
+ return &Digest{ptr: p}, nil
+}
+
+// GetDigestByName returns the Digest with the NID or nil and an error if the
+// digest was not found.
+func GetDigestByNid(nid NID) (*Digest, error) {
+ sn, err := Nid2ShortName(nid)
+ if err != nil {
+ return nil, err
+ }
+ return GetDigestByName(sn)
+}
diff --git a/vendor/src/github.com/spacemonkeygo/openssl/key.go b/vendor/src/github.com/spacemonkeygo/openssl/key.go
index ec6d7805824..c69a101631f 100644
--- a/vendor/src/github.com/spacemonkeygo/openssl/key.go
+++ b/vendor/src/github.com/spacemonkeygo/openssl/key.go
@@ -244,6 +244,43 @@ func LoadPrivateKeyFromPEM(pem_block []byte) (PrivateKey, error) {
return p, nil
}
+// LoadPrivateKeyFromPEM loads a private key from a PEM-encoded block.
+func LoadPrivateKeyFromPEMWidthPassword(pem_block []byte, password string) (
+ PrivateKey, error) {
+ if len(pem_block) == 0 {
+ return nil, errors.New("empty pem block")
+ }
+ bio := C.BIO_new_mem_buf(unsafe.Pointer(&pem_block[0]),
+ C.int(len(pem_block)))
+ if bio == nil {
+ return nil, errors.New("failed creating bio")
+ }
+ defer C.BIO_free(bio)
+ cs := C.CString(password)
+ defer C.free(unsafe.Pointer(cs))
+ rsakey := C.PEM_read_bio_RSAPrivateKey(bio, nil, nil, unsafe.Pointer(cs))
+ if rsakey == nil {
+ return nil, errors.New("failed reading rsa key")
+ }
+ defer C.RSA_free(rsakey)
+
+ // convert to PKEY
+ key := C.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)
+ 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)
+ })
+ return p, nil
+}
+
// LoadPublicKeyFromPEM loads a public key from a PEM-encoded block.
func LoadPublicKeyFromPEM(pem_block []byte) (PublicKey, error) {
if len(pem_block) == 0 {
diff --git a/vendor/src/github.com/spacemonkeygo/openssl/net.go b/vendor/src/github.com/spacemonkeygo/openssl/net.go
index 275f5c27b97..3cdd040d4d4 100644
--- a/vendor/src/github.com/spacemonkeygo/openssl/net.go
+++ b/vendor/src/github.com/spacemonkeygo/openssl/net.go
@@ -77,6 +77,25 @@ const (
// This library is not nice enough to use the system certificate store by
// default for you yet.
func Dial(network, addr string, ctx *Ctx, flags DialFlags) (*Conn, error) {
+ return DialSession(network, addr, ctx, flags, nil)
+}
+
+// DialSession will connect to network/address and then wrap the corresponding
+// underlying connection with an OpenSSL client connection using context ctx.
+// If flags includes InsecureSkipHostVerification, the server certificate's
+// hostname will not be checked to match the hostname in addr. Otherwise, flags
+// should be 0.
+//
+// Dial probably won't work for you unless you set a verify location or add
+// some certs to the certificate store of the client context you're using.
+// This library is not nice enough to use the system certificate store by
+// default for you yet.
+//
+// If session is not nil it will be used to resume the tls state. The session
+// can be retrieved from the GetSession method on the Conn.
+func DialSession(network, addr string, ctx *Ctx, flags DialFlags,
+ session []byte) (*Conn, error) {
+
host, _, err := net.SplitHostPort(addr)
if err != nil {
return nil, err
diff --git a/vendor/src/github.com/spacemonkeygo/openssl/old_openssl_compat.go b/vendor/src/github.com/spacemonkeygo/openssl/old_openssl_compat.go
deleted file mode 100644
index 028f13bdcc0..00000000000
--- a/vendor/src/github.com/spacemonkeygo/openssl/old_openssl_compat.go
+++ /dev/null
@@ -1,44 +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 !darwin brew
-// +build cgo
-
-package openssl
-
-// #include <openssl/ssl.h>
-import "C"
-
-// these constants do not exist in the openssl version packaged with os x. when
-// darwin decides to update the base openssl version, we can move these back
-// to the appropriate spots in the source. as a workaround, if you need access
-// to these constants on darwin, use homebrew or whatever to install a more
-// recent version of os x, and build the package with the '-tags brew' flag
-
-const (
- UnsupportedConstraintSyntax VerifyResult = C.X509_V_ERR_UNSUPPORTED_CONSTRAINT_SYNTAX
- UnsupportedConstraintType VerifyResult = C.X509_V_ERR_UNSUPPORTED_CONSTRAINT_TYPE
- UnsupportedExtensionFeature VerifyResult = C.X509_V_ERR_UNSUPPORTED_EXTENSION_FEATURE
- ExcludedViolation VerifyResult = C.X509_V_ERR_EXCLUDED_VIOLATION
- SubtreeMinmax VerifyResult = C.X509_V_ERR_SUBTREE_MINMAX
- UnsupportedNameSyntax VerifyResult = C.X509_V_ERR_UNSUPPORTED_NAME_SYNTAX
- DifferentCrlScope VerifyResult = C.X509_V_ERR_DIFFERENT_CRL_SCOPE
- PermittedViolation VerifyResult = C.X509_V_ERR_PERMITTED_VIOLATION
- CrlPathValidationError VerifyResult = C.X509_V_ERR_CRL_PATH_VALIDATION_ERROR
-)
-
-const (
- NoTLSv1_1 Options = C.SSL_OP_NO_TLSv1_1
- NoTLSv1_2 Options = C.SSL_OP_NO_TLSv1_2
-)
diff --git a/vendor/src/github.com/spacemonkeygo/openssl/sni.c b/vendor/src/github.com/spacemonkeygo/openssl/sni.c
new file mode 100644
index 00000000000..5398da869b8
--- /dev/null
+++ b/vendor/src/github.com/spacemonkeygo/openssl/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 <openssl/ssl.h>
+#include "_cgo_export.h"
+#include <stdio.h>
+
+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/vendor/src/github.com/spacemonkeygo/openssl/sni_test.go b/vendor/src/github.com/spacemonkeygo/openssl/sni_test.go
new file mode 100644
index 00000000000..ee3b1a8bbaf
--- /dev/null
+++ b/vendor/src/github.com/spacemonkeygo/openssl/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/vendor/src/github.com/spacemonkeygo/openssl/ssl.go b/vendor/src/github.com/spacemonkeygo/openssl/ssl.go
new file mode 100644
index 00000000000..d6120e15d99
--- /dev/null
+++ b/vendor/src/github.com/spacemonkeygo/openssl/ssl.go
@@ -0,0 +1,167 @@
+// 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 <openssl/crypto.h>
+#include <openssl/ssl.h>
+#include <openssl/err.h>
+#include <openssl/conf.h>
+
+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);
+*/
+import "C"
+
+import (
+ "os"
+ "unsafe"
+)
+
+type SSLTLSExtErr int
+
+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
+}
+
+// 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))
+}
+
+//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))
+}
diff --git a/vendor/src/github.com/spacemonkeygo/openssl/verify.c b/vendor/src/github.com/spacemonkeygo/openssl/verify.c
index bfc626812cd..d55866c4cf0 100644
--- a/vendor/src/github.com/spacemonkeygo/openssl/verify.c
+++ b/vendor/src/github.com/spacemonkeygo/openssl/verify.c
@@ -14,12 +14,18 @@
#include <openssl/ssl.h>
#include "_cgo_export.h"
-#include <stdio.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_ctx = SSL_get_SSL_CTX(ssl);
+ 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);
+}