Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Test GoThemis with Go 1.11~1.14 on CircleCI #595

Merged
merged 8 commits into from
Feb 27, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
102 changes: 98 additions & 4 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,6 @@ jobs:
docker:
- image: cossacklabs/android-build:2019.01
environment:
GOTHEMIS_IMPORT: github.com/cossacklabs/themis/gothemis
# NIST STS tests tend to fail in Docker environment
NO_NIST_STS: 1
WITH_FATAL_WARNINGS: yes
Expand Down Expand Up @@ -208,8 +207,6 @@ jobs:
- run: make ENGINE=boringssl BUILD_PATH=build_with_boringssl prepare_tests_basic
- run: make BUILD_PATH=cover_build COVERAGE=y prepare_tests_basic
- run: make prepare_tests_all
- run: mkdir -p $HOME/go/src/$GOTHEMIS_IMPORT
- run: rsync -auv gothemis/ $HOME/go/src/$GOTHEMIS_IMPORT/
- run: lcov --directory . --zerocounters
# run only if CIRCLE_PR_NUMBER variable is not set (it's not pull request and COVERALLS_TOKEN will be set via circleCI for non-PR build) and COVERALLS_TOKEN is set
# we should calculate coverage for gothemis and send report before sending coverage of main C part
Expand All @@ -227,7 +224,6 @@ jobs:
# - run: make clean_themispp_test && CXX="clang++" CFLAGS="-std=c++17" make themispp_test && make test_cpp
- run: make test_python
- run: make test_ruby
- run: make test_go
- run: make test_rust
- run: make fuzz
- run: $HOME/valgrind/bin/valgrind build/tests/soter_test 2>&1 | grep "ERROR SUMMARY\|definitely lost\|indirectly lost\|possibly lost" | awk '{sum += $4} END {print $0; if ( sum > 0 ) { exit 1 } }'
Expand All @@ -247,6 +243,102 @@ jobs:
- ~/.cargo
- ~/.rustup

gothemis:
docker:
- image: cossacklabs/build:ubuntu-bionic
environment:
GOTHEMIS_IMPORT: github.com/cossacklabs/themis/gothemis
WITH_FATAL_WARNINGS: yes
steps:
- run:
name: Install Go versions
command: |
# These is not much difference between fetching these binaries from
# CircleCI cache and downloading them from scratch: both take around
# 30 seconds. But CircleCI caches are immutable and tricky to update.
#
# You can find latest versions and their hashes here:
# https://golang.org/dl/
# We support latest stable releases (as declared by Go team)
# as well as some historical versions on best-effort basis
go_versions=(
"1.14 1.14 https://dl.google.com/go/go1.14.linux-amd64.tar.gz 08df79b46b0adf498ea9f320a0f23d6ec59e9003660b4c9c1ce8e5e2c6f823ca"
"1.13 1.13.8 https://dl.google.com/go/go1.13.8.linux-amd64.tar.gz 0567734d558aef19112f2b2873caa0c600f1b4a5827930eb5a7f35235219e9d8"
"1.12 1.12.17 https://dl.google.com/go/go1.12.17.linux-amd64.tar.gz a53dd476129d496047487bfd53d021dd17e0c96895865a0e7d0469ce3db8c8d2"
"1.11 1.11.13 https://dl.google.com/go/go1.11.13.linux-amd64.tar.gz 50fe8e13592f8cf22304b9c4adfc11849a2c3d281b1d7e09c924ae24874c6daa"
)
mkdir -p "$HOME/go-install"
for v in "${go_versions[@]}"
do
set -- $v
install_name="$HOME/go-install/go-$1"
tarball_name="$HOME/go-install/go-$2.tar.gz"
tarball_url="$3"
expect_hash="$4"
# Download the tarball only if we do not have it already installed
if [[ ! -e "$install_name" ]]
then
wget -O "$tarball_name" "$tarball_url"
actual_hash=$(sha256sum "$tarball_name" | awk '{print $1}')
if [[ "$actual_hash" != "$expect_hash" ]]
then
echo 1>&2 "Go distribution checksum mismatch!"
echo 1>&2 " actual: $actual_hash"
echo 1>&2 " expect: $expect_hash"
exit 1
fi
# Go tarball already contains a "go" directory, but we want
# it to be named differently to allow parallel installs
echo "Unpacking $tarball_name into $install_name..."
tar -C "$HOME/go-install" -xzf "$tarball_name"
mv "$HOME/go-install/go" "$install_name"
fi
done
- checkout
- run:
name: Init submodules
command: |
git reset --hard HEAD
git submodule sync
git submodule update --init
- run:
name: Install Themis Core
command: |
make
sudo make install
- run:
name: Prepare tests
command: make prepare_tests_all
- run:
name: Install GoThemis
command: |
mkdir -p $HOME/go/src/$GOTHEMIS_IMPORT
cp -ar gothemis/* $HOME/go/src/$GOTHEMIS_IMPORT
- run:
name: GoThemis unit tests (Go 1.14)
command: |
export PATH="$HOME/go-install/go-1.14/bin:$PATH"
go version
make test_go
- run:
name: GoThemis unit tests (Go 1.13)
command: |
export PATH="$HOME/go-install/go-1.13/bin:$PATH"
go version
make test_go
- run:
name: GoThemis unit tests (Go 1.12)
command: |
export PATH="$HOME/go-install/go-1.12/bin:$PATH"
go version
make test_go
- run:
name: GoThemis unit tests (Go 1.11)
command: |
export PATH="$HOME/go-install/go-1.11/bin:$PATH"
go version
make test_go

jsthemis:
docker:
- image: cossacklabs/android-build:2019.01
Expand Down Expand Up @@ -529,6 +621,7 @@ workflows:
- benchmark
- android
- x86_64
- gothemis
- jsthemis
- php5
- php70
Expand All @@ -550,6 +643,7 @@ workflows:
- benchmark
- android
- x86_64
- gothemis
- jsthemis
- php5
- php70
Expand Down
52 changes: 52 additions & 0 deletions gothemis/cell/cell_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,12 @@ import (
"bytes"
"crypto/rand"
"math/big"
"runtime"
"strconv"
"strings"
"testing"

"github.com/cossacklabs/themis/gothemis/keys"
)

func testProtect(mode int, context []byte, t *testing.T) {
Expand Down Expand Up @@ -96,3 +101,50 @@ func TestProtect(t *testing.T) {

testProtect(ModeContextImprint, context, t)
}

// Regression test for cgo false positive, resolved in go 1.12:
// https://github.com/golang/go/issues/14210
func TestBufferGo111(t *testing.T) {
key, err := keys.NewSymmetricKey()
if err != nil {
t.Fatalf("cannot generate master key: %v", err)
}
sc := New(key.Value, ModeSeal)

data := []byte("some data to encrypt")

b := new(bytes.Buffer)
b.WriteString("context in bytes.Buffer")
context := b.Bytes()

// Code that follows panics before Go 1.12
defer func() {
if msg := recover(); msg != nil {
major, minor, _ := goVersion()
if major >= 1 && minor >= 12 {
t.Errorf("Protect() panicked: %v", msg)
}
}
}()
_, _, err = sc.Protect(data, context)
if err != nil {
t.Errorf("Protect() failed: %v", err)
}
}

func goVersion() (int, int, int) {
version := runtime.Version()
version = strings.TrimPrefix(version, "go")
components := strings.Split(version, ".")
var major, minor, patch int
if len(components) >= 1 {
major, _ = strconv.Atoi(components[0])
}
if len(components) >= 2 {
minor, _ = strconv.Atoi(components[1])
}
if len(components) >= 3 {
patch, _ = strconv.Atoi(components[2])
}
return major, minor, patch
}
179 changes: 178 additions & 1 deletion gothemis/message/message_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@ package message
import (
"bytes"
"crypto/rand"
"github.com/cossacklabs/themis/gothemis/keys"
"math/big"
"testing"

"github.com/cossacklabs/themis/gothemis/keys"
)

func testWrap(keytype int, t *testing.T) {
Expand Down Expand Up @@ -124,3 +125,179 @@ func TestMessageSign(t *testing.T) {
testSign(keys.TypeEC, t)
testSign(keys.TypeRSA, t)
}

func BenchmarkSMessageEncryptRSA(b *testing.B) {
keyPair, err := keys.New(keys.TypeRSA)
if err != nil {
b.Errorf("failed to generate key pair: %v", err)
}
plaintext := make([]byte, 1024)
_, err = rand.Read(plaintext)
if err != nil {
b.Errorf("failed to generate plaintext: %v", err)
}
smessage := New(keyPair.Private, keyPair.Public)
b.ResetTimer()
for i := 0; i < b.N; i++ {
_, err := smessage.Wrap(plaintext)
if err != nil {
b.Errorf("encryption failed: %v", err)
}
}
}

func BenchmarkSMessageEncryptEC(b *testing.B) {
keyPair, err := keys.New(keys.TypeEC)
if err != nil {
b.Errorf("failed to generate key pair: %v", err)
}
plaintext := make([]byte, 1024)
_, err = rand.Read(plaintext)
if err != nil {
b.Errorf("failed to generate plaintext: %v", err)
}
smessage := New(keyPair.Private, keyPair.Public)
b.ResetTimer()
for i := 0; i < b.N; i++ {
_, err := smessage.Wrap(plaintext)
if err != nil {
b.Errorf("encryption failed: %v", err)
}
}
}

func BenchmarkSMessageDecryptRSA(b *testing.B) {
keyPair, err := keys.New(keys.TypeRSA)
if err != nil {
b.Errorf("failed to generate key pair: %v", err)
}
plaintext := make([]byte, 1024)
_, err = rand.Read(plaintext)
if err != nil {
b.Errorf("failed to generate plaintext: %v", err)
}
smessage := New(keyPair.Private, keyPair.Public)
encrypted, err := smessage.Wrap(plaintext)
if err != nil {
b.Errorf("failed to encrypt message: %v", err)
}
b.ResetTimer()
for i := 0; i < b.N; i++ {
_, err := smessage.Unwrap(encrypted)
if err != nil {
b.Errorf("decryption failed: %v", err)
}
}
}

func BenchmarkSMessageDecryptEC(b *testing.B) {
keyPair, err := keys.New(keys.TypeEC)
if err != nil {
b.Errorf("failed to generate key pair: %v", err)
}
plaintext := make([]byte, 1024)
_, err = rand.Read(plaintext)
if err != nil {
b.Errorf("failed to generate plaintext: %v", err)
}
smessage := New(keyPair.Private, keyPair.Public)
encrypted, err := smessage.Wrap(plaintext)
if err != nil {
b.Errorf("failed to encrypt message: %v", err)
}
b.ResetTimer()
for i := 0; i < b.N; i++ {
_, err := smessage.Unwrap(encrypted)
if err != nil {
b.Errorf("decryption failed: %v", err)
}
}
}

func BenchmarkSMessageSignRSA(b *testing.B) {
keyPair, err := keys.New(keys.TypeRSA)
if err != nil {
b.Errorf("failed to generate key pair: %v", err)
}
plaintext := make([]byte, 1024)
_, err = rand.Read(plaintext)
if err != nil {
b.Errorf("failed to generate plaintext: %v", err)
}
smessage := New(keyPair.Private, keyPair.Public)
b.ResetTimer()
for i := 0; i < b.N; i++ {
_, err := smessage.Sign(plaintext)
if err != nil {
b.Errorf("signing failed: %v", err)
}
}
}

func BenchmarkSMessageSignEC(b *testing.B) {
keyPair, err := keys.New(keys.TypeEC)
if err != nil {
b.Errorf("failed to generate key pair: %v", err)
}
plaintext := make([]byte, 1024)
_, err = rand.Read(plaintext)
if err != nil {
b.Errorf("failed to generate plaintext: %v", err)
}
smessage := New(keyPair.Private, keyPair.Public)
b.ResetTimer()
for i := 0; i < b.N; i++ {
_, err := smessage.Sign(plaintext)
if err != nil {
b.Errorf("signing failed: %v", err)
}
}
}

func BenchmarkSMessageVerifyRSA(b *testing.B) {
keyPair, err := keys.New(keys.TypeRSA)
if err != nil {
b.Errorf("failed to generate key pair: %v", err)
}
plaintext := make([]byte, 1024)
_, err = rand.Read(plaintext)
if err != nil {
b.Errorf("failed to generate plaintext: %v", err)
}
smessage := New(keyPair.Private, keyPair.Public)
encrypted, err := smessage.Sign(plaintext)
if err != nil {
b.Errorf("failed to sign message: %v", err)
}
b.ResetTimer()
for i := 0; i < b.N; i++ {
_, err := smessage.Verify(encrypted)
if err != nil {
b.Errorf("verification failed: %v", err)
}
}
}

func BenchmarkSMessageVerifyEC(b *testing.B) {
keyPair, err := keys.New(keys.TypeEC)
if err != nil {
b.Errorf("failed to generate key pair: %v", err)
}
plaintext := make([]byte, 1024)
_, err = rand.Read(plaintext)
if err != nil {
b.Errorf("failed to generate plaintext: %v", err)
}
smessage := New(keyPair.Private, keyPair.Public)
encrypted, err := smessage.Sign(plaintext)
if err != nil {
b.Errorf("failed to sign message: %v", err)
}
b.ResetTimer()
for i := 0; i < b.N; i++ {
_, err := smessage.Verify(encrypted)
if err != nil {
b.Errorf("verification failed: %v", err)
}
}
}