Address staticcheck issues

Fix `staticcheck` issues:
- S1028 use `fmt.Errorf` to construct formatted errors
- ST1017 yoda conditions
- ST1005 error message capitalization
- ST1006 avoid `self` as receiver name
- S1030 use `buf.String`
- S1011 avoid redundant loop when `append` suffices
- SA4006 unused value
- S1019 remove redundant capacity on `make` call
- SA2002 `t.Fatal` called outside of test

Exported error violates ST1012, which is ignored by this PR since rename may cause breaking changes.

Remove redundant parentheses wrapping, and use CamelCase naming while at it.
This commit is contained in:
Masih H. Derkani
2021-07-19 16:47:21 +01:00
parent 6f65c2c3af
commit 597b8983b0
20 changed files with 196 additions and 212 deletions

78
bio.go
View File

@@ -112,14 +112,14 @@ func writeBioPending(b *C.BIO) C.long {
return C.long(len(ptr.buf)) return C.long(len(ptr.buf))
} }
func (b *writeBio) WriteTo(w io.Writer) (rv int64, err error) { func (wb *writeBio) WriteTo(w io.Writer) (rv int64, err error) {
b.op_mtx.Lock() wb.op_mtx.Lock()
defer b.op_mtx.Unlock() defer wb.op_mtx.Unlock()
// write whatever data we currently have // write whatever data we currently have
b.data_mtx.Lock() wb.data_mtx.Lock()
data := b.buf data := wb.buf
b.data_mtx.Unlock() wb.data_mtx.Unlock()
if len(data) == 0 { if len(data) == 0 {
return 0, nil return 0, nil
@@ -127,26 +127,26 @@ func (b *writeBio) WriteTo(w io.Writer) (rv int64, err error) {
n, err := w.Write(data) n, err := w.Write(data)
// subtract however much data we wrote from the buffer // subtract however much data we wrote from the buffer
b.data_mtx.Lock() wb.data_mtx.Lock()
b.buf = b.buf[:copy(b.buf, b.buf[n:])] wb.buf = wb.buf[:copy(wb.buf, wb.buf[n:])]
if b.release_buffers && len(b.buf) == 0 { if wb.release_buffers && len(wb.buf) == 0 {
b.buf = nil wb.buf = nil
} }
b.data_mtx.Unlock() wb.data_mtx.Unlock()
return int64(n), err return int64(n), err
} }
func (self *writeBio) Disconnect(b *C.BIO) { func (wb *writeBio) Disconnect(b *C.BIO) {
if loadWritePtr(b) == self { if loadWritePtr(b) == wb {
writeBioMapping.Del(token(C.X_BIO_get_data(b))) writeBioMapping.Del(token(C.X_BIO_get_data(b)))
C.X_BIO_set_data(b, nil) C.X_BIO_set_data(b, nil)
} }
} }
func (b *writeBio) MakeCBIO() *C.BIO { func (wb *writeBio) MakeCBIO() *C.BIO {
rv := C.X_BIO_new_write_bio() rv := C.X_BIO_new_write_bio()
token := writeBioMapping.Add(unsafe.Pointer(b)) token := writeBioMapping.Add(unsafe.Pointer(wb))
C.X_BIO_set_data(rv, unsafe.Pointer(token)) C.X_BIO_set_data(rv, unsafe.Pointer(token))
return rv return rv
} }
@@ -228,53 +228,53 @@ func readBioPending(b *C.BIO) C.long {
return C.long(len(ptr.buf)) return C.long(len(ptr.buf))
} }
func (b *readBio) ReadFromOnce(r io.Reader) (n int, err error) { func (rb *readBio) ReadFromOnce(r io.Reader) (n int, err error) {
b.op_mtx.Lock() rb.op_mtx.Lock()
defer b.op_mtx.Unlock() defer rb.op_mtx.Unlock()
// make sure we have a destination that fits at least one SSL record // make sure we have a destination that fits at least one SSL record
b.data_mtx.Lock() rb.data_mtx.Lock()
if cap(b.buf) < len(b.buf)+SSLRecordSize { if cap(rb.buf) < len(rb.buf)+SSLRecordSize {
new_buf := make([]byte, len(b.buf), len(b.buf)+SSLRecordSize) new_buf := make([]byte, len(rb.buf), len(rb.buf)+SSLRecordSize)
copy(new_buf, b.buf) copy(new_buf, rb.buf)
b.buf = new_buf rb.buf = new_buf
} }
dst := b.buf[len(b.buf):cap(b.buf)] dst := rb.buf[len(rb.buf):cap(rb.buf)]
dst_slice := b.buf dst_slice := rb.buf
b.data_mtx.Unlock() rb.data_mtx.Unlock()
n, err = r.Read(dst) n, err = r.Read(dst)
b.data_mtx.Lock() rb.data_mtx.Lock()
defer b.data_mtx.Unlock() defer rb.data_mtx.Unlock()
if n > 0 { if n > 0 {
if len(dst_slice) != len(b.buf) { if len(dst_slice) != len(rb.buf) {
// someone shrunk the buffer, so we read in too far ahead and we // someone shrunk the buffer, so we read in too far ahead and we
// need to slide backwards // need to slide backwards
copy(b.buf[len(b.buf):len(b.buf)+n], dst) copy(rb.buf[len(rb.buf):len(rb.buf)+n], dst)
} }
b.buf = b.buf[:len(b.buf)+n] rb.buf = rb.buf[:len(rb.buf)+n]
} }
return n, err return n, err
} }
func (b *readBio) MakeCBIO() *C.BIO { func (rb *readBio) MakeCBIO() *C.BIO {
rv := C.X_BIO_new_read_bio() rv := C.X_BIO_new_read_bio()
token := readBioMapping.Add(unsafe.Pointer(b)) token := readBioMapping.Add(unsafe.Pointer(rb))
C.X_BIO_set_data(rv, unsafe.Pointer(token)) C.X_BIO_set_data(rv, unsafe.Pointer(token))
return rv return rv
} }
func (self *readBio) Disconnect(b *C.BIO) { func (rb *readBio) Disconnect(b *C.BIO) {
if loadReadPtr(b) == self { if loadReadPtr(b) == rb {
readBioMapping.Del(token(C.X_BIO_get_data(b))) readBioMapping.Del(token(C.X_BIO_get_data(b)))
C.X_BIO_set_data(b, nil) C.X_BIO_set_data(b, nil)
} }
} }
func (b *readBio) MarkEOF() { func (rb *readBio) MarkEOF() {
b.data_mtx.Lock() rb.data_mtx.Lock()
defer b.data_mtx.Unlock() defer rb.data_mtx.Unlock()
b.eof = true rb.eof = true
} }
type anyBio C.BIO type anyBio C.BIO

View File

@@ -267,8 +267,8 @@ func (c *Certificate) Sign(privKey PrivateKey, digest EVP_MD) error {
case EVP_SHA384: case EVP_SHA384:
case EVP_SHA512: case EVP_SHA512:
default: default:
return errors.New("Unsupported digest" + return errors.New("unsupported digest; " +
"You're probably looking for 'EVP_SHA256' or 'EVP_SHA512'.") "you're probably looking for 'EVP_SHA256' or 'EVP_SHA512'")
} }
return c.insecureSign(privKey, digest) return c.insecureSign(privKey, digest)
} }
@@ -336,7 +336,7 @@ func (c *Certificate) AddCustomExtension(nid NID, value []byte) error {
val := (*C.char)(C.CBytes(value)) val := (*C.char)(C.CBytes(value))
defer C.free(unsafe.Pointer(val)) defer C.free(unsafe.Pointer(val))
if int(C.add_custom_ext(c.x, C.int(nid), val, C.int(len(value)))) == 0 { if int(C.add_custom_ext(c.x, C.int(nid), val, C.int(len(value)))) == 0 {
return errors.New("Unable to add extension") return errors.New("unable to add extension")
} }
return nil return nil
} }

View File

@@ -125,7 +125,7 @@ func (ctx *cipherCtx) applyKeyAndIV(key, iv []byte) error {
} else { } else {
res = C.EVP_DecryptInit_ex(ctx.ctx, nil, nil, kptr, iptr) res = C.EVP_DecryptInit_ex(ctx.ctx, nil, nil, kptr, iptr)
} }
if 1 != res { if res != 1 {
return errors.New("failed to apply key/IV") return errors.New("failed to apply key/IV")
} }
} }
@@ -243,7 +243,7 @@ func newEncryptionCipherCtx(c *Cipher, e *Engine, key, iv []byte) (
if e != nil { if e != nil {
eptr = e.e eptr = e.e
} }
if 1 != C.EVP_EncryptInit_ex(ctx.ctx, c.ptr, eptr, nil, nil) { if C.EVP_EncryptInit_ex(ctx.ctx, c.ptr, eptr, nil, nil) != 1 {
return nil, errors.New("failed to initialize cipher context") return nil, errors.New("failed to initialize cipher context")
} }
err = ctx.applyKeyAndIV(key, iv) err = ctx.applyKeyAndIV(key, iv)
@@ -266,7 +266,7 @@ func newDecryptionCipherCtx(c *Cipher, e *Engine, key, iv []byte) (
if e != nil { if e != nil {
eptr = e.e eptr = e.e
} }
if 1 != C.EVP_DecryptInit_ex(ctx.ctx, c.ptr, eptr, nil, nil) { if C.EVP_DecryptInit_ex(ctx.ctx, c.ptr, eptr, nil, nil) != 1 {
return nil, errors.New("failed to initialize cipher context") return nil, errors.New("failed to initialize cipher context")
} }
err = ctx.applyKeyAndIV(key, iv) err = ctx.applyKeyAndIV(key, iv)
@@ -317,7 +317,7 @@ func (ctx *decryptionCipherCtx) DecryptUpdate(input []byte) ([]byte, error) {
func (ctx *encryptionCipherCtx) EncryptFinal() ([]byte, error) { func (ctx *encryptionCipherCtx) EncryptFinal() ([]byte, error) {
outbuf := make([]byte, ctx.BlockSize()) outbuf := make([]byte, ctx.BlockSize())
var outlen C.int var outlen C.int
if 1 != C.EVP_EncryptFinal_ex(ctx.ctx, (*C.uchar)(&outbuf[0]), &outlen) { if C.EVP_EncryptFinal_ex(ctx.ctx, (*C.uchar)(&outbuf[0]), &outlen) != 1 {
return nil, errors.New("encryption failed") return nil, errors.New("encryption failed")
} }
return outbuf[:outlen], nil return outbuf[:outlen], nil
@@ -326,7 +326,7 @@ func (ctx *encryptionCipherCtx) EncryptFinal() ([]byte, error) {
func (ctx *decryptionCipherCtx) DecryptFinal() ([]byte, error) { func (ctx *decryptionCipherCtx) DecryptFinal() ([]byte, error) {
outbuf := make([]byte, ctx.BlockSize()) outbuf := make([]byte, ctx.BlockSize())
var outlen C.int var outlen C.int
if 1 != C.EVP_DecryptFinal_ex(ctx.ctx, (*C.uchar)(&outbuf[0]), &outlen) { if C.EVP_DecryptFinal_ex(ctx.ctx, (*C.uchar)(&outbuf[0]), &outlen) != 1 {
// this may mean the tag failed to verify- all previous plaintext // this may mean the tag failed to verify- all previous plaintext
// returned must be considered faked and invalid // returned must be considered faked and invalid
return nil, errors.New("decryption failed") return nil, errors.New("decryption failed")

View File

@@ -86,8 +86,8 @@ func NewGCMEncryptionCipherCtx(blocksize int, e *Engine, key, iv []byte) (
return nil, fmt.Errorf("could not set IV len to %d: %s", return nil, fmt.Errorf("could not set IV len to %d: %s",
len(iv), err) len(iv), err)
} }
if 1 != C.EVP_EncryptInit_ex(ctx.ctx, nil, nil, nil, if C.EVP_EncryptInit_ex(ctx.ctx, nil, nil, nil,
(*C.uchar)(&iv[0])) { (*C.uchar)(&iv[0])) != 1 {
return nil, errors.New("failed to apply IV") return nil, errors.New("failed to apply IV")
} }
} }
@@ -110,8 +110,8 @@ func NewGCMDecryptionCipherCtx(blocksize int, e *Engine, key, iv []byte) (
return nil, fmt.Errorf("could not set IV len to %d: %s", return nil, fmt.Errorf("could not set IV len to %d: %s",
len(iv), err) len(iv), err)
} }
if 1 != C.EVP_DecryptInit_ex(ctx.ctx, nil, nil, nil, if C.EVP_DecryptInit_ex(ctx.ctx, nil, nil, nil,
(*C.uchar)(&iv[0])) { (*C.uchar)(&iv[0])) != 1 {
return nil, errors.New("failed to apply IV") return nil, errors.New("failed to apply IV")
} }
} }
@@ -123,8 +123,8 @@ func (ctx *authEncryptionCipherCtx) ExtraData(aad []byte) error {
return nil return nil
} }
var outlen C.int var outlen C.int
if 1 != C.EVP_EncryptUpdate(ctx.ctx, nil, &outlen, (*C.uchar)(&aad[0]), if C.EVP_EncryptUpdate(ctx.ctx, nil, &outlen, (*C.uchar)(&aad[0]),
C.int(len(aad))) { C.int(len(aad))) != 1 {
return errors.New("failed to add additional authenticated data") return errors.New("failed to add additional authenticated data")
} }
return nil return nil
@@ -135,8 +135,8 @@ func (ctx *authDecryptionCipherCtx) ExtraData(aad []byte) error {
return nil return nil
} }
var outlen C.int var outlen C.int
if 1 != C.EVP_DecryptUpdate(ctx.ctx, nil, &outlen, (*C.uchar)(&aad[0]), if C.EVP_DecryptUpdate(ctx.ctx, nil, &outlen, (*C.uchar)(&aad[0]),
C.int(len(aad))) { C.int(len(aad))) != 1 {
return errors.New("failed to add additional authenticated data") return errors.New("failed to add additional authenticated data")
} }
return nil return nil

View File

@@ -185,17 +185,16 @@ func TestBadTag(t *testing.T) {
} }
// flip the last bit // flip the last bit
tag[len(tag)-1] ^= 1 tag[len(tag)-1] ^= 1
plaintext_out, err := doDecryption(key, iv, nil, ciphertext, tag, 128, 129) if _, err := doDecryption(key, iv, nil, ciphertext, tag, 128, 129); err == nil {
if err == nil {
t.Fatal("Expected error for bad tag, but got none") t.Fatal("Expected error for bad tag, but got none")
} }
// flip it back, try again just to make sure // flip it back, try again just to make sure
tag[len(tag)-1] ^= 1 tag[len(tag)-1] ^= 1
plaintext_out, err = doDecryption(key, iv, nil, ciphertext, tag, 128, 129) plaintextOut, err := doDecryption(key, iv, nil, ciphertext, tag, 128, 129)
if err != nil { if err != nil {
t.Fatal("Decryption failure:", err) t.Fatal("Decryption failure:", err)
} }
checkEqual(t, plaintext_out, plaintext) checkEqual(t, plaintextOut, plaintext)
} }
func TestBadCiphertext(t *testing.T) { func TestBadCiphertext(t *testing.T) {
@@ -211,17 +210,16 @@ func TestBadCiphertext(t *testing.T) {
} }
// flip the last bit // flip the last bit
ciphertext[len(ciphertext)-1] ^= 1 ciphertext[len(ciphertext)-1] ^= 1
plaintext_out, err := doDecryption(key, iv, aad, ciphertext, tag, 192, 192) if _, err := doDecryption(key, iv, aad, ciphertext, tag, 192, 192); err == nil {
if err == nil {
t.Fatal("Expected error for bad ciphertext, but got none") t.Fatal("Expected error for bad ciphertext, but got none")
} }
// flip it back, try again just to make sure // flip it back, try again just to make sure
ciphertext[len(ciphertext)-1] ^= 1 ciphertext[len(ciphertext)-1] ^= 1
plaintext_out, err = doDecryption(key, iv, aad, ciphertext, tag, 192, 192) plaintextOut, err := doDecryption(key, iv, aad, ciphertext, tag, 192, 192)
if err != nil { if err != nil {
t.Fatal("Decryption failure:", err) t.Fatal("Decryption failure:", err)
} }
checkEqual(t, plaintext_out, plaintext) checkEqual(t, plaintextOut, plaintext)
} }
func TestBadAAD(t *testing.T) { func TestBadAAD(t *testing.T) {
@@ -237,17 +235,16 @@ func TestBadAAD(t *testing.T) {
} }
// flip the last bit // flip the last bit
aad[len(aad)-1] ^= 1 aad[len(aad)-1] ^= 1
plaintext_out, err := doDecryption(key, iv, aad, ciphertext, tag, 256, 256) if _, err := doDecryption(key, iv, aad, ciphertext, tag, 256, 256); err == nil {
if err == nil {
t.Fatal("Expected error for bad AAD, but got none") t.Fatal("Expected error for bad AAD, but got none")
} }
// flip it back, try again just to make sure // flip it back, try again just to make sure
aad[len(aad)-1] ^= 1 aad[len(aad)-1] ^= 1
plaintext_out, err = doDecryption(key, iv, aad, ciphertext, tag, 256, 256) plaintextOut, err := doDecryption(key, iv, aad, ciphertext, tag, 256, 256)
if err != nil { if err != nil {
t.Fatal("Decryption failure:", err) t.Fatal("Decryption failure:", err)
} }
checkEqual(t, plaintext_out, plaintext) checkEqual(t, plaintextOut, plaintext)
} }
func TestNonAuthenticatedEncryption(t *testing.T) { func TestNonAuthenticatedEncryption(t *testing.T) {

32
conn.go
View File

@@ -31,10 +31,10 @@ import (
) )
var ( var (
zeroReturn = errors.New("zero return") errZeroReturn = errors.New("zero return")
wantRead = errors.New("want read") errWantRead = errors.New("want read")
wantWrite = errors.New("want write") errWantWrite = errors.New("want write")
tryAgain = errors.New("try again") errTryAgain = errors.New("try again")
) )
type Conn struct { type Conn struct {
@@ -192,7 +192,7 @@ func (c *Conn) GetCtx() *Ctx { return c.ctx }
func (c *Conn) CurrentCipher() (string, error) { func (c *Conn) CurrentCipher() (string, error) {
p := C.X_SSL_get_cipher_name(c.ssl) p := C.X_SSL_get_cipher_name(c.ssl)
if p == nil { if p == nil {
return "", errors.New("Session not established") return "", errors.New("session not established")
} }
return C.GoString(p), nil return C.GoString(p), nil
@@ -247,7 +247,7 @@ func (c *Conn) getErrorHandler(rv C.int, errno error) func() error {
if err != nil { if err != nil {
return err return err
} }
return tryAgain return errTryAgain
} }
case C.SSL_ERROR_WANT_WRITE: case C.SSL_ERROR_WANT_WRITE:
return func() error { return func() error {
@@ -255,7 +255,7 @@ func (c *Conn) getErrorHandler(rv C.int, errno error) func() error {
if err != nil { if err != nil {
return err return err
} }
return tryAgain return errTryAgain
} }
case C.SSL_ERROR_SYSCALL: case C.SSL_ERROR_SYSCALL:
var err error var err error
@@ -303,8 +303,8 @@ func (c *Conn) handshake() func() error {
// Handshake performs an SSL handshake. If a handshake is not manually // Handshake performs an SSL handshake. If a handshake is not manually
// triggered, it will run before the first I/O on the encrypted stream. // triggered, it will run before the first I/O on the encrypted stream.
func (c *Conn) Handshake() error { func (c *Conn) Handshake() error {
err := tryAgain err := errTryAgain
for err == tryAgain { for err == errTryAgain {
err = c.handleError(c.handshake()) err = c.handleError(c.handshake())
} }
go c.flushOutputBuffer() go c.flushOutputBuffer()
@@ -404,15 +404,15 @@ func (c *Conn) shutdown() func() error {
} }
func (c *Conn) shutdownLoop() error { func (c *Conn) shutdownLoop() error {
err := tryAgain err := errTryAgain
shutdown_tries := 0 shutdown_tries := 0
for err == tryAgain { for err == errTryAgain {
shutdown_tries = shutdown_tries + 1 shutdown_tries = shutdown_tries + 1
err = c.handleError(c.shutdown()) err = c.handleError(c.shutdown())
if err == nil { if err == nil {
return c.flushOutputBuffer() return c.flushOutputBuffer()
} }
if err == tryAgain && shutdown_tries >= 2 { if err == errTryAgain && shutdown_tries >= 2 {
return errors.New("shutdown requested a third time?") return errors.New("shutdown requested a third time?")
} }
} }
@@ -463,8 +463,8 @@ func (c *Conn) Read(b []byte) (n int, err error) {
if len(b) == 0 { if len(b) == 0 {
return 0, nil return 0, nil
} }
err = tryAgain err = errTryAgain
for err == tryAgain { for err == errTryAgain {
n, errcb := c.read(b) n, errcb := c.read(b)
err = c.handleError(errcb) err = c.handleError(errcb)
if err == nil { if err == nil {
@@ -504,8 +504,8 @@ func (c *Conn) Write(b []byte) (written int, err error) {
if len(b) == 0 { if len(b) == 0 {
return 0, nil return 0, nil
} }
err = tryAgain err = errTryAgain
for err == tryAgain { for err == errTryAgain {
n, errcb := c.write(b) n, errcb := c.write(b)
err = c.handleError(errcb) err = c.handleError(errcb)
if err == nil { if err == nil {

28
ctx.go
View File

@@ -127,7 +127,7 @@ func NewCtxFromFiles(cert_file string, key_file string) (*Ctx, error) {
certs := SplitPEM(cert_bytes) certs := SplitPEM(cert_bytes)
if len(certs) == 0 { if len(certs) == 0 {
return nil, fmt.Errorf("No PEM certificate found in '%s'", cert_file) return nil, fmt.Errorf("no PEM certificate found in '%s'", cert_file)
} }
first, certs := certs[0], certs[1:] first, certs := certs[0], certs[1:]
cert, err := LoadCertificateFromPEM(first) cert, err := LoadCertificateFromPEM(first)
@@ -190,7 +190,7 @@ func (c *Ctx) SetEllipticCurve(curve EllipticCurve) error {
k := C.EC_KEY_new_by_curve_name(C.int(curve)) k := C.EC_KEY_new_by_curve_name(C.int(curve))
if k == nil { if k == nil {
return errors.New("Unknown curve") return errors.New("unknown curve")
} }
defer C.EC_KEY_free(k) defer C.EC_KEY_free(k)
@@ -302,12 +302,12 @@ type CertificateStoreCtx struct {
ssl_ctx *Ctx ssl_ctx *Ctx
} }
func (self *CertificateStoreCtx) VerifyResult() VerifyResult { func (csc *CertificateStoreCtx) VerifyResult() VerifyResult {
return VerifyResult(C.X509_STORE_CTX_get_error(self.ctx)) return VerifyResult(C.X509_STORE_CTX_get_error(csc.ctx))
} }
func (self *CertificateStoreCtx) Err() error { func (csc *CertificateStoreCtx) Err() error {
code := C.X509_STORE_CTX_get_error(self.ctx) code := C.X509_STORE_CTX_get_error(csc.ctx)
if code == C.X509_V_OK { if code == C.X509_V_OK {
return nil return nil
} }
@@ -315,19 +315,19 @@ func (self *CertificateStoreCtx) Err() error {
C.GoString(C.X509_verify_cert_error_string(C.long(code)))) C.GoString(C.X509_verify_cert_error_string(C.long(code))))
} }
func (self *CertificateStoreCtx) Depth() int { func (csc *CertificateStoreCtx) Depth() int {
return int(C.X509_STORE_CTX_get_error_depth(self.ctx)) return int(C.X509_STORE_CTX_get_error_depth(csc.ctx))
} }
// the certicate returned is only valid for the lifetime of the underlying // the certificate returned is only valid for the lifetime of the underlying
// X509_STORE_CTX // X509_STORE_CTX
func (self *CertificateStoreCtx) GetCurrentCert() *Certificate { func (csc *CertificateStoreCtx) GetCurrentCert() *Certificate {
x509 := C.X509_STORE_CTX_get_current_cert(self.ctx) x509 := C.X509_STORE_CTX_get_current_cert(csc.ctx)
if x509 == nil { if x509 == nil {
return nil return nil
} }
// add a ref // add a ref
if 1 != C.X_X509_add_ref(x509) { if C.X_X509_add_ref(x509) != 1 {
return nil return nil
} }
cert := &Certificate{ cert := &Certificate{
@@ -531,7 +531,7 @@ func (c *Ctx) SetNextProtos(protos []string) error {
for _, proto := range protos { for _, proto := range protos {
if len(proto) > 255 { if len(proto) > 255 {
return fmt.Errorf( return fmt.Errorf(
"Proto length can't be more than 255. But got a proto %s with length %d", "proto length can't be more than 255. But got a proto %s with length %d",
proto, len(proto)) proto, len(proto))
} }
vector = append(vector, byte(uint8(len(proto)))) vector = append(vector, byte(uint8(len(proto))))
@@ -540,7 +540,7 @@ func (c *Ctx) SetNextProtos(protos []string) error {
ret := int(C.SSL_CTX_set_alpn_protos(c.ctx, (*C.uchar)(unsafe.Pointer(&vector[0])), ret := int(C.SSL_CTX_set_alpn_protos(c.ctx, (*C.uchar)(unsafe.Pointer(&vector[0])),
C.uint(len(vector)))) C.uint(len(vector))))
if ret != 0 { if ret != 0 {
return errors.New("Error while setting protos to ctx") return errors.New("error while setting protos to ctx")
} }
return nil return nil
} }

View File

@@ -40,7 +40,7 @@ func TestECDH(t *testing.T) {
t.Fatal(err) t.Fatal(err)
} }
if bytes.Compare(mySecret, theirSecret) != 0 { if !bytes.Equal(mySecret, theirSecret) {
t.Fatal("shared secrets are different") t.Fatal("shared secrets are different")
} }
} }

View File

@@ -74,7 +74,7 @@ func (h *HMAC) Write(data []byte) (n int, err error) {
} }
func (h *HMAC) Reset() error { func (h *HMAC) Reset() error {
if 1 != C.X_HMAC_Init_ex(h.ctx, nil, 0, nil, nil) { if C.X_HMAC_Init_ex(h.ctx, nil, 0, nil, nil) != 1 {
return errors.New("failed to reset HMAC_CTX") return errors.New("failed to reset HMAC_CTX")
} }
return nil return nil

View File

@@ -40,7 +40,7 @@ import (
) )
var ( var (
ValidationError = errors.New("Host validation error") ValidationError = errors.New("host validation error") //lint:ignore ST1012 rename may cause breaking changes; research before renaming.
) )
type CheckFlags int type CheckFlags int

View File

@@ -88,14 +88,13 @@ package openssl
import "C" import "C"
import ( import (
"errors"
"fmt" "fmt"
"strings" "strings"
) )
func init() { func init() {
if rc := C.X_shim_init(); rc != 0 { if rc := C.X_shim_init(); rc != 0 {
panic(fmt.Errorf("X_shim_init failed with %d", rc)) panic(fmt.Errorf("x_shim_init failed with %d", rc))
} }
} }
@@ -113,5 +112,5 @@ func errorFromErrorQueue() error {
C.GoString(C.ERR_func_error_string(err)), C.GoString(C.ERR_func_error_string(err)),
C.GoString(C.ERR_reason_error_string(err)))) C.GoString(C.ERR_reason_error_string(err))))
} }
return errors.New(fmt.Sprintf("SSL errors: %s", strings.Join(errs, "\n"))) return fmt.Errorf("SSL errors: %s", strings.Join(errs, "\n"))
} }

38
key.go
View File

@@ -143,36 +143,36 @@ func (key *pKey) SignPKCS1v15(method Method, data []byte) ([]byte, error) {
return nil, errors.New("signpkcs1v15: 0-length data or non-null digest") return nil, errors.New("signpkcs1v15: 0-length data or non-null digest")
} }
if 1 != C.X_EVP_DigestSignInit(ctx, nil, nil, nil, key.key) { if C.X_EVP_DigestSignInit(ctx, nil, nil, nil, key.key) != 1 {
return nil, errors.New("signpkcs1v15: failed to init signature") return nil, errors.New("signpkcs1v15: failed to init signature")
} }
// evp signatures are 64 bytes // evp signatures are 64 bytes
sig := make([]byte, 64, 64) sig := make([]byte, 64)
var sigblen C.size_t = 64 var sigblen C.size_t = 64
if 1 != C.X_EVP_DigestSign(ctx, if C.X_EVP_DigestSign(ctx,
((*C.uchar)(unsafe.Pointer(&sig[0]))), (*C.uchar)(unsafe.Pointer(&sig[0])),
&sigblen, &sigblen,
(*C.uchar)(unsafe.Pointer(&data[0])), (*C.uchar)(unsafe.Pointer(&data[0])),
C.size_t(len(data))) { C.size_t(len(data))) != 1 {
return nil, errors.New("signpkcs1v15: failed to do one-shot signature") return nil, errors.New("signpkcs1v15: failed to do one-shot signature")
} }
return sig[:sigblen], nil return sig[:sigblen], nil
} else { } else {
if 1 != C.X_EVP_SignInit(ctx, method) { if C.X_EVP_SignInit(ctx, method) != 1 {
return nil, errors.New("signpkcs1v15: failed to init signature") return nil, errors.New("signpkcs1v15: failed to init signature")
} }
if len(data) > 0 { if len(data) > 0 {
if 1 != C.X_EVP_SignUpdate( if C.X_EVP_SignUpdate(
ctx, unsafe.Pointer(&data[0]), C.uint(len(data))) { ctx, unsafe.Pointer(&data[0]), C.uint(len(data))) != 1 {
return nil, errors.New("signpkcs1v15: failed to update signature") return nil, errors.New("signpkcs1v15: failed to update signature")
} }
} }
sig := make([]byte, C.X_EVP_PKEY_size(key.key)) sig := make([]byte, C.X_EVP_PKEY_size(key.key))
var sigblen C.uint var sigblen C.uint
if 1 != C.X_EVP_SignFinal(ctx, if C.X_EVP_SignFinal(ctx,
((*C.uchar)(unsafe.Pointer(&sig[0]))), &sigblen, key.key) { (*C.uchar)(unsafe.Pointer(&sig[0])), &sigblen, key.key) != 1 {
return nil, errors.New("signpkcs1v15: failed to finalize signature") return nil, errors.New("signpkcs1v15: failed to finalize signature")
} }
return sig[:sigblen], nil return sig[:sigblen], nil
@@ -194,32 +194,32 @@ func (key *pKey) VerifyPKCS1v15(method Method, data, sig []byte) error {
return errors.New("verifypkcs1v15: 0-length data or non-null digest") return errors.New("verifypkcs1v15: 0-length data or non-null digest")
} }
if 1 != C.X_EVP_DigestVerifyInit(ctx, nil, nil, nil, key.key) { if C.X_EVP_DigestVerifyInit(ctx, nil, nil, nil, key.key) != 1 {
return errors.New("verifypkcs1v15: failed to init verify") return errors.New("verifypkcs1v15: failed to init verify")
} }
if 1 != C.X_EVP_DigestVerify(ctx, if C.X_EVP_DigestVerify(ctx,
((*C.uchar)(unsafe.Pointer(&sig[0]))), (*C.uchar)(unsafe.Pointer(&sig[0])),
C.size_t(len(sig)), C.size_t(len(sig)),
(*C.uchar)(unsafe.Pointer(&data[0])), (*C.uchar)(unsafe.Pointer(&data[0])),
C.size_t(len(data))) { C.size_t(len(data))) != 1 {
return errors.New("verifypkcs1v15: failed to do one-shot verify") return errors.New("verifypkcs1v15: failed to do one-shot verify")
} }
return nil return nil
} else { } else {
if 1 != C.X_EVP_VerifyInit(ctx, method) { if C.X_EVP_VerifyInit(ctx, method) != 1 {
return errors.New("verifypkcs1v15: failed to init verify") return errors.New("verifypkcs1v15: failed to init verify")
} }
if len(data) > 0 { if len(data) > 0 {
if 1 != C.X_EVP_VerifyUpdate( if C.X_EVP_VerifyUpdate(
ctx, unsafe.Pointer(&data[0]), C.uint(len(data))) { ctx, unsafe.Pointer(&data[0]), C.uint(len(data))) != 1 {
return errors.New("verifypkcs1v15: failed to update verify") return errors.New("verifypkcs1v15: failed to update verify")
} }
} }
if 1 != C.X_EVP_VerifyFinal(ctx, if C.X_EVP_VerifyFinal(ctx,
((*C.uchar)(unsafe.Pointer(&sig[0]))), C.uint(len(sig)), key.key) { (*C.uchar)(unsafe.Pointer(&sig[0])), C.uint(len(sig)), key.key) != 1 {
return errors.New("verifypkcs1v15: failed to finalize verify") return errors.New("verifypkcs1v15: failed to finalize verify")
} }
return nil return nil

View File

@@ -187,12 +187,10 @@ func TestGenerateEd25519(t *testing.T) {
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
_, err = key.MarshalPKIXPublicKeyPEM() if _, err = key.MarshalPKIXPublicKeyPEM(); err != nil {
if err != nil {
t.Fatal(err) t.Fatal(err)
} }
_, err = key.MarshalPKCS1PrivateKeyPEM() if _, err = key.MarshalPKCS1PrivateKeyPEM(); err != nil {
if err != nil {
t.Fatal(err) t.Fatal(err)
} }
} }
@@ -289,8 +287,7 @@ func TestSignED25519(t *testing.T) {
} }
func TestMarshalEC(t *testing.T) { func TestMarshalEC(t *testing.T) {
key, err := LoadPrivateKeyFromPEM(prime256v1KeyBytes) if _, err := LoadPrivateKeyFromPEM(prime256v1KeyBytes); err != nil {
if err != nil {
t.Fatal(err) t.Fatal(err)
} }
cert, err := LoadCertificateFromPEM(prime256v1CertBytes) cert, err := LoadCertificateFromPEM(prime256v1CertBytes)
@@ -299,7 +296,7 @@ func TestMarshalEC(t *testing.T) {
} }
privateBlock, _ := pem_pkg.Decode(prime256v1KeyBytes) privateBlock, _ := pem_pkg.Decode(prime256v1KeyBytes)
key, err = LoadPrivateKeyFromDER(privateBlock.Bytes) key, err := LoadPrivateKeyFromDER(privateBlock.Bytes)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
@@ -410,8 +407,7 @@ func TestMarshalEd25519(t *testing.T) {
t.SkipNow() t.SkipNow()
} }
key, err := LoadPrivateKeyFromPEM(ed25519KeyBytes) if _, err := LoadPrivateKeyFromPEM(ed25519KeyBytes); err != nil {
if err != nil {
t.Fatal(err) t.Fatal(err)
} }
cert, err := LoadCertificateFromPEM(ed25519CertBytes) cert, err := LoadCertificateFromPEM(ed25519CertBytes)
@@ -420,7 +416,7 @@ func TestMarshalEd25519(t *testing.T) {
} }
privateBlock, _ := pem_pkg.Decode(ed25519KeyBytes) privateBlock, _ := pem_pkg.Decode(ed25519KeyBytes)
key, err = LoadPrivateKeyFromDER(privateBlock.Bytes) key, err := LoadPrivateKeyFromDER(privateBlock.Bytes)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
@@ -435,17 +431,15 @@ func TestMarshalEd25519(t *testing.T) {
t.Fatal("invalid cert pem bytes") t.Fatal("invalid cert pem bytes")
} }
pem, err = key.MarshalPKCS1PrivateKeyPEM() if _, err = key.MarshalPKCS1PrivateKeyPEM(); err != nil {
if err != nil {
t.Fatal(err) t.Fatal(err)
} }
der, err := key.MarshalPKCS1PrivateKeyDER() if _, err := key.MarshalPKCS1PrivateKeyDER(); err != nil {
if err != nil {
t.Fatal(err) t.Fatal(err)
} }
der, err = key.MarshalPKIXPublicKeyDER() der, err := key.MarshalPKIXPublicKeyDER()
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
@@ -455,22 +449,22 @@ func TestMarshalEd25519(t *testing.T) {
t.Fatal(err) t.Fatal(err)
} }
loaded_pubkey_from_pem, err := LoadPublicKeyFromPEM(pem) loadedPubkeyFromPem, err := LoadPublicKeyFromPEM(pem)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
loaded_pubkey_from_der, err := LoadPublicKeyFromDER(der) loadedPubkeyFromDer, err := LoadPublicKeyFromDER(der)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
_, err = loaded_pubkey_from_pem.MarshalPKIXPublicKeyDER() _, err = loadedPubkeyFromPem.MarshalPKIXPublicKeyDER()
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
_, err = loaded_pubkey_from_der.MarshalPKIXPublicKeyDER() _, err = loadedPubkeyFromDer.MarshalPKIXPublicKeyDER()
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }

10
md4.go
View File

@@ -51,7 +51,7 @@ func (s *MD4Hash) Close() {
} }
func (s *MD4Hash) Reset() error { func (s *MD4Hash) Reset() error {
if 1 != C.X_EVP_DigestInit_ex(s.ctx, C.X_EVP_md4(), engineRef(s.engine)) { if C.X_EVP_DigestInit_ex(s.ctx, C.X_EVP_md4(), engineRef(s.engine)) != 1 {
return errors.New("openssl: md4: cannot init digest ctx") return errors.New("openssl: md4: cannot init digest ctx")
} }
return nil return nil
@@ -61,16 +61,16 @@ func (s *MD4Hash) Write(p []byte) (n int, err error) {
if len(p) == 0 { if len(p) == 0 {
return 0, nil return 0, nil
} }
if 1 != C.X_EVP_DigestUpdate(s.ctx, unsafe.Pointer(&p[0]), if C.X_EVP_DigestUpdate(s.ctx, unsafe.Pointer(&p[0]),
C.size_t(len(p))) { C.size_t(len(p))) != 1 {
return 0, errors.New("openssl: md4: cannot update digest") return 0, errors.New("openssl: md4: cannot update digest")
} }
return len(p), nil return len(p), nil
} }
func (s *MD4Hash) Sum() (result [16]byte, err error) { func (s *MD4Hash) Sum() (result [16]byte, err error) {
if 1 != C.X_EVP_DigestFinal_ex(s.ctx, if C.X_EVP_DigestFinal_ex(s.ctx,
(*C.uchar)(unsafe.Pointer(&result[0])), nil) { (*C.uchar)(unsafe.Pointer(&result[0])), nil) != 1 {
return result, errors.New("openssl: md4: cannot finalize ctx") return result, errors.New("openssl: md4: cannot finalize ctx")
} }
return result, s.Reset() return result, s.Reset()

10
md5.go
View File

@@ -51,7 +51,7 @@ func (s *MD5Hash) Close() {
} }
func (s *MD5Hash) Reset() error { func (s *MD5Hash) Reset() error {
if 1 != C.X_EVP_DigestInit_ex(s.ctx, C.X_EVP_md5(), engineRef(s.engine)) { if C.X_EVP_DigestInit_ex(s.ctx, C.X_EVP_md5(), engineRef(s.engine)) != 1 {
return errors.New("openssl: md5: cannot init digest ctx") return errors.New("openssl: md5: cannot init digest ctx")
} }
return nil return nil
@@ -61,16 +61,16 @@ func (s *MD5Hash) Write(p []byte) (n int, err error) {
if len(p) == 0 { if len(p) == 0 {
return 0, nil return 0, nil
} }
if 1 != C.X_EVP_DigestUpdate(s.ctx, unsafe.Pointer(&p[0]), if C.X_EVP_DigestUpdate(s.ctx, unsafe.Pointer(&p[0]),
C.size_t(len(p))) { C.size_t(len(p))) != 1 {
return 0, errors.New("openssl: md5: cannot update digest") return 0, errors.New("openssl: md5: cannot update digest")
} }
return len(p), nil return len(p), nil
} }
func (s *MD5Hash) Sum() (result [16]byte, err error) { func (s *MD5Hash) Sum() (result [16]byte, err error) {
if 1 != C.X_EVP_DigestFinal_ex(s.ctx, if C.X_EVP_DigestFinal_ex(s.ctx,
(*C.uchar)(unsafe.Pointer(&result[0])), nil) { (*C.uchar)(unsafe.Pointer(&result[0])), nil) != 1 {
return result, errors.New("openssl: md5: cannot finalize ctx") return result, errors.New("openssl: md5: cannot finalize ctx")
} }
return result, s.Reset() return result, s.Reset()

7
pem.go
View File

@@ -16,7 +16,6 @@ package openssl
import ( import (
"regexp" "regexp"
) )
var pemSplit *regexp.Regexp = regexp.MustCompile(`(?sm)` + var pemSplit *regexp.Regexp = regexp.MustCompile(`(?sm)` +
@@ -25,9 +24,5 @@ var pemSplit *regexp.Regexp = regexp.MustCompile(`(?sm)` +
`^-----[\s-]*?END.*?-----[\s-]*?$)`) `^-----[\s-]*?END.*?-----[\s-]*?$)`)
func SplitPEM(data []byte) [][]byte { func SplitPEM(data []byte) [][]byte {
var results [][]byte return pemSplit.FindAll(data, -1)
for _, block := range pemSplit.FindAll(data, -1) {
results = append(results, block)
}
return results
} }

10
sha1.go
View File

@@ -58,7 +58,7 @@ func engineRef(e *Engine) *C.ENGINE {
} }
func (s *SHA1Hash) Reset() error { func (s *SHA1Hash) Reset() error {
if 1 != C.X_EVP_DigestInit_ex(s.ctx, C.X_EVP_sha1(), engineRef(s.engine)) { if C.X_EVP_DigestInit_ex(s.ctx, C.X_EVP_sha1(), engineRef(s.engine)) != 1 {
return errors.New("openssl: sha1: cannot init digest ctx") return errors.New("openssl: sha1: cannot init digest ctx")
} }
return nil return nil
@@ -68,16 +68,16 @@ func (s *SHA1Hash) Write(p []byte) (n int, err error) {
if len(p) == 0 { if len(p) == 0 {
return 0, nil return 0, nil
} }
if 1 != C.X_EVP_DigestUpdate(s.ctx, unsafe.Pointer(&p[0]), if C.X_EVP_DigestUpdate(s.ctx, unsafe.Pointer(&p[0]),
C.size_t(len(p))) { C.size_t(len(p))) != 1 {
return 0, errors.New("openssl: sha1: cannot update digest") return 0, errors.New("openssl: sha1: cannot update digest")
} }
return len(p), nil return len(p), nil
} }
func (s *SHA1Hash) Sum() (result [20]byte, err error) { func (s *SHA1Hash) Sum() (result [20]byte, err error) {
if 1 != C.X_EVP_DigestFinal_ex(s.ctx, if C.X_EVP_DigestFinal_ex(s.ctx,
(*C.uchar)(unsafe.Pointer(&result[0])), nil) { (*C.uchar)(unsafe.Pointer(&result[0])), nil) != 1 {
return result, errors.New("openssl: sha1: cannot finalize ctx") return result, errors.New("openssl: sha1: cannot finalize ctx")
} }
return result, s.Reset() return result, s.Reset()

View File

@@ -51,7 +51,7 @@ func (s *SHA256Hash) Close() {
} }
func (s *SHA256Hash) Reset() error { func (s *SHA256Hash) Reset() error {
if 1 != C.X_EVP_DigestInit_ex(s.ctx, C.X_EVP_sha256(), engineRef(s.engine)) { if C.X_EVP_DigestInit_ex(s.ctx, C.X_EVP_sha256(), engineRef(s.engine)) != 1 {
return errors.New("openssl: sha256: cannot init digest ctx") return errors.New("openssl: sha256: cannot init digest ctx")
} }
return nil return nil
@@ -61,16 +61,16 @@ func (s *SHA256Hash) Write(p []byte) (n int, err error) {
if len(p) == 0 { if len(p) == 0 {
return 0, nil return 0, nil
} }
if 1 != C.X_EVP_DigestUpdate(s.ctx, unsafe.Pointer(&p[0]), if C.X_EVP_DigestUpdate(s.ctx, unsafe.Pointer(&p[0]),
C.size_t(len(p))) { C.size_t(len(p))) != 1 {
return 0, errors.New("openssl: sha256: cannot update digest") return 0, errors.New("openssl: sha256: cannot update digest")
} }
return len(p), nil return len(p), nil
} }
func (s *SHA256Hash) Sum() (result [32]byte, err error) { func (s *SHA256Hash) Sum() (result [32]byte, err error) {
if 1 != C.X_EVP_DigestFinal_ex(s.ctx, if C.X_EVP_DigestFinal_ex(s.ctx,
(*C.uchar)(unsafe.Pointer(&result[0])), nil) { (*C.uchar)(unsafe.Pointer(&result[0])), nil) != 1 {
return result, errors.New("openssl: sha256: cannot finalize ctx") return result, errors.New("openssl: sha256: cannot finalize ctx")
} }
return result, s.Reset() return result, s.Reset()

View File

@@ -197,7 +197,7 @@ func SimpleConnTest(t testing.TB, constructor func(
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
if string(buf.Bytes()) != data { if buf.String() != data {
t.Fatal("mismatched data") t.Fatal("mismatched data")
} }
@@ -304,21 +304,21 @@ func ThroughputBenchmark(b *testing.B, constructor func(
wg.Add(2) wg.Add(2)
go func() { go func() {
defer wg.Done() defer wg.Done()
_, err = io.Copy(client, bytes.NewReader([]byte(data))) if _, err = io.Copy(client, bytes.NewReader(data)); err != nil {
if err != nil { b.Error(err)
b.Fatal(err) return
} }
}() }()
go func() { go func() {
defer wg.Done() defer wg.Done()
buf := &bytes.Buffer{} buf := &bytes.Buffer{}
_, err = io.CopyN(buf, server, int64(len(data))) if _, err = io.CopyN(buf, server, int64(len(data))); err != nil {
if err != nil { b.Error(err)
b.Fatal(err) return
} }
if !bytes.Equal(buf.Bytes(), data) { if !bytes.Equal(buf.Bytes(), data) {
b.Fatal("mismatched data") b.Error("mismatched data")
} }
}() }()
wg.Wait() wg.Wait()
@@ -551,27 +551,27 @@ func LotsOfConns(t *testing.T, payload_size int64, loops, clients int,
for { for {
conn, err := ssl_listener.Accept() conn, err := ssl_listener.Accept()
if err != nil { if err != nil {
t.Fatalf("failed accept: %s", err) t.Errorf("failed accept: %s", err)
continue continue
} }
go func() { go func() {
defer func() { defer func() {
err = conn.Close() err = conn.Close()
if err != nil { if err != nil {
t.Fatalf("failed closing: %s", err) t.Errorf("failed closing: %s", err)
} }
}() }()
for i := 0; i < loops; i++ { for i := 0; i < loops; i++ {
_, err := io.Copy(ioutil.Discard, _, err := io.Copy(ioutil.Discard,
io.LimitReader(conn, payload_size)) io.LimitReader(conn, payload_size))
if err != nil { if err != nil {
t.Fatalf("failed reading: %s", err) t.Errorf("failed reading: %s", err)
return return
} }
_, err = io.Copy(conn, io.LimitReader(rand.Reader, _, err = io.Copy(conn, io.LimitReader(rand.Reader,
payload_size)) payload_size))
if err != nil { if err != nil {
t.Fatalf("failed writing: %s", err) t.Errorf("failed writing: %s", err)
return return
} }
} }
@@ -581,35 +581,37 @@ func LotsOfConns(t *testing.T, payload_size int64, loops, clients int,
}() }()
var wg sync.WaitGroup var wg sync.WaitGroup
for i := 0; i < clients; i++ { for i := 0; i < clients; i++ {
tcp_client, err := net.Dial(tcp_listener.Addr().Network(), tcpClient, err := net.Dial(tcp_listener.Addr().Network(),
tcp_listener.Addr().String()) tcp_listener.Addr().String())
if err != nil { if err != nil {
t.Fatal(err) t.Error(err)
return
} }
ssl_client, err := newClient(tcp_client) ssl_client, err := newClient(tcpClient)
if err != nil { if err != nil {
t.Fatal(err) t.Error(err)
return
} }
wg.Add(1) wg.Add(1)
go func(i int) { go func(i int) {
defer wg.Done()
defer func() { defer func() {
err = ssl_client.Close() err = ssl_client.Close()
if err != nil { if err != nil {
t.Fatalf("failed closing: %s", err) t.Errorf("failed closing: %s", err)
} }
wg.Done()
}() }()
for i := 0; i < loops; i++ { for i := 0; i < loops; i++ {
_, err := io.Copy(ssl_client, io.LimitReader(rand.Reader, _, err := io.Copy(ssl_client, io.LimitReader(rand.Reader,
payload_size)) payload_size))
if err != nil { if err != nil {
t.Fatalf("failed writing: %s", err) t.Errorf("failed writing: %s", err)
return return
} }
_, err = io.Copy(ioutil.Discard, _, err = io.Copy(ioutil.Discard,
io.LimitReader(ssl_client, payload_size)) io.LimitReader(ssl_client, payload_size))
if err != nil { if err != nil {
t.Fatalf("failed reading: %s", err) t.Errorf("failed reading: %s", err)
return return
} }
} }
@@ -645,20 +647,17 @@ func TestOpenSSLLotsOfConns(t *testing.T) {
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
err = ctx.UsePrivateKey(key) if err = ctx.UsePrivateKey(key); err != nil {
if err != nil {
t.Fatal(err) t.Fatal(err)
} }
cert, err := LoadCertificateFromPEM(certBytes) cert, err := LoadCertificateFromPEM(certBytes)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
err = ctx.UseCertificate(cert) if err = ctx.UseCertificate(cert); err != nil {
if err != nil {
t.Fatal(err) t.Fatal(err)
} }
err = ctx.SetCipherList("AES128-SHA") if err = ctx.SetCipherList("AES128-SHA"); err != nil {
if err != nil {
t.Fatal(err) t.Fatal(err)
} }
LotsOfConns(t, 1024*64, 10, 100, 0*time.Second, LotsOfConns(t, 1024*64, 10, 100, 0*time.Second,

View File

@@ -45,35 +45,35 @@ func NewFuture() *Future {
} }
// Get blocks until the Future has a value set. // Get blocks until the Future has a value set.
func (self *Future) Get() (interface{}, error) { func (f *Future) Get() (interface{}, error) {
self.mutex.Lock() f.mutex.Lock()
defer self.mutex.Unlock() defer f.mutex.Unlock()
for { for {
if self.received { if f.received {
return self.val, self.err return f.val, f.err
} }
self.cond.Wait() f.cond.Wait()
} }
} }
// Fired returns whether or not a value has been set. If Fired is true, Get // Fired returns whether or not a value has been set. If Fired is true, Get
// won't block. // won't block.
func (self *Future) Fired() bool { func (f *Future) Fired() bool {
self.mutex.Lock() f.mutex.Lock()
defer self.mutex.Unlock() defer f.mutex.Unlock()
return self.received return f.received
} }
// Set provides the value to present and future Get calls. If Set has already // Set provides the value to present and future Get calls. If Set has already
// been called, this is a no-op. // been called, this is a no-op.
func (self *Future) Set(val interface{}, err error) { func (f *Future) Set(val interface{}, err error) {
self.mutex.Lock() f.mutex.Lock()
defer self.mutex.Unlock() defer f.mutex.Unlock()
if self.received { if f.received {
return return
} }
self.received = true f.received = true
self.val = val f.val = val
self.err = err f.err = err
self.cond.Broadcast() f.cond.Broadcast()
} }