From ce0c256f372a2c3b50ffa45402e2005e456c2719 Mon Sep 17 00:00:00 2001 From: Duncan Jones Date: Mon, 21 Jan 2019 13:13:01 +0000 Subject: [PATCH 1/4] Improve error checking in test files --- Gopkg.lock | 53 ++++++++++++++++++++++++++++++++++++++++++-- Gopkg.toml | 4 ++++ crypto11_test.go | 56 +++++++++++++++++++++++++++++++++-------------- dsa_test.go | 8 ++++--- ecdsa_test.go | 8 ++++--- hmac_test.go | 8 ++++--- pool_test.go | 19 +++++++++++----- rand_test.go | 8 ++++--- rsa_test.go | 17 +++++++++----- symmetric_test.go | 14 +++++++----- thread_test.go | 8 ++++--- 11 files changed, 153 insertions(+), 50 deletions(-) diff --git a/Gopkg.lock b/Gopkg.lock index 9030a39..1e78dac 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -1,37 +1,86 @@ # This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'. +[[projects]] + digest = "1:0deddd908b6b4b768cfc272c16ee61e7088a60f7fe2f06c547bd3d8e1f8b8e77" + name = "github.com/davecgh/go-spew" + packages = ["spew"] + pruneopts = "" + revision = "8991bc29aa16c548c550c7ff78260e27b9ab7c73" + version = "v1.1.1" + [[projects]] branch = "master" + digest = "1:e48e3de0a7d38e6d55730d0ade3624650ccdbfcc8f518db3486401337cac617b" name = "github.com/miekg/pkcs11" packages = ["."] + pruneopts = "" revision = "c6d6ee821fb161c8022ceb8ba93ce3b815d8d62e" [[projects]] + digest = "1:256484dbbcd271f9ecebc6795b2df8cad4c458dd0f5fd82a8c2fa0c29f233411" + name = "github.com/pmezard/go-difflib" + packages = ["difflib"] + pruneopts = "" + revision = "792786c7400a136282c1664665ae0a8db921c6c2" + version = "v1.0.0" + +[[projects]] + digest = "1:711eebe744c0151a9d09af2315f0bb729b2ec7637ef4c410fa90a18ef74b65b6" + name = "github.com/stretchr/objx" + packages = ["."] + pruneopts = "" + revision = "477a77ecc69700c7cdeb1fa9e129548e1c1c393c" + version = "v0.1.1" + +[[projects]] + digest = "1:381bcbeb112a51493d9d998bbba207a529c73dbb49b3fd789e48c63fac1f192c" + name = "github.com/stretchr/testify" + packages = [ + ".", + "assert", + "http", + "mock", + ] + pruneopts = "" + revision = "ffdc059bfe9ce6a4e144ba849dbedead332c6053" + version = "v1.3.0" + +[[projects]] + digest = "1:c04f8425afbb4fe70847f832fb4f773db79f9b0460bdbdd112282a369a401638" name = "github.com/youtube/vitess" packages = ["go/pools"] + pruneopts = "" revision = "66e84fadcc1a7e956e7ffcebcaaba0b04132ca1f" version = "v2.2" [[projects]] branch = "master" + digest = "1:08e41d63f8dac84d83797368b56cf0b339e42d0224e5e56668963c28aec95685" name = "golang.org/x/net" packages = ["context"] + pruneopts = "" revision = "4dfa2610cdf3b287375bbba5b8f2a14d3b01d8de" [[projects]] + digest = "1:c04f8425afbb4fe70847f832fb4f773db79f9b0460bdbdd112282a369a401638" name = "vitess.io/vitess" packages = [ "go/cache", "go/sync2", - "go/timer" + "go/timer", ] + pruneopts = "" revision = "66e84fadcc1a7e956e7ffcebcaaba0b04132ca1f" version = "v2.2" [solve-meta] analyzer-name = "dep" analyzer-version = 1 - inputs-digest = "8cd1e283a543a5f16f1a28efc4432ba787658c62e70c42078f5910e9b21a3803" + input-imports = [ + "github.com/miekg/pkcs11", + "github.com/stretchr/testify", + "github.com/youtube/vitess/go/pools", + ] solver-name = "gps-cdcl" solver-version = 1 diff --git a/Gopkg.toml b/Gopkg.toml index 045b459..d604a73 100644 --- a/Gopkg.toml +++ b/Gopkg.toml @@ -24,3 +24,7 @@ [[constraint]] branch = "master" name = "github.com/miekg/pkcs11" + +[[constraint]] + name = "github.com/stretchr/testify" + version = "1.3.0" diff --git a/crypto11_test.go b/crypto11_test.go index 77cc7c0..1a56ec2 100644 --- a/crypto11_test.go +++ b/crypto11_test.go @@ -27,6 +27,7 @@ import ( "encoding/json" "fmt" "github.com/miekg/pkcs11" + "github.com/stretchr/testify/require" "log" "os" "testing" @@ -40,17 +41,22 @@ func TestInitializeFromConfig(t *testing.T) { config.TokenSerial = "NoSuchToken" config.TokenLabel = "NoSuchToken" //assert.Panics(Configure(config), "Invalid config should panic") - ConfigureFromFile("config") - Close() + _, err := ConfigureFromFile("config") + require.NoError(t, err) + require.NoError(t, Close()) } func TestLoginContext(t *testing.T) { t.Run("key identity with login", func(t *testing.T) { - configureWithPin(t) - defer Close() + _, err := configureWithPin(t) + require.NoError(t, err) + + defer func() { + err = Close() + require.NoError(t, err) + }() // Generate a key and and close a session - var err error var key *PKCS11PrivateKeyDSA psize := dsa.L1024N160 if key, err = GenerateDSAKeyPair(dsaSizes[psize]); err != nil { @@ -74,7 +80,8 @@ func TestLoginContext(t *testing.T) { // Reopen a session and try to find a key. // Valid session must enlist a key. // If login is not performed than it will fail. - configureWithPin(t) + _, err = configureWithPin(t) + require.NoError(t, err) var key2 crypto.PrivateKey if key2, err = FindKeyPair(id, nil); err != nil { @@ -89,11 +96,15 @@ func TestLoginContext(t *testing.T) { defer func() {instance.cfg.IdleTimeout = prevIdleTimeout}() instance.cfg.IdleTimeout = time.Second - configureWithPin(t) - defer Close() + _, err := configureWithPin(t) + require.NoError(t, err) + + defer func() { + err = Close() + require.NoError(t, err) + }() // Generate a key and and close a session - var err error var key *PKCS11PrivateKeyDSA psize := dsa.L1024N160 if key, err = GenerateDSAKeyPair(dsaSizes[psize]); err != nil { @@ -123,11 +134,15 @@ func TestLoginContext(t *testing.T) { }) t.Run("login context shared between sessions", func(t *testing.T) { - configureWithPin(t) - defer Close() + _, err := configureWithPin(t) + require.NoError(t, err) + + defer func() { + err = Close() + require.NoError(t, err) + }() // Generate a key and and close a session - var err error var key *PKCS11PrivateKeyDSA psize := dsa.L1024N160 if key, err = GenerateDSAKeyPair(dsaSizes[psize]); err != nil { @@ -167,11 +182,15 @@ func TestIdentityExpiration(t *testing.T) { defer func() {instance.cfg.IdleTimeout = prevIdleTimeout}() instance.cfg.IdleTimeout = time.Second - configureWithPin(t) - defer Close() + _, err := configureWithPin(t) + require.NoError(t, err) + + defer func() { + err = Close() + require.NoError(t, err) + }() // Generate a key and and close a session - var err error var key *PKCS11PrivateKeyDSA psize := dsa.L1024N160 if key, err = GenerateDSAKeyPair(dsaSizes[psize]); err != nil { @@ -211,13 +230,16 @@ func configureWithPin(t *testing.T) (*pkcs11.Ctx, error) { return ctx, nil } -func getConfig(configLocation string) (*PKCS11Config, error) { +func getConfig(configLocation string) (ctx *PKCS11Config, err error) { file, err := os.Open(configLocation) if err != nil { log.Printf("Could not open config file: %s", configLocation) return nil, err } - defer file.Close() + defer func() { + err = file.Close() + }() + configDecoder := json.NewDecoder(file) config := &PKCS11Config{} err = configDecoder.Decode(config) diff --git a/dsa_test.go b/dsa_test.go index c3fee61..23764d9 100644 --- a/dsa_test.go +++ b/dsa_test.go @@ -28,6 +28,7 @@ import ( _ "crypto/sha1" _ "crypto/sha256" _ "crypto/sha512" + "github.com/stretchr/testify/require" "io" "math/big" "testing" @@ -99,11 +100,12 @@ func TestNativeDSA(t *testing.T) { } func TestHardDSA(t *testing.T) { - var err error var key *PKCS11PrivateKeyDSA var key2, key3 crypto.PrivateKey var id, label []byte - ConfigureFromFile("config") + _, err := ConfigureFromFile("config") + require.NoError(t, err) + for psize, params := range dsaSizes { if key, err = GenerateDSAKeyPair(params); err != nil { t.Errorf("crypto11.GenerateDSAKeyPair: %v", err) @@ -130,7 +132,7 @@ func TestHardDSA(t *testing.T) { } testDsaSigning(t, key3.(crypto.Signer), psize, "hard3") } - Close() + require.NoError(t, Close()) } func testDsaSigning(t *testing.T, key crypto.Signer, psize dsa.ParameterSizes, what string) { diff --git a/ecdsa_test.go b/ecdsa_test.go index fdca2a1..21d4e11 100644 --- a/ecdsa_test.go +++ b/ecdsa_test.go @@ -29,6 +29,7 @@ import ( _ "crypto/sha1" _ "crypto/sha256" _ "crypto/sha512" + "github.com/stretchr/testify/require" "testing" ) @@ -57,11 +58,12 @@ func TestNativeECDSA(t *testing.T) { } func TestHardECDSA(t *testing.T) { - var err error var key *PKCS11PrivateKeyECDSA var key2, key3 crypto.PrivateKey var id, label []byte - ConfigureFromFile("config") + _, err := ConfigureFromFile("config") + require.NoError(t, err) + for _, curve := range curves { if key, err = GenerateECDSAKeyPair(curve); err != nil { t.Errorf("GenerateECDSAKeyPair: %v", err) @@ -92,7 +94,7 @@ func TestHardECDSA(t *testing.T) { } testEcdsaSigning(t, key3.(crypto.Signer), crypto.SHA384) } - Close() + require.NoError(t, Close()) } func testEcdsaSigning(t *testing.T, key crypto.Signer, hashFunction crypto.Hash) { diff --git a/hmac_test.go b/hmac_test.go index 9baa766..4757065 100644 --- a/hmac_test.go +++ b/hmac_test.go @@ -24,14 +24,16 @@ package crypto11 import ( "bytes" "github.com/miekg/pkcs11" + "github.com/stretchr/testify/require" "hash" "testing" ) func TestHmac(t *testing.T) { - ConfigureFromFile("config") + _, err := ConfigureFromFile("config") + require.NoError(t, err) + var info pkcs11.Info - var err error if info, err = instance.ctx.GetInfo(); err != nil { t.Errorf("GetInfo: %v", err) return @@ -48,7 +50,7 @@ func TestHmac(t *testing.T) { t.Run("HMACSHA256", func(t *testing.T) { testHmac(t, pkcs11.CKK_SHA256_HMAC, pkcs11.CKM_SHA256_HMAC, 0, 32, false) }) - Close() + require.NoError(t, Close()) } func testHmac(t *testing.T, keytype int, mech int, length int, xlength int, full bool) { diff --git a/pool_test.go b/pool_test.go index 18a2baa..5eb0d8e 100644 --- a/pool_test.go +++ b/pool_test.go @@ -27,6 +27,7 @@ import ( "crypto/rand" "fmt" "github.com/miekg/pkcs11" + "github.com/stretchr/testify/require" "testing" "time" ) @@ -38,12 +39,16 @@ func TestPoolTimeout(t *testing.T) { defer func() { instance.cfg.IdleTimeout = prevIdleTimeout }() instance.cfg.IdleTimeout = d - configureWithPin(t) - defer Close() + _, err := configureWithPin(t) + require.NoError(t, err) + + defer func() { + require.NoError(t, Close()) + }() time.Sleep(instance.cfg.IdleTimeout + time.Second) - _, err := GenerateECDSAKeyPair(elliptic.P256()) + _, err = GenerateECDSAKeyPair(elliptic.P256()) if err != nil { if perr, ok := err.(pkcs11.Error); ok && perr == pkcs11.CKR_USER_NOT_LOGGED_IN { t.Fatal("pool handle session incorrectly, login required but missing:", err) @@ -58,8 +63,12 @@ func TestPoolTimeout(t *testing.T) { defer func() { instance.cfg.IdleTimeout = prevIdleTimeout }() instance.cfg.IdleTimeout = d - configureWithPin(t) - defer Close() + _, err := configureWithPin(t) + require.NoError(t, err) + + defer func() { + require.NoError(t, Close()) + }() key, err := GenerateECDSAKeyPair(elliptic.P256()) if err != nil { diff --git a/rand_test.go b/rand_test.go index d48e28c..52ea4fe 100644 --- a/rand_test.go +++ b/rand_test.go @@ -22,15 +22,17 @@ package crypto11 import ( + "github.com/stretchr/testify/require" "testing" ) func TestRandomReader(t *testing.T) { var a [32768]byte var r PKCS11RandReader - var err error var n int - ConfigureFromFile("config") + _, err := ConfigureFromFile("config") + require.NoError(t, err) + for _, size := range []int{1, 16, 32, 256, 347, 4096, 32768} { if n, err = r.Read(a[:size]); err != nil { t.Errorf("crypto11.PKCS11RandRead.Read: %v", err) @@ -41,5 +43,5 @@ func TestRandomReader(t *testing.T) { return } } - Close() + require.NoError(t, Close()) } diff --git a/rsa_test.go b/rsa_test.go index a057c08..e6a3f27 100644 --- a/rsa_test.go +++ b/rsa_test.go @@ -31,15 +31,17 @@ import ( _ "crypto/sha512" "fmt" "github.com/miekg/pkcs11" + "github.com/stretchr/testify/require" "testing" ) var rsaSizes = []int{1024, 2048} func TestNativeRSA(t *testing.T) { - var err error var key *rsa.PrivateKey - ConfigureFromFile("config") + _, err := ConfigureFromFile("config") + require.NoError(t, err) + for _, nbits := range rsaSizes { t.Run(fmt.Sprintf("%v", nbits), func(t *testing.T) { t.Run("Generate", func(t *testing.T) { @@ -56,15 +58,18 @@ func TestNativeRSA(t *testing.T) { t.Run("Encrypt", func(t *testing.T) { testRsaEncryption(t, key, nbits, ^uint(0)) }) }) } - Close() + + require.NoError(t, Close()) } func TestHardRSA(t *testing.T) { - var err error var key *PKCS11PrivateKeyRSA var key2, key3 crypto.PrivateKey var id, label []byte - ConfigureFromFile("config") + + _, err := ConfigureFromFile("config") + require.NoError(t, err) + for _, nbits := range rsaSizes { t.Run(fmt.Sprintf("%v", nbits), func(t *testing.T) { t.Run("Generate", func(t *testing.T) { @@ -114,7 +119,7 @@ func TestHardRSA(t *testing.T) { }) }) } - Close() + require.NoError(t, Close()) } func testRsaSigning(t *testing.T, key crypto.Signer, nbits int, slot uint) { diff --git a/symmetric_test.go b/symmetric_test.go index 113555c..c4682da 100644 --- a/symmetric_test.go +++ b/symmetric_test.go @@ -26,17 +26,20 @@ import ( "crypto" "crypto/cipher" "github.com/miekg/pkcs11" + "github.com/stretchr/testify/require" "runtime" "testing" ) func TestHardSymmetric(t *testing.T) { - ConfigureFromFile("config") + _, err := ConfigureFromFile("config") + require.NoError(t, err) + t.Run("AES128", func(t *testing.T) { testHardSymmetric(t, pkcs11.CKK_AES, 128) }) t.Run("AES192", func(t *testing.T) { testHardSymmetric(t, pkcs11.CKK_AES, 192) }) t.Run("AES256", func(t *testing.T) { testHardSymmetric(t, pkcs11.CKK_AES, 256) }) t.Run("DES3", func(t *testing.T) { testHardSymmetric(t, pkcs11.CKK_DES3, 0) }) - Close() + require.NoError(t, Close()) } func testHardSymmetric(t *testing.T, keytype int, bits int) { @@ -254,8 +257,9 @@ func testAEADMode(t *testing.T, aead cipher.AEAD, ptlen int, adlen int) { } func BenchmarkCBC(b *testing.B) { - ConfigureFromFile("config") - var err error + _, err := ConfigureFromFile("config") + require.NoError(b, err) + var key *PKCS11SecretKey if key, err = GenerateSecretKey(128, Ciphers[pkcs11.CKK_AES]); err != nil { b.Errorf("crypto11.GenerateSecretKey: %v", err) @@ -290,7 +294,7 @@ func BenchmarkCBC(b *testing.B) { } runtime.GC() }) - Close() + require.NoError(b, Close()) } // TODO BenchmarkGCM along the same lines as above diff --git a/thread_test.go b/thread_test.go index 9ebd6da..bd01fb8 100644 --- a/thread_test.go +++ b/thread_test.go @@ -23,6 +23,7 @@ package crypto11 import ( "crypto" + "github.com/stretchr/testify/require" "testing" "time" ) @@ -31,9 +32,10 @@ var threadCount = 32 var signaturesPerThread = 256 func TestThreadedRSA(t *testing.T) { - var err error var key *PKCS11PrivateKeyRSA - ConfigureFromFile("config") + _, err := ConfigureFromFile("config") + require.NoError(t, err) + if key, err = GenerateRSAKeyPair(1024); err != nil { t.Errorf("crypto11.GenerateRSAKeyPair: %v", err) return @@ -54,7 +56,7 @@ func TestThreadedRSA(t *testing.T) { t.Logf("Made %v signatures in %v elapsed (%v/s)", threadCount*signaturesPerThread, elapsed, float64(threadCount*signaturesPerThread)/elapsed) - Close() + require.NoError(t, Close()) } func signingRoutine(t *testing.T, key crypto.Signer, done chan int) { From 8e189017d36859af43e16d0ad2c616c5c0feacb8 Mon Sep 17 00:00:00 2001 From: Duncan Jones Date: Mon, 21 Jan 2019 13:54:53 +0000 Subject: [PATCH 2/4] Improve error handling, deprecate Close() function The PKCS11Session.Close() method was ignoring the error return from the PKCS#11 library. Impossible to fix this without breaking existing code, so this function is deprecated and the awkwardly named CloseSession() succeeds it. --- common.go | 8 ++++++-- crypto11.go | 7 +++++-- hmac.go | 5 ++++- keys.go | 7 ++++--- sessions.go | 21 ++++++++++++++++++--- 5 files changed, 37 insertions(+), 11 deletions(-) diff --git a/common.go b/common.go index ea41cfb..c7c3503 100644 --- a/common.go +++ b/common.go @@ -72,7 +72,7 @@ func (sig *dsaSignature) marshalDER() ([]byte, error) { return asn1.Marshal(*sig) } -// Compute *DSA signature and marshal the result in DER fform +// Compute *DSA signature and marshal the result in DER form func dsaGeneric(slot uint, key pkcs11.ObjectHandle, mechanism uint, digest []byte) ([]byte, error) { var err error var sigBytes []byte @@ -88,7 +88,11 @@ func dsaGeneric(slot uint, key pkcs11.ObjectHandle, mechanism uint, digest []byt if err != nil { return nil, err } - sig.unmarshalBytes(sigBytes) + err = sig.unmarshalBytes(sigBytes) + if err != nil { + return nil, err + } + return sig.marshalDER() } diff --git a/crypto11.go b/crypto11.go index 88251aa..f769f53 100644 --- a/crypto11.go +++ b/crypto11.go @@ -285,13 +285,16 @@ func Configure(config *PKCS11Config) (*pkcs11.Ctx, error) { // Note that if CRYPTO11_CONFIG_PATH is set in the environment, // configuration will be read from that file, overriding any later // runtime configuration. -func ConfigureFromFile(configLocation string) (*pkcs11.Ctx, error) { +func ConfigureFromFile(configLocation string) (ctx *pkcs11.Ctx, err error) { file, err := os.Open(configLocation) if err != nil { log.Printf("Could not open config file: %s", configLocation) return nil, err } - defer file.Close() + defer func() { + err = file.Close() + }() + configDecoder := json.NewDecoder(file) config := &PKCS11Config{} err = configDecoder.Decode(config) diff --git a/hmac.go b/hmac.go index 2e12cbf..ba43ace 100644 --- a/hmac.go +++ b/hmac.go @@ -214,7 +214,10 @@ func (hi *hmacImplementation) Sum(b []byte) []byte { func (hi *hmacImplementation) Reset() { hi.Sum(nil) // Clean up - hi.initialize() + err := hi.initialize() + if err != nil { + panic(err) + } } func (hi *hmacImplementation) Size() int { diff --git a/keys.go b/keys.go index 6df9906..59f1405 100644 --- a/keys.go +++ b/keys.go @@ -46,8 +46,7 @@ func (object *PKCS11Object) Identify() (id []byte, label []byte, err error) { // Find a key object. For asymmetric keys this only finds one half so // callers will call it twice. -func findKey(session *PKCS11Session, id []byte, label []byte, keyclass uint, keytype uint) (pkcs11.ObjectHandle, error) { - var err error +func findKey(session *PKCS11Session, id []byte, label []byte, keyclass uint, keytype uint) (obj pkcs11.ObjectHandle, err error) { var handles []pkcs11.ObjectHandle var template []*pkcs11.Attribute if keyclass != ^uint(0) { @@ -65,7 +64,9 @@ func findKey(session *PKCS11Session, id []byte, label []byte, keyclass uint, key if err = session.Ctx.FindObjectsInit(session.Handle, template); err != nil { return 0, err } - defer session.Ctx.FindObjectsFinal(session.Handle) + defer func() { + err = session.Ctx.FindObjectsFinal(session.Handle) + }() if handles, _, err = session.Ctx.FindObjects(session.Handle, 1); err != nil { return 0, err } diff --git a/sessions.go b/sessions.go index 5ead920..4d235bc 100644 --- a/sessions.go +++ b/sessions.go @@ -69,8 +69,18 @@ func newSessionPool() *sessionPool { } // Close closes the session. +// +// Deprecated: Use CloseSession, which returns any underlying errors. func (session *PKCS11Session) Close() { - session.Ctx.CloseSession(session.Handle) + // TODO - when next making breaking changes, kill this method (or fix it) + + // Assign error to "_", to indicate we are knowingly ignoring it + _ = session.Ctx.CloseSession(session.Handle) +} + +// CloseSession closes the session. +func (session *PKCS11Session) CloseSession() error { + return session.Ctx.CloseSession(session.Handle) } // Get returns requested resource pool by slot id @@ -176,9 +186,14 @@ func loginToken(s *PKCS11Session) error { return nil } log.Printf("Failed to open PKCS#11 Session: %s", err.Error()) - s.Close() - return err + closeErr := s.CloseSession() + if closeErr != nil { + log.Printf("Failed to close session: %s", closeErr.Error()) + } + + // Return the first error we encountered + return err } return nil } From d164647ed0fb82f2b171e5e25407c16e39217781 Mon Sep 17 00:00:00 2001 From: Duncan Jones Date: Mon, 21 Jan 2019 14:03:21 +0000 Subject: [PATCH 3/4] Revert a change that wasn't backwards compatible --- hmac.go | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/hmac.go b/hmac.go index ba43ace..dc710ae 100644 --- a/hmac.go +++ b/hmac.go @@ -214,10 +214,11 @@ func (hi *hmacImplementation) Sum(b []byte) []byte { func (hi *hmacImplementation) Reset() { hi.Sum(nil) // Clean up - err := hi.initialize() - if err != nil { - panic(err) - } + + // Assign the error to "_" to indicate we are knowingly ignoring this. It may have been + // sensible to panic at this stage, but we cannot add a panic without breaking backwards + // compatibility. + _ = hi.initialize() } func (hi *hmacImplementation) Size() int { From 448ffac7ec7923b66635c69f58e12d28f77470ce Mon Sep 17 00:00:00 2001 From: Duncan Jones Date: Tue, 22 Jan 2019 11:32:34 +0000 Subject: [PATCH 4/4] Fix caching issue in CI --- .travis.yml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index bf1c6d4..bed83e9 100644 --- a/.travis.yml +++ b/.travis.yml @@ -9,9 +9,7 @@ go: # trusty only has softhsmv1 before_script: - - sudo add-apt-repository -y ppa:pkg-opendnssec/ppa - - sudo apt-get update - - sudo apt-get install softhsm2 + - sudo add-apt-repository -y ppa:pkg-opendnssec/ppa && sudo apt-get update && sudo apt-get install softhsm2 - curl https://raw.githubusercontent.com/golang/dep/master/install.sh | sh script: