mirror of https://github.com/docker/docs.git
commit
eb52b64586
|
@ -63,7 +63,7 @@
|
|||
},
|
||||
{
|
||||
"ImportPath": "github.com/endophage/gotuf",
|
||||
"Rev": "31d0377282dac4a9e5800933d9a920fb09a15331"
|
||||
"Rev": "5be7693587dc2f3c6b35fd1394fcc4e098b4f643"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/go-sql-driver/mysql",
|
||||
|
|
|
@ -65,10 +65,6 @@
|
|||
{
|
||||
"ImportPath": "golang.org/x/crypto/scrypt",
|
||||
"Rev": "bfc286917c5fcb7420d7e3092b50bbfd31b38a98"
|
||||
},
|
||||
{
|
||||
"ImportPath": "gopkg.in/check.v1",
|
||||
"Rev": "64131543e7896d5bcc6bd5a76287eb75ea96c673"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
@ -2,56 +2,54 @@ package data
|
|||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"testing"
|
||||
|
||||
. "gopkg.in/check.v1"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
type TypesSuite struct{}
|
||||
|
||||
var _ = Suite(&TypesSuite{})
|
||||
|
||||
func (TypesSuite) TestGenerateFileMetaDefault(c *C) {
|
||||
func TestGenerateFileMetaDefault(t *testing.T) {
|
||||
// default is sha512
|
||||
r := bytes.NewReader([]byte("foo"))
|
||||
meta, err := NewFileMeta(r, "sha512")
|
||||
c.Assert(err, IsNil)
|
||||
c.Assert(meta.Length, Equals, int64(3))
|
||||
assert.NoError(t, err, "Unexpected error.")
|
||||
assert.Equal(t, meta.Length, int64(3), "Meta did not have expected Length field value")
|
||||
hashes := meta.Hashes
|
||||
c.Assert(hashes, HasLen, 1)
|
||||
assert.Len(t, hashes, 1, "Only expected one hash to be present")
|
||||
hash, ok := hashes["sha512"]
|
||||
if !ok {
|
||||
c.Fatal("missing sha512 hash")
|
||||
t.Fatal("missing sha512 hash")
|
||||
}
|
||||
c.Assert(hash.String(), DeepEquals, "f7fbba6e0636f890e56fbbf3283e524c6fa3204ae298382d624741d0dc6638326e282c41be5e4254d8820772c5518a2c5a8c0c7f7eda19594a7eb539453e1ed7")
|
||||
assert.Equal(t, "f7fbba6e0636f890e56fbbf3283e524c6fa3204ae298382d624741d0dc6638326e282c41be5e4254d8820772c5518a2c5a8c0c7f7eda19594a7eb539453e1ed7", hex.EncodeToString(hash), "Hashes not equal")
|
||||
}
|
||||
|
||||
func (TypesSuite) TestGenerateFileMetaExplicit(c *C) {
|
||||
func TestGenerateFileMetaExplicit(t *testing.T) {
|
||||
r := bytes.NewReader([]byte("foo"))
|
||||
meta, err := NewFileMeta(r, "sha256", "sha512")
|
||||
c.Assert(err, IsNil)
|
||||
c.Assert(meta.Length, Equals, int64(3))
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, meta.Length, int64(3))
|
||||
hashes := meta.Hashes
|
||||
c.Assert(hashes, HasLen, 2)
|
||||
assert.Len(t, hashes, 2)
|
||||
for name, val := range map[string]string{
|
||||
"sha256": "2c26b46b68ffc68ff99b453c1d30413413422d706483bfa0f98a5e886266e7ae",
|
||||
"sha512": "f7fbba6e0636f890e56fbbf3283e524c6fa3204ae298382d624741d0dc6638326e282c41be5e4254d8820772c5518a2c5a8c0c7f7eda19594a7eb539453e1ed7",
|
||||
} {
|
||||
hash, ok := hashes[name]
|
||||
if !ok {
|
||||
c.Fatalf("missing %s hash", name)
|
||||
t.Fatalf("missing %s hash", name)
|
||||
}
|
||||
c.Assert(hash.String(), DeepEquals, val)
|
||||
assert.Equal(t, hex.EncodeToString(hash), val)
|
||||
}
|
||||
}
|
||||
|
||||
func (TypesSuite) TestSignatureUnmarshalJSON(c *C) {
|
||||
func TestSignatureUnmarshalJSON(t *testing.T) {
|
||||
signatureJSON := `{"keyid":"97e8e1b51b6e7cf8720a56b5334bd8692ac5b28233c590b89fab0b0cd93eeedc","method":"RSA","sig":"2230cba525e4f5f8fc744f234221ca9a92924da4cc5faf69a778848882fcf7a20dbb57296add87f600891f2569a9c36706314c240f9361c60fd36f5a915a0e9712fc437b761e8f480868d7a4444724daa0d29a2669c0edbd4046046649a506b3d711d0aa5e70cb9d09dec7381e7de27a3168e77731e08f6ed56fcce2478855e837816fb69aff53412477748cd198dce783850080d37aeb929ad0f81460ebd31e61b772b6c7aa56977c787d4281fa45dbdefbb38d449eb5bccb2702964a52c78811545939712c8280dee0b23b2fa9fbbdd6a0c42476689ace655eba0745b4a21ba108bcd03ad00fdefff416dc74e08486a0538f8fd24989e1b9fc89e675141b7c"}`
|
||||
|
||||
var sig Signature
|
||||
err := json.Unmarshal([]byte(signatureJSON), &sig)
|
||||
c.Assert(err, IsNil)
|
||||
assert.NoError(t, err)
|
||||
|
||||
// Check that the method string is lowercased
|
||||
c.Assert(sig.Method.String(), Equals, "rsa")
|
||||
assert.Equal(t, sig.Method.String(), "rsa")
|
||||
}
|
||||
|
|
|
@ -4,45 +4,38 @@ import (
|
|||
"encoding/json"
|
||||
"testing"
|
||||
|
||||
. "gopkg.in/check.v1"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
// Hook up gocheck into the "go test" runner.
|
||||
func Test(t *testing.T) { TestingT(t) }
|
||||
|
||||
type EncryptedSuite struct{}
|
||||
|
||||
var _ = Suite(&EncryptedSuite{})
|
||||
|
||||
var plaintext = []byte("reallyimportant")
|
||||
|
||||
func (EncryptedSuite) TestRoundtrip(c *C) {
|
||||
func TestRoundtrip(t *testing.T) {
|
||||
passphrase := []byte("supersecret")
|
||||
|
||||
enc, err := Encrypt(plaintext, passphrase)
|
||||
c.Assert(err, IsNil)
|
||||
assert.NoError(t, err)
|
||||
|
||||
// successful decrypt
|
||||
dec, err := Decrypt(enc, passphrase)
|
||||
c.Assert(err, IsNil)
|
||||
c.Assert(dec, DeepEquals, plaintext)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, dec, plaintext)
|
||||
|
||||
// wrong passphrase
|
||||
passphrase[0] = 0
|
||||
dec, err = Decrypt(enc, passphrase)
|
||||
c.Assert(err, NotNil)
|
||||
c.Assert(dec, IsNil)
|
||||
assert.Error(t, err)
|
||||
assert.Nil(t, dec)
|
||||
}
|
||||
|
||||
func (EncryptedSuite) TestTamperedRoundtrip(c *C) {
|
||||
func TestTamperedRoundtrip(t *testing.T) {
|
||||
passphrase := []byte("supersecret")
|
||||
|
||||
enc, err := Encrypt(plaintext, passphrase)
|
||||
c.Assert(err, IsNil)
|
||||
assert.NoError(t, err)
|
||||
|
||||
data := &data{}
|
||||
err = json.Unmarshal(enc, data)
|
||||
c.Assert(err, IsNil)
|
||||
assert.NoError(t, err)
|
||||
|
||||
data.Ciphertext[0] = 0
|
||||
data.Ciphertext[1] = 0
|
||||
|
@ -50,15 +43,15 @@ func (EncryptedSuite) TestTamperedRoundtrip(c *C) {
|
|||
enc, _ = json.Marshal(data)
|
||||
|
||||
dec, err := Decrypt(enc, passphrase)
|
||||
c.Assert(err, NotNil)
|
||||
c.Assert(dec, IsNil)
|
||||
assert.Error(t, err)
|
||||
assert.Nil(t, dec)
|
||||
}
|
||||
|
||||
func (EncryptedSuite) TestDecrypt(c *C) {
|
||||
func TestDecrypt(t *testing.T) {
|
||||
enc := []byte(`{"kdf":{"name":"scrypt","params":{"N":32768,"r":8,"p":1},"salt":"N9a7x5JFGbrtB2uBR81jPwp0eiLR4A7FV3mjVAQrg1g="},"cipher":{"name":"nacl/secretbox","nonce":"2h8HxMmgRfuYdpswZBQaU3xJ1nkA/5Ik"},"ciphertext":"SEW6sUh0jf2wfdjJGPNS9+bkk2uB+Cxamf32zR8XkQ=="}`)
|
||||
passphrase := []byte("supersecret")
|
||||
|
||||
dec, err := Decrypt(enc, passphrase)
|
||||
c.Assert(err, IsNil)
|
||||
c.Assert(dec, DeepEquals, plaintext)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, dec, plaintext)
|
||||
}
|
||||
|
|
|
@ -1,8 +1,11 @@
|
|||
package signed
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/Sirupsen/logrus"
|
||||
"github.com/endophage/gotuf/data"
|
||||
"github.com/endophage/gotuf/errors"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// Sign takes a data.Signed and a key, calculated and adds the signature
|
||||
|
@ -17,7 +20,7 @@ func Sign(service CryptoService, s *data.Signed, keys ...data.PublicKey) error {
|
|||
keyIDMemb[key.ID()] = struct{}{}
|
||||
keyIDs = append(keyIDs, key.ID())
|
||||
}
|
||||
logrus.Debugf("Generated list of signing IDs: %v", keyIDs)
|
||||
logrus.Debugf("Generated list of signing IDs: %s", strings.Join(keyIDs, ", "))
|
||||
for _, sig := range s.Signatures {
|
||||
if _, ok := keyIDMemb[sig.KeyID]; ok {
|
||||
continue
|
||||
|
@ -28,6 +31,12 @@ func Sign(service CryptoService, s *data.Signed, keys ...data.PublicKey) error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if len(newSigs) < 1 {
|
||||
return errors.ErrInsufficientSignatures{
|
||||
Name: fmt.Sprint("Cryptoservice failed to produce any signatures for keys with IDs: %s", strings.Join(keyIDs, ", ")),
|
||||
Err: nil,
|
||||
}
|
||||
}
|
||||
logrus.Debugf("appending %d new signatures", len(newSigs))
|
||||
s.Signatures = append(signatures, newSigs...)
|
||||
return nil
|
||||
|
|
|
@ -15,6 +15,31 @@ const (
|
|||
testKeyID2 = "26f2f5c0fbfa98823bf1ad39d5f3b32575895793baf80f1df675597d5b95dba8"
|
||||
)
|
||||
|
||||
type FailingCryptoService struct {
|
||||
testKey data.PublicKey
|
||||
}
|
||||
|
||||
func (mts *FailingCryptoService) Sign(keyIDs []string, _ []byte) ([]data.Signature, error) {
|
||||
sigs := make([]data.Signature, 0, len(keyIDs))
|
||||
return sigs, nil
|
||||
}
|
||||
|
||||
func (mts *FailingCryptoService) Create(_ string, _ data.KeyAlgorithm) (data.PublicKey, error) {
|
||||
return mts.testKey, nil
|
||||
}
|
||||
|
||||
func (mts *FailingCryptoService) GetKey(keyID string) data.PublicKey {
|
||||
if keyID == "testID" {
|
||||
return mts.testKey
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (mts *FailingCryptoService) RemoveKey(keyID string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
type MockCryptoService struct {
|
||||
testKey data.PublicKey
|
||||
}
|
||||
|
@ -114,6 +139,22 @@ func TestMultiSign(t *testing.T) {
|
|||
|
||||
}
|
||||
|
||||
func TestSignReturnsNoSigs(t *testing.T) {
|
||||
failingCryptoService := &FailingCryptoService{}
|
||||
testData := data.Signed{}
|
||||
|
||||
testKey, _ := pem.Decode([]byte(testKeyPEM1))
|
||||
key := data.NewPublicKey(data.RSAKey, testKey.Bytes)
|
||||
err := Sign(failingCryptoService, &testData, key)
|
||||
|
||||
if err == nil {
|
||||
t.Fatalf("Expected failure due to no signature being returned by the crypto service")
|
||||
}
|
||||
if len(testData.Signatures) != 0 {
|
||||
t.Fatalf("Incorrect number of signatures, expected 0: %d", len(testData.Signatures))
|
||||
}
|
||||
}
|
||||
|
||||
func TestCreate(t *testing.T) {
|
||||
testKey, _ := pem.Decode([]byte(testKeyPEM1))
|
||||
k := data.NewPublicKey(data.RSAKey, testKey.Bytes)
|
||||
|
|
|
@ -4,6 +4,7 @@ import (
|
|||
"bytes"
|
||||
"crypto"
|
||||
"crypto/ecdsa"
|
||||
"crypto/elliptic"
|
||||
"crypto/rand"
|
||||
"crypto/rsa"
|
||||
"crypto/sha256"
|
||||
|
@ -272,6 +273,40 @@ func TestECDSAVerifier(t *testing.T) {
|
|||
assert.NoError(t, err, "expecting success but got error while verifying data using ECDSA")
|
||||
}
|
||||
|
||||
func TestECDSAVerifierOtherCurves(t *testing.T) {
|
||||
curves := []elliptic.Curve{elliptic.P224(), elliptic.P256(), elliptic.P384(), elliptic.P521()}
|
||||
|
||||
for _, curve := range curves {
|
||||
ecdsaPrivKey, err := ecdsa.GenerateKey(curve, rand.Reader)
|
||||
|
||||
// Get a DER-encoded representation of the PublicKey
|
||||
ecdsaPubBytes, err := x509.MarshalPKIXPublicKey(&ecdsaPrivKey.PublicKey)
|
||||
assert.NoError(t, err, "failed to marshal public key")
|
||||
|
||||
// Get a DER-encoded representation of the PrivateKey
|
||||
ecdsaPrivKeyBytes, err := x509.MarshalECPrivateKey(ecdsaPrivKey)
|
||||
assert.NoError(t, err, "failed to marshal private key")
|
||||
|
||||
testECDSAKey := data.NewPrivateKey(data.ECDSAKey, ecdsaPubBytes, ecdsaPrivKeyBytes)
|
||||
|
||||
// Sign some data using ECDSA
|
||||
message := []byte("test data for signing")
|
||||
hashed := sha256.Sum256(message)
|
||||
signedData, err := ecdsaSign(testECDSAKey, hashed[:])
|
||||
assert.NoError(t, err)
|
||||
|
||||
// Create and call Verify on the verifier
|
||||
ecdsaVerifier := ECDSAVerifier{}
|
||||
err = ecdsaVerifier.Verify(testECDSAKey, signedData, message)
|
||||
assert.NoError(t, err, "expecting success but got error while verifying data using ECDSA")
|
||||
|
||||
// Make sure an invalid signature fails verification
|
||||
signedData[0]++
|
||||
err = ecdsaVerifier.Verify(testECDSAKey, signedData, message)
|
||||
assert.Error(t, err, "expecting error but got success while verifying data using ECDSA")
|
||||
}
|
||||
}
|
||||
|
||||
func TestECDSAx509Verifier(t *testing.T) {
|
||||
var testECDSAKey data.TUFKey
|
||||
var jsonKey bytes.Buffer
|
||||
|
|
|
@ -4,21 +4,14 @@ import (
|
|||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
cjson "github.com/tent/canonical-json-go"
|
||||
. "gopkg.in/check.v1"
|
||||
|
||||
"github.com/endophage/gotuf/data"
|
||||
"github.com/endophage/gotuf/keys"
|
||||
)
|
||||
|
||||
// Hook up gocheck into the "go test" runner.
|
||||
func Test(t *testing.T) { TestingT(t) }
|
||||
|
||||
type VerifySuite struct{}
|
||||
|
||||
var _ = Suite(&VerifySuite{})
|
||||
|
||||
func (VerifySuite) Test(c *C) {
|
||||
func Test(t *testing.T) {
|
||||
cryptoService := NewEd25519()
|
||||
type test struct {
|
||||
name string
|
||||
|
@ -141,68 +134,68 @@ func (VerifySuite) Test(c *C) {
|
|||
err: ErrExpired{expiredTime.Format("2006-01-02 15:04:05 MST")},
|
||||
},
|
||||
}
|
||||
for _, t := range tests {
|
||||
if t.role == "" {
|
||||
t.role = "root"
|
||||
for _, run := range tests {
|
||||
if run.role == "" {
|
||||
run.role = "root"
|
||||
}
|
||||
if t.ver == 0 {
|
||||
t.ver = minVer
|
||||
if run.ver == 0 {
|
||||
run.ver = minVer
|
||||
}
|
||||
if t.exp == nil {
|
||||
if run.exp == nil {
|
||||
expires := time.Now().Add(time.Hour)
|
||||
t.exp = &expires
|
||||
run.exp = &expires
|
||||
}
|
||||
if t.typ == "" {
|
||||
t.typ = data.TUFTypes[t.role]
|
||||
if run.typ == "" {
|
||||
run.typ = data.TUFTypes[run.role]
|
||||
}
|
||||
if t.keys == nil && t.s == nil {
|
||||
if run.keys == nil && run.s == nil {
|
||||
k, _ := cryptoService.Create("root", data.ED25519Key)
|
||||
meta := &signedMeta{Type: t.typ, Version: t.ver, Expires: t.exp.Format("2006-01-02 15:04:05 MST")}
|
||||
meta := &signedMeta{Type: run.typ, Version: run.ver, Expires: run.exp.Format("2006-01-02 15:04:05 MST")}
|
||||
|
||||
b, err := cjson.Marshal(meta)
|
||||
c.Assert(err, IsNil)
|
||||
assert.NoError(t, err)
|
||||
s := &data.Signed{Signed: b}
|
||||
Sign(cryptoService, s, k)
|
||||
t.s = s
|
||||
t.keys = []data.PublicKey{k}
|
||||
run.s = s
|
||||
run.keys = []data.PublicKey{k}
|
||||
}
|
||||
if t.roles == nil {
|
||||
t.roles = map[string]*data.Role{
|
||||
if run.roles == nil {
|
||||
run.roles = map[string]*data.Role{
|
||||
"root": &data.Role{
|
||||
RootRole: data.RootRole{
|
||||
KeyIDs: []string{t.keys[0].ID()},
|
||||
KeyIDs: []string{run.keys[0].ID()},
|
||||
Threshold: 1,
|
||||
},
|
||||
Name: "root",
|
||||
},
|
||||
}
|
||||
}
|
||||
if t.mut != nil {
|
||||
t.mut(&t)
|
||||
if run.mut != nil {
|
||||
run.mut(&run)
|
||||
}
|
||||
|
||||
db := keys.NewDB()
|
||||
for _, k := range t.keys {
|
||||
for _, k := range run.keys {
|
||||
db.AddKey(k)
|
||||
}
|
||||
for _, r := range t.roles {
|
||||
for _, r := range run.roles {
|
||||
err := db.AddRole(r)
|
||||
c.Assert(err, IsNil)
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
|
||||
err := Verify(t.s, t.role, minVer, db)
|
||||
if e, ok := t.err.(ErrExpired); ok {
|
||||
assertErrExpired(c, err, e)
|
||||
err := Verify(run.s, run.role, minVer, db)
|
||||
if e, ok := run.err.(ErrExpired); ok {
|
||||
assertErrExpired(t, err, e)
|
||||
} else {
|
||||
c.Assert(err, DeepEquals, t.err, Commentf("name = %s", t.name))
|
||||
assert.Equal(t, run.err, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func assertErrExpired(c *C, err error, expected ErrExpired) {
|
||||
func assertErrExpired(t *testing.T, err error, expected ErrExpired) {
|
||||
actual, ok := err.(ErrExpired)
|
||||
if !ok {
|
||||
c.Fatalf("expected err to have type ErrExpired, got %T", err)
|
||||
t.Fatalf("expected err to have type ErrExpired, got %T", err)
|
||||
}
|
||||
c.Assert(actual.Expired, Equals, expected.Expired)
|
||||
assert.Equal(t, actual.Expired, expected.Expired)
|
||||
}
|
||||
|
|
|
@ -80,11 +80,11 @@ func TestAddBlob(t *testing.T) {
|
|||
t.Fatal("Hashes map has been modified")
|
||||
}
|
||||
|
||||
hash := []bytes{0x01, 0x02}
|
||||
hash := []byte{0x01, 0x02}
|
||||
if sha256[0] != hash[0] || sha256[1] != hash[1] {
|
||||
t.Fatal("SHA256 has been modified")
|
||||
}
|
||||
hash = []bytes{0x03, 0x04}
|
||||
hash = []byte{0x03, 0x04}
|
||||
if sha512[0] != hash[0] || sha512[1] != hash[1] {
|
||||
t.Fatal("SHA512 has been modified")
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@ package store
|
|||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/base64"
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"io"
|
||||
|
@ -11,12 +12,17 @@ import (
|
|||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/tent/canonical-json-go"
|
||||
|
||||
"github.com/endophage/gotuf/data"
|
||||
"github.com/endophage/gotuf/signed"
|
||||
)
|
||||
|
||||
const testRoot = `{"signed":{"_type":"Root","consistent_snapshot":false,"expires":"2025-07-17T16:19:21.101698314-07:00","keys":{"1ca15c7f4b2b0c6efce202a545e7267152da28ab7c91590b3b60bdb4da723aad":{"keytype":"ecdsa","keyval":{"private":null,"public":"MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEb0720c99Cj6ZmuDlznEZ52NA6YpeY9Sj45z51XvPnG63Bi2RSBezMJlPzbSfP39mXKXqOJyT+z9BZhi3FVWczg=="}},"b1d6813b55442ecbfb1f4b40eb1fcdb4290e53434cfc9ba2da24c26c9143873b":{"keytype":"ecdsa-x509","keyval":{"private":null,"public":"LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUJVekNCKzZBREFnRUNBaEFCWDNKLzkzaW8zbHcrZUsvNFhvSHhNQW9HQ0NxR1NNNDlCQU1DTUJFeER6QU4KQmdOVkJBTVRCbVY0Y0dseVpUQWVGdzB4TlRBM01qQXlNekU1TVRkYUZ3MHlOVEEzTVRjeU16RTVNVGRhTUJFeApEekFOQmdOVkJBTVRCbVY0Y0dseVpUQlpNQk1HQnlxR1NNNDlBZ0VHQ0NxR1NNNDlBd0VIQTBJQUJFTDhOTFhQCitreUJZYzhYY0FTMXB2S2l5MXRQUDlCZHJ1dEdrWlR3Z0dEYTM1THMzSUFXaWlrUmlPbGRuWmxVVEE5cG5JekoKOFlRQThhTjQ1TDQvUlplak5UQXpNQTRHQTFVZER3RUIvd1FFQXdJQW9EQVRCZ05WSFNVRUREQUtCZ2dyQmdFRgpCUWNEQXpBTUJnTlZIUk1CQWY4RUFqQUFNQW9HQ0NxR1NNNDlCQU1DQTBjQU1FUUNJRVJ1ZUVURG5xMlRqRFBmClhGRStqUFJqMEtqdXdEOG9HSmtoVGpMUDAycjhBaUI5cUNyL2ZqSXpJZ1NQcTJVSXZqR0hlYmZOYXh1QlpZZUUKYW8xNjd6dHNYZz09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K"}},"fbddae7f25a6c23ca735b017206a849d4c89304a4d8de4dcc4b3d6f3eb22ce3b":{"keytype":"ecdsa","keyval":{"private":null,"public":"MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE/xS5fBHK2HKmlGcvAr06vwPITvmxWP4P3CMDCgY25iSaIiM21OiXA1/Uvo3Pa3xh5G3cwCtDvi+4FpflW2iB/w=="}},"fd75751f010c3442e23b3e3e99a1442a112f2f21038603cb8609d8b17c9e912a":{"keytype":"ed25519","keyval":{"private":null,"public":"rc+glN01m+q8jmX8SolGsjTfk6NMhUQTWyj10hjmne0="}}},"roles":{"root":{"keyids":["b1d6813b55442ecbfb1f4b40eb1fcdb4290e53434cfc9ba2da24c26c9143873b"],"threshold":1},"snapshot":{"keyids":["1ca15c7f4b2b0c6efce202a545e7267152da28ab7c91590b3b60bdb4da723aad"],"threshold":1},"targets":{"keyids":["fbddae7f25a6c23ca735b017206a849d4c89304a4d8de4dcc4b3d6f3eb22ce3b"],"threshold":1},"timestamp":{"keyids":["fd75751f010c3442e23b3e3e99a1442a112f2f21038603cb8609d8b17c9e912a"],"threshold":1}},"version":2},"signatures":[{"keyid":"b1d6813b55442ecbfb1f4b40eb1fcdb4290e53434cfc9ba2da24c26c9143873b","method":"ecdsa","sig":"A2lNVwxHBnD9ViFtRre8r5oG6VvcvJnC6gdvvxv/Jyag40q/fNMjllCqyHrb+6z8XDZcrTTDsFU1R3/e+92d1A=="}]}`
|
||||
|
||||
const testRootKey = "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUJVekNCKzZBREFnRUNBaEFCWDNKLzkzaW8zbHcrZUsvNFhvSHhNQW9HQ0NxR1NNNDlCQU1DTUJFeER6QU4KQmdOVkJBTVRCbVY0Y0dseVpUQWVGdzB4TlRBM01qQXlNekU1TVRkYUZ3MHlOVEEzTVRjeU16RTVNVGRhTUJFeApEekFOQmdOVkJBTVRCbVY0Y0dseVpUQlpNQk1HQnlxR1NNNDlBZ0VHQ0NxR1NNNDlBd0VIQTBJQUJFTDhOTFhQCitreUJZYzhYY0FTMXB2S2l5MXRQUDlCZHJ1dEdrWlR3Z0dEYTM1THMzSUFXaWlrUmlPbGRuWmxVVEE5cG5JekoKOFlRQThhTjQ1TDQvUlplak5UQXpNQTRHQTFVZER3RUIvd1FFQXdJQW9EQVRCZ05WSFNVRUREQUtCZ2dyQmdFRgpCUWNEQXpBTUJnTlZIUk1CQWY4RUFqQUFNQW9HQ0NxR1NNNDlCQU1DQTBjQU1FUUNJRVJ1ZUVURG5xMlRqRFBmClhGRStqUFJqMEtqdXdEOG9HSmtoVGpMUDAycjhBaUI5cUNyL2ZqSXpJZ1NQcTJVSXZqR0hlYmZOYXh1QlpZZUUKYW8xNjd6dHNYZz09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K"
|
||||
|
||||
type TestRoundTripper struct{}
|
||||
|
||||
func (rt *TestRoundTripper) RoundTrip(req *http.Request) (*http.Response, error) {
|
||||
|
@ -24,8 +30,12 @@ func (rt *TestRoundTripper) RoundTrip(req *http.Request) (*http.Response, error)
|
|||
}
|
||||
|
||||
func TestHTTPStoreGetMeta(t *testing.T) {
|
||||
handler := func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Write([]byte(testRoot))
|
||||
}
|
||||
server := httptest.NewServer(http.HandlerFunc(handler))
|
||||
store, err := NewHTTPStore(
|
||||
"http://mirror1.poly.edu/test-pypi/",
|
||||
server.URL,
|
||||
"metadata",
|
||||
"txt",
|
||||
"targets",
|
||||
|
@ -44,8 +54,9 @@ func TestHTTPStoreGetMeta(t *testing.T) {
|
|||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
rootPem := "-----BEGIN PUBLIC KEY-----\nMIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIBigKCAYEArvqUPYb6JJROPJQglPTj\n5uDrsxQKl34Mo+3pSlBVuD6puE4lDnG649a2YksJy+C8ZIPJgokn5w+C3alh+dMe\nzbdWHHxrY1h9CLpYz5cbMlE16303ubkt1rvwDqEezG0HDBzPaKj4oP9YJ9x7wbsq\ndvFcy+Qc3wWd7UWcieo6E0ihbJkYcY8chRXVLg1rL7EfZ+e3bq5+ojA2ECM5JqzZ\nzgDpqCv5hTCYYZp72MZcG7dfSPAHrcSGIrwg7whzz2UsEtCOpsJTuCl96FPN7kAu\n4w/WyM3+SPzzr4/RQXuY1SrLCFD8ebM2zHt/3ATLhPnGmyG5I0RGYoegFaZ2AViw\nlqZDOYnBtgDvKP0zakMtFMbkh2XuNBUBO7Sjs0YcZMjLkh9gYUHL1yWS3Aqus1Lw\nlI0gHS22oyGObVBWkZEgk/Foy08sECLGao+5VvhmGpfVuiz9OKFUmtPVjWzRE4ng\niekEu4drSxpH41inLGSvdByDWLpcTvWQI9nkgclh3AT/AgMBAAE=\n-----END PUBLIC KEY-----"
|
||||
k := data.NewPublicKey("RSA", []byte(rootPem))
|
||||
rootKey, err := base64.StdEncoding.DecodeString(testRootKey)
|
||||
assert.NoError(t, err)
|
||||
k := data.NewPublicKey("ecdsa-x509", rootKey)
|
||||
|
||||
sigBytes := p.Signatures[0].Signature
|
||||
if err != nil {
|
||||
|
|
|
@ -225,15 +225,15 @@ func (tr *TufRepo) InitTargets() error {
|
|||
}
|
||||
|
||||
func (tr *TufRepo) InitSnapshot() error {
|
||||
signedRoot, err := tr.SignRoot(data.DefaultExpires("root"), nil)
|
||||
root, err := tr.Root.ToSigned()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
signedTargets, err := tr.SignTargets("targets", data.DefaultExpires("targets"), nil)
|
||||
targets, err := tr.Targets[data.ValidRoles["targets"]].ToSigned()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
snapshot, err := data.NewSnapshot(signedRoot, signedTargets)
|
||||
snapshot, err := data.NewSnapshot(root, targets)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -242,11 +242,11 @@ func (tr *TufRepo) InitSnapshot() error {
|
|||
}
|
||||
|
||||
func (tr *TufRepo) InitTimestamp() error {
|
||||
signedSnapshot, err := tr.SignSnapshot(data.DefaultExpires("snapshot"), nil)
|
||||
snap, err := tr.Snapshot.ToSigned()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
timestamp, err := data.NewTimestamp(signedSnapshot)
|
||||
timestamp, err := data.NewTimestamp(snap)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -5,17 +5,10 @@ import (
|
|||
"testing"
|
||||
|
||||
"github.com/endophage/gotuf/data"
|
||||
. "gopkg.in/check.v1"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
// Hook up gocheck into the "go test" runner.
|
||||
func Test(t *testing.T) { TestingT(t) }
|
||||
|
||||
type UtilSuite struct{}
|
||||
|
||||
var _ = Suite(&UtilSuite{})
|
||||
|
||||
func (UtilSuite) TestFileMetaEqual(c *C) {
|
||||
func TestFileMetaEqual(t *testing.T) {
|
||||
type test struct {
|
||||
name string
|
||||
b data.FileMeta
|
||||
|
@ -26,7 +19,7 @@ func (UtilSuite) TestFileMetaEqual(c *C) {
|
|||
m := data.FileMeta{Length: length, Hashes: make(map[string][]byte, len(hashes))}
|
||||
for typ, hash := range hashes {
|
||||
v, err := hex.DecodeString(hash)
|
||||
c.Assert(err, IsNil)
|
||||
assert.NoError(t, err, "hash not in hex")
|
||||
m.Hashes[typ] = v
|
||||
}
|
||||
return m
|
||||
|
@ -57,12 +50,12 @@ func (UtilSuite) TestFileMetaEqual(c *C) {
|
|||
err: func(t test) error { return ErrNoCommonHash{t.b.Hashes, t.a.Hashes} },
|
||||
},
|
||||
}
|
||||
for _, t := range tests {
|
||||
c.Assert(FileMetaEqual(t.a, t.b), DeepEquals, t.err(t), Commentf("name = %s", t.name))
|
||||
for _, run := range tests {
|
||||
assert.Equal(t, FileMetaEqual(run.a, run.b), run.err(run), "Files not equivalent")
|
||||
}
|
||||
}
|
||||
|
||||
func (UtilSuite) TestNormalizeTarget(c *C) {
|
||||
func TestNormalizeTarget(t *testing.T) {
|
||||
for before, after := range map[string]string{
|
||||
"": "/",
|
||||
"foo.txt": "/foo.txt",
|
||||
|
@ -71,14 +64,14 @@ func (UtilSuite) TestNormalizeTarget(c *C) {
|
|||
"/with/./a/dot": "/with/a/dot",
|
||||
"/with/double/../dot": "/with/dot",
|
||||
} {
|
||||
c.Assert(NormalizeTarget(before), Equals, after)
|
||||
assert.Equal(t, NormalizeTarget(before), after, "Path normalization did not output expected.")
|
||||
}
|
||||
}
|
||||
|
||||
func (UtilSuite) TestHashedPaths(c *C) {
|
||||
func TestHashedPaths(t *testing.T) {
|
||||
hexBytes := func(s string) []byte {
|
||||
v, err := hex.DecodeString(s)
|
||||
c.Assert(err, IsNil)
|
||||
assert.NoError(t, err, "String was not hex")
|
||||
return v
|
||||
}
|
||||
hashes := data.Hashes{
|
||||
|
@ -87,11 +80,11 @@ func (UtilSuite) TestHashedPaths(c *C) {
|
|||
}
|
||||
paths := HashedPaths("foo/bar.txt", hashes)
|
||||
// cannot use DeepEquals as the returned order is non-deterministic
|
||||
c.Assert(paths, HasLen, 2)
|
||||
assert.Len(t, paths, 2, "Expected 2 paths")
|
||||
expected := map[string]struct{}{"foo/abc123.bar.txt": {}, "foo/def456.bar.txt": {}}
|
||||
for _, path := range paths {
|
||||
if _, ok := expected[path]; !ok {
|
||||
c.Fatalf("unexpected path: %s", path)
|
||||
t.Fatalf("unexpected path: %s", path)
|
||||
}
|
||||
delete(expected, path)
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@ import (
|
|||
"github.com/endophage/gotuf"
|
||||
tufclient "github.com/endophage/gotuf/client"
|
||||
"github.com/endophage/gotuf/data"
|
||||
tuferrors "github.com/endophage/gotuf/errors"
|
||||
"github.com/endophage/gotuf/keys"
|
||||
"github.com/endophage/gotuf/signed"
|
||||
"github.com/endophage/gotuf/store"
|
||||
|
@ -207,7 +208,21 @@ func (r *NotaryRepository) Initialize(uCryptoService *cryptoservice.UnlockedCryp
|
|||
|
||||
r.tufRepo = tuf.NewTufRepo(kdb, r.cryptoService)
|
||||
|
||||
if err := r.tufRepo.InitRepo(false); err != nil {
|
||||
err = r.tufRepo.InitRoot(false)
|
||||
if err != nil {
|
||||
logrus.Debug("Error on InitRoot: ", err.Error())
|
||||
if _, ok := err.(tuferrors.ErrInsufficientSignatures); !ok {
|
||||
return err
|
||||
}
|
||||
}
|
||||
err = r.tufRepo.InitTargets()
|
||||
if err != nil {
|
||||
logrus.Debug("Error on InitTargets: ", err.Error())
|
||||
return err
|
||||
}
|
||||
err = r.tufRepo.InitSnapshot()
|
||||
if err != nil {
|
||||
logrus.Debug("Error on InitSnapshot: ", err.Error())
|
||||
return err
|
||||
}
|
||||
|
||||
|
|
|
@ -66,6 +66,10 @@ func validateRootSuccessfully(t *testing.T, rootType data.KeyAlgorithm) {
|
|||
err = repo.Initialize(rootCryptoService)
|
||||
assert.NoError(t, err, "error creating repository: %s", err)
|
||||
|
||||
// tests need to manually boostrap timestamp as client doesn't generate it
|
||||
err = repo.tufRepo.InitTimestamp()
|
||||
assert.NoError(t, err, "error creating repository: %s", err)
|
||||
|
||||
// Initialize is supposed to have created new certificate for this repository
|
||||
// Lets check for it and store it for later use
|
||||
allCerts := repo.KeyStoreManager.TrustedCertificateStore().GetCertificates()
|
||||
|
|
|
@ -219,6 +219,10 @@ func testAddListTarget(t *testing.T, rootType data.KeyAlgorithm) {
|
|||
err = repo.Initialize(rootCryptoService)
|
||||
assert.NoError(t, err, "error creating repository: %s", err)
|
||||
|
||||
// tests need to manually boostrap timestamp as client doesn't generate it
|
||||
err = repo.tufRepo.InitTimestamp()
|
||||
assert.NoError(t, err, "error creating repository: %s", err)
|
||||
|
||||
// Add fixtures/intermediate-ca.crt as a target. There's no particular reason
|
||||
// for using this file except that it happens to be available as
|
||||
// a fixture.
|
||||
|
|
Loading…
Reference in New Issue