mirror of https://github.com/docker/docs.git
commit
cab1006568
|
@ -47,7 +47,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/endophage/gotuf",
|
"ImportPath": "github.com/endophage/gotuf",
|
||||||
"Rev": "88765abdd5ec33be6be1efa18c71d7f43c7c4983"
|
"Rev": "af7152a51a0663dc47768e591ffdfa1f60e5308a"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/go-sql-driver/mysql",
|
"ImportPath": "github.com/go-sql-driver/mysql",
|
||||||
|
|
|
@ -57,12 +57,12 @@ func (c *Client) Update() error {
|
||||||
func (c *Client) update() error {
|
func (c *Client) update() error {
|
||||||
err := c.downloadTimestamp()
|
err := c.downloadTimestamp()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logrus.Errorf("Client Update (Timestamp): ", err.Error())
|
logrus.Errorf("Client Update (Timestamp): %s", err.Error())
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
err = c.downloadSnapshot()
|
err = c.downloadSnapshot()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logrus.Errorf("Client Update (Snapshot): ", err.Error())
|
logrus.Errorf("Client Update (Snapshot): %s", err.Error())
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
err = c.checkRoot()
|
err = c.checkRoot()
|
||||||
|
@ -71,7 +71,7 @@ func (c *Client) update() error {
|
||||||
}
|
}
|
||||||
err = c.downloadTargets("targets")
|
err = c.downloadTargets("targets")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logrus.Errorf("Client Update (Targets): ", err.Error())
|
logrus.Errorf("Client Update (Targets): %s", err.Error())
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
|
|
@ -1,150 +0,0 @@
|
||||||
package client
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/json"
|
|
||||||
"io/ioutil"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/Sirupsen/logrus"
|
|
||||||
tuf "github.com/endophage/gotuf"
|
|
||||||
"github.com/endophage/gotuf/data"
|
|
||||||
"github.com/endophage/gotuf/keys"
|
|
||||||
"github.com/endophage/gotuf/store"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestClientUpdate(t *testing.T) {
|
|
||||||
pypiRoot := `{
|
|
||||||
"signatures": [
|
|
||||||
{
|
|
||||||
"keyid": "92db731bf30e31c13e775360453f0adc8bfd3107f5000b99431c4bdbcebb31ed",
|
|
||||||
"method": "PyCrypto-PKCS#1 PSS",
|
|
||||||
"sig": "31d1fa4712eaf591b367740f69ba7577fb5565863639d7e89145abe159f047d5f848e7696fbaf16f5c4214e1f2295d14e3078f5c0a6e2cbc015c13f8557836a039208970b436bb13b921f86f3e4d4518ce2f731bd7a55083d45634f206dc92e886daeb15e65a513f6451575811e9e44b5573d6999d4b69f86a27f01d0d9a868a535a1f0f6534bd9e555d4df95f019ea6859c83fca30e95e0d1c2ce1dcb2b19c91facd98a7cae9f4c81b5ff4c12980f333e38eac99f4561a8f9e5342382443f165cf0af840d5c61b62698b27413d7f5e1bdba714b98759bcfc7c3d65c567459ce093c66c88ebae836665bcdf2efc1e6921bd792406c0529dab2678a922e5fa6ef39e92f89d3072a22bd755a49b2e2e2c801ce73006fd8a7f56595fae01af3e2a49a3bce4ce9fcaec43e1aae5b0c0fc807bc4caca9fae7c34ff026a417262b5435cfd6cbf17b70aae041eae30a6bd6a857db88566c89f2c02171674b9195f22a84ec5839a4e46e2e63fbb5d4821ae66237ea261846c7d5a341d5f4ab2e12412d4e"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"signed": {
|
|
||||||
"_type": "Root",
|
|
||||||
"expires": "2014-08-31 00:49:33 UTC",
|
|
||||||
"keys": {
|
|
||||||
"07f12f6c470e60d49fe6a60cd893dfba870db387083d50fe4fc43c6171a0be59": {
|
|
||||||
"keytype": "rsa",
|
|
||||||
"keyval": {
|
|
||||||
"private": "",
|
|
||||||
"public": "-----BEGIN PUBLIC KEY-----\nMIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIBigKCAYEAtb4vuMJF1kOc1deExdqV\nZ3o9W6zulfRDX6u8Exd3NEL0/9bCYluqpshFzgmDYpCsuS79Ve5S8WgXAnEXyWOf\nHL/FnAVqFSnmgmYr52waMYV57BsNMY8pXxOnJm1opUbt0PdnF2D2yfLLY8IgZ/0m\niJ+gWojwEBMRlTOnHFx+l/UVvZAhpVsua6C8C2ThFLrXlmmtkg5BAIm1kWPsZ0nB\n3Cczcwh8zE0l2ytVi458AuRGKwi1TMIGXl064ekjsWexH1zCuoEcv/CKob0BkL4c\nLFUKe6WD6XlEp/xnMh6lNG8LT+UKzSb1hPkTtt23RntFB4Qx7UUT8LoO79bv6coE\njeEqHltmeohHpVmTLWsbTdaX7W3clWPUErGh5kAO0SJu1EM94p5nGWlZ+kwASxtO\nz1qR8AqQ02HBBQU+cY24CNnOwKDq/Kgsg1Aw7bqglvtUwBUQkuuCuisjHI0bSMFr\ntGIhlswxItfQ709/OMrN44Vw/H/Z50UzGFtRlu1h07/vAgMBAAE=\n-----END PUBLIC KEY-----"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"2d9f41a1b79429e9d950a687fe00da0bb4fd751da98aeade1524b8d28968eb89": {
|
|
||||||
"keytype": "rsa",
|
|
||||||
"keyval": {
|
|
||||||
"private": "",
|
|
||||||
"public": "-----BEGIN PUBLIC KEY-----\nMIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIBigKCAYEAmjt8CIbohZxZQ1+I8CQn\nvugLsGXq1G2OiMZvbN281q1/E1futll3+EnfxPLP0SBlyYxixma/ozoMj94lPyOX\nBbiF/U1WJ0Wp5D1kpT0Jzt9Ar0bkRxWoPhubeJ7D4k8Br2m7aG+wchfozdbMmUwK\n/MiAZ1fmpKQAr1ek3/hJiN/dURw+mQEdgXwgA4raDy4Ty3AkG7SDCG1cYoYYMJa3\nKg82AWISQQEHUO1MwRVBon2B5d2UriUEzsYYi+2whDOekchjgyd2xdcRvdCBbdGv\nJBCtzVZpd52lCwqAMJUyDGre6Mb6NmKC2nuk+TYEujqRQK97LnjmPwI42b4cBHqv\nDtg7Z8K3rEQIyD+VvrcWlu+1cE8drjh3y+r7oTtjRPr1M8xaCWn/dh8huSJmaFlk\nmWKDX9KI3/5pxFjgpry20eBRYkZHJWwByc9GVvwhRsIF61QdKvA6uGqkFHy9YQBW\nnzWTPo/4UTUwcpfjneoyMOVKx2K05ZePa5UNAgJVDgFfAgMBAAE=\n-----END PUBLIC KEY-----"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"92db731bf30e31c13e775360453f0adc8bfd3107f5000b99431c4bdbcebb31ed": {
|
|
||||||
"keytype": "rsa",
|
|
||||||
"keyval": {
|
|
||||||
"private": "",
|
|
||||||
"public": "-----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-----"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"e1ccde549849bb6aa548412e79c407c93f303f3a3ca0ab1e5923ff7d5c4de769": {
|
|
||||||
"keytype": "rsa",
|
|
||||||
"keyval": {
|
|
||||||
"private": "",
|
|
||||||
"public": "-----BEGIN PUBLIC KEY-----\nMIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIBigKCAYEAqnNAzjIb73u2Nk+r2AdU\nnK+xvKDcZgIzjSzRVjtRJgu3MVffzPcGIsjv2RS8/LLl8nSf48V+tWZf/PnTzkMn\n1iJhbdOQTt6bABiizm5dLP9Jm/AIMTTUpbu+fpFbV8vNH+qM5/Z0WNOptQnOEfNs\n84MNh919lJjHc5VPTw86h68Mkn7W5RChZqnwEv75M1XfWdAnUGeLfZh6BKxFMnaB\nciYxieUvc1bnCtqsdaDE2Ab86WXM7cmNCqyLAh4JkTV+RcMzqEnZCAm68TkO6gM/\n5g4A7fbnn9Jc4O3fJvu80fYOg63nS6hAFldmN74oYu2h5PV75xyTIEERoXqJbSaj\n1Agj/98khIZGsSVjoQ5Mi7ETcSbsH7rqWdHFIu+dbKw8vlnqWnEQYjXA8CIOY3X7\nB6/u5FBS5AdxjO6AR/MuaqpWdDTZwXwgZ9c4wqO4Re4z73sGM1PugUK4dbXIGwVe\nRtzv7cSFOB7OPmj53miJWt2ILACb+Dpnxt9h6TzT1C0JAgMBAAE=\n-----END PUBLIC KEY-----"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"roles": {
|
|
||||||
"release": {
|
|
||||||
"keyids": [
|
|
||||||
"e1ccde549849bb6aa548412e79c407c93f303f3a3ca0ab1e5923ff7d5c4de769"
|
|
||||||
],
|
|
||||||
"threshold": 1
|
|
||||||
},
|
|
||||||
"root": {
|
|
||||||
"keyids": [
|
|
||||||
"92db731bf30e31c13e775360453f0adc8bfd3107f5000b99431c4bdbcebb31ed"
|
|
||||||
],
|
|
||||||
"threshold": 1
|
|
||||||
},
|
|
||||||
"targets": {
|
|
||||||
"keyids": [
|
|
||||||
"07f12f6c470e60d49fe6a60cd893dfba870db387083d50fe4fc43c6171a0be59"
|
|
||||||
],
|
|
||||||
"threshold": 1
|
|
||||||
},
|
|
||||||
"timestamp": {
|
|
||||||
"keyids": [
|
|
||||||
"2d9f41a1b79429e9d950a687fe00da0bb4fd751da98aeade1524b8d28968eb89"
|
|
||||||
],
|
|
||||||
"threshold": 1
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"version": 1
|
|
||||||
}
|
|
||||||
}`
|
|
||||||
|
|
||||||
data.SetTUFTypes(
|
|
||||||
map[string]string{
|
|
||||||
"snapshot": "Release",
|
|
||||||
},
|
|
||||||
)
|
|
||||||
data.SetValidRoles(
|
|
||||||
map[string]string{
|
|
||||||
"snapshot": "release",
|
|
||||||
},
|
|
||||||
)
|
|
||||||
|
|
||||||
s := &data.Signed{}
|
|
||||||
err := json.Unmarshal([]byte(pypiRoot), s)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
kdb := keys.NewDB()
|
|
||||||
|
|
||||||
logrus.SetLevel(logrus.DebugLevel)
|
|
||||||
|
|
||||||
// Being able to set the second argument, signer, to nil is a great
|
|
||||||
// test as we shouldn't need to instantiate a signer just for reading
|
|
||||||
// a repo.
|
|
||||||
repo := tuf.NewTufRepo(kdb, nil)
|
|
||||||
repo.SetRoot(s)
|
|
||||||
remote, err := store.NewHTTPStore(
|
|
||||||
"http://mirror1.poly.edu/test-pypi/",
|
|
||||||
"metadata",
|
|
||||||
"txt",
|
|
||||||
"targets",
|
|
||||||
)
|
|
||||||
cached := store.NewFileCacheStore(remote, "/tmp/tuf")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
client := Client{
|
|
||||||
local: repo,
|
|
||||||
remote: cached,
|
|
||||||
keysDB: kdb,
|
|
||||||
}
|
|
||||||
|
|
||||||
err = client.Update()
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
testTarget := "packages/2.3/T/TracHTTPAuth/TracHTTPAuth-1.0.1-py2.3.egg"
|
|
||||||
expectedHash := "dbcaa6dc0035a636234f9b457d24bf1aeecac0a29b4da97a3b32692f2729f9db"
|
|
||||||
expectedSize := int64(8140)
|
|
||||||
m := client.TargetMeta(testTarget)
|
|
||||||
if m == nil {
|
|
||||||
t.Fatal("Failed to find existing target")
|
|
||||||
}
|
|
||||||
if m.Hashes["sha256"].String() != expectedHash {
|
|
||||||
t.Fatal("Target hash incorrect.\nExpected:", expectedHash, "\nReceived:", m.Hashes["sha256"].String())
|
|
||||||
}
|
|
||||||
if m.Length != expectedSize {
|
|
||||||
t.Fatal("Target size incorrect.\nExpected:", expectedSize, "\nReceived:", m.Length)
|
|
||||||
}
|
|
||||||
err = client.DownloadTarget(ioutil.Discard, testTarget, m)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
}
|
|
45
Godeps/_workspace/src/github.com/endophage/gotuf/data/types_test.go
generated
vendored
Normal file
45
Godeps/_workspace/src/github.com/endophage/gotuf/data/types_test.go
generated
vendored
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
package data
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
|
||||||
|
. "gopkg.in/check.v1"
|
||||||
|
)
|
||||||
|
|
||||||
|
type TypesSuite struct{}
|
||||||
|
|
||||||
|
var _ = Suite(&TypesSuite{})
|
||||||
|
|
||||||
|
func (TypesSuite) TestGenerateFileMetaDefault(c *C) {
|
||||||
|
// default is sha512
|
||||||
|
r := bytes.NewReader([]byte("foo"))
|
||||||
|
meta, err := NewFileMeta(r, "sha512")
|
||||||
|
c.Assert(err, IsNil)
|
||||||
|
c.Assert(meta.Length, Equals, int64(3))
|
||||||
|
hashes := meta.Hashes
|
||||||
|
c.Assert(hashes, HasLen, 1)
|
||||||
|
hash, ok := hashes["sha512"]
|
||||||
|
if !ok {
|
||||||
|
c.Fatal("missing sha512 hash")
|
||||||
|
}
|
||||||
|
c.Assert(hash.String(), DeepEquals, "f7fbba6e0636f890e56fbbf3283e524c6fa3204ae298382d624741d0dc6638326e282c41be5e4254d8820772c5518a2c5a8c0c7f7eda19594a7eb539453e1ed7")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (TypesSuite) TestGenerateFileMetaExplicit(c *C) {
|
||||||
|
r := bytes.NewReader([]byte("foo"))
|
||||||
|
meta, err := NewFileMeta(r, "sha256", "sha512")
|
||||||
|
c.Assert(err, IsNil)
|
||||||
|
c.Assert(meta.Length, Equals, int64(3))
|
||||||
|
hashes := meta.Hashes
|
||||||
|
c.Assert(hashes, HasLen, 2)
|
||||||
|
for name, val := range map[string]string{
|
||||||
|
"sha256": "2c26b46b68ffc68ff99b453c1d30413413422d706483bfa0f98a5e886266e7ae",
|
||||||
|
"sha512": "f7fbba6e0636f890e56fbbf3283e524c6fa3204ae298382d624741d0dc6638326e282c41be5e4254d8820772c5518a2c5a8c0c7f7eda19594a7eb539453e1ed7",
|
||||||
|
} {
|
||||||
|
hash, ok := hashes[name]
|
||||||
|
if !ok {
|
||||||
|
c.Fatalf("missing %s hash", name)
|
||||||
|
}
|
||||||
|
c.Assert(hash.String(), DeepEquals, val)
|
||||||
|
}
|
||||||
|
}
|
|
@ -37,7 +37,7 @@ func (trust *Ed25519) Sign(keyIDs []string, toSign []byte) ([]data.Signature, er
|
||||||
sig := ed25519.Sign(&priv, toSign)
|
sig := ed25519.Sign(&priv, toSign)
|
||||||
signatures = append(signatures, data.Signature{
|
signatures = append(signatures, data.Signature{
|
||||||
KeyID: kID,
|
KeyID: kID,
|
||||||
Method: "ed25519",
|
Method: "ED25519",
|
||||||
Signature: sig[:],
|
Signature: sig[:],
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -50,8 +50,8 @@ func (trust *Ed25519) Create(role string) (*data.PublicKey, error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
public := data.NewPublicKey("ed25519", pub[:])
|
public := data.NewPublicKey("ED25519", pub[:])
|
||||||
private := data.NewPrivateKey("ed25519", pub[:], priv[:])
|
private := data.NewPrivateKey("ED25519", pub[:], priv[:])
|
||||||
trust.addKey(private)
|
trust.addKey(private)
|
||||||
return public, nil
|
return public, nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,7 +41,7 @@ var _ CryptoService = &MockCryptoService{}
|
||||||
// Test signing and ensure the expected signature is added
|
// Test signing and ensure the expected signature is added
|
||||||
func TestBasicSign(t *testing.T) {
|
func TestBasicSign(t *testing.T) {
|
||||||
testKey, _ := pem.Decode([]byte(testKeyPEM1))
|
testKey, _ := pem.Decode([]byte(testKeyPEM1))
|
||||||
k := data.NewPublicKey("rsa", testKey.Bytes)
|
k := data.NewPublicKey("RSA", testKey.Bytes)
|
||||||
signer := Signer{&MockCryptoService{
|
signer := Signer{&MockCryptoService{
|
||||||
testKey: *k,
|
testKey: *k,
|
||||||
}}
|
}}
|
||||||
|
@ -68,7 +68,7 @@ func TestBasicSign(t *testing.T) {
|
||||||
// should be cleaning previous signatures by the KeyID when asked to sign again)
|
// should be cleaning previous signatures by the KeyID when asked to sign again)
|
||||||
func TestReSign(t *testing.T) {
|
func TestReSign(t *testing.T) {
|
||||||
testKey, _ := pem.Decode([]byte(testKeyPEM1))
|
testKey, _ := pem.Decode([]byte(testKeyPEM1))
|
||||||
k := data.NewPublicKey("rsa", testKey.Bytes)
|
k := data.NewPublicKey("RSA", testKey.Bytes)
|
||||||
signer := Signer{&MockCryptoService{
|
signer := Signer{&MockCryptoService{
|
||||||
testKey: *k,
|
testKey: *k,
|
||||||
}}
|
}}
|
||||||
|
@ -92,11 +92,11 @@ func TestMultiSign(t *testing.T) {
|
||||||
testData := data.Signed{}
|
testData := data.Signed{}
|
||||||
|
|
||||||
testKey, _ := pem.Decode([]byte(testKeyPEM1))
|
testKey, _ := pem.Decode([]byte(testKeyPEM1))
|
||||||
key := data.NewPublicKey("rsa", testKey.Bytes)
|
key := data.NewPublicKey("RSA", testKey.Bytes)
|
||||||
signer.Sign(&testData, key)
|
signer.Sign(&testData, key)
|
||||||
|
|
||||||
testKey, _ = pem.Decode([]byte(testKeyPEM2))
|
testKey, _ = pem.Decode([]byte(testKeyPEM2))
|
||||||
key = data.NewPublicKey("rsa", testKey.Bytes)
|
key = data.NewPublicKey("RSA", testKey.Bytes)
|
||||||
signer.Sign(&testData, key)
|
signer.Sign(&testData, key)
|
||||||
|
|
||||||
if len(testData.Signatures) != 2 {
|
if len(testData.Signatures) != 2 {
|
||||||
|
@ -114,7 +114,7 @@ func TestMultiSign(t *testing.T) {
|
||||||
|
|
||||||
func TestCreate(t *testing.T) {
|
func TestCreate(t *testing.T) {
|
||||||
testKey, _ := pem.Decode([]byte(testKeyPEM1))
|
testKey, _ := pem.Decode([]byte(testKeyPEM1))
|
||||||
k := data.NewPublicKey("rsa", testKey.Bytes)
|
k := data.NewPublicKey("RSA", testKey.Bytes)
|
||||||
signer := Signer{&MockCryptoService{
|
signer := Signer{&MockCryptoService{
|
||||||
testKey: *k,
|
testKey: *k,
|
||||||
}}
|
}}
|
||||||
|
|
|
@ -17,10 +17,10 @@ import (
|
||||||
// can be injected into a verificationService. For testing and configuration
|
// can be injected into a verificationService. For testing and configuration
|
||||||
// purposes, it will not be used by default.
|
// purposes, it will not be used by default.
|
||||||
var Verifiers = map[string]Verifier{
|
var Verifiers = map[string]Verifier{
|
||||||
"ed25519": Ed25519Verifier{},
|
"ed25519": Ed25519Verifier{},
|
||||||
"rsa": RSAVerifier{},
|
"rsassa-pss": RSAPSSVerifier{},
|
||||||
"rsassa-pkcs1-v1_5-sign": RSAPemVerifier{}, // RSASSA-PKCS1-V1_5-SIGN
|
"rsassa-pss-x509": RSAPSSX509Verifier{},
|
||||||
"pycrypto-pkcs#1 pss": RSAPSSVerifier{},
|
"pycrypto-pkcs#1 pss": RSAPyCryptoVerifier{},
|
||||||
}
|
}
|
||||||
|
|
||||||
// RegisterVerifier provides a convenience function for init() functions
|
// RegisterVerifier provides a convenience function for init() functions
|
||||||
|
@ -61,83 +61,79 @@ func (v Ed25519Verifier) Verify(key data.Key, sig []byte, msg []byte) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type RSAVerifier struct{}
|
func verifyPSS(key interface{}, digest, sig []byte) error {
|
||||||
|
rsaPub, ok := key.(*rsa.PublicKey)
|
||||||
func (v RSAVerifier) Verify(key data.Key, sig []byte, msg []byte) error {
|
|
||||||
digest := sha256.Sum256(msg)
|
|
||||||
//keyReader := base64.NewDecoder(base64.StdEncoding, strings.NewReader(key.Public()))
|
|
||||||
//keyBytes, _ := ioutil.ReadAll(keyReader)
|
|
||||||
//pub, err := x509.ParsePKIXPublicKey(keyBytes)
|
|
||||||
pub, err := x509.ParsePKIXPublicKey(key.Public())
|
|
||||||
if err != nil {
|
|
||||||
logrus.Infof("Failed to parse public key: %s\n", err)
|
|
||||||
return ErrInvalid
|
|
||||||
}
|
|
||||||
|
|
||||||
rsaPub, ok := pub.(*rsa.PublicKey)
|
|
||||||
if !ok {
|
if !ok {
|
||||||
logrus.Infof("Value returned from ParsePKIXPublicKey was not an RSA public key")
|
logrus.Infof("Value was not an RSA public key")
|
||||||
return ErrInvalid
|
return ErrInvalid
|
||||||
}
|
}
|
||||||
|
|
||||||
if err = rsa.VerifyPKCS1v15(rsaPub, crypto.SHA256, digest[:], sig); err != nil {
|
opts := rsa.PSSOptions{SaltLength: sha256.Size, Hash: crypto.SHA256}
|
||||||
|
if err := rsa.VerifyPSS(rsaPub, crypto.SHA256, digest[:], sig, &opts); err != nil {
|
||||||
logrus.Infof("Failed verification: %s", err)
|
logrus.Infof("Failed verification: %s", err)
|
||||||
return ErrInvalid
|
return ErrInvalid
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type RSAPemVerifier struct{}
|
|
||||||
|
|
||||||
func (v RSAPemVerifier) Verify(key data.Key, sig []byte, msg []byte) error {
|
|
||||||
digest := sha256.Sum256(msg)
|
|
||||||
|
|
||||||
k, _ := pem.Decode([]byte(key.Public()))
|
|
||||||
cert, err := x509.ParseCertificate(k.Bytes)
|
|
||||||
if err != nil {
|
|
||||||
logrus.Errorf("Failed to parse public key: %s\n", err.Error())
|
|
||||||
return ErrInvalid
|
|
||||||
}
|
|
||||||
|
|
||||||
rsaPub, ok := cert.PublicKey.(*rsa.PublicKey)
|
|
||||||
if !ok {
|
|
||||||
logrus.Infof("Value returned from ParsePKIXPublicKey was not an RSA public key")
|
|
||||||
return ErrInvalid
|
|
||||||
}
|
|
||||||
|
|
||||||
if err = rsa.VerifyPKCS1v15(rsaPub, crypto.SHA256, digest[:], sig); err != nil {
|
|
||||||
logrus.Errorf("Failed verification: %s", err.Error())
|
|
||||||
return ErrInvalid
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// RSAPSSVerifier checks RSASSA-PSS signatures
|
// RSAPSSVerifier checks RSASSA-PSS signatures
|
||||||
type RSAPSSVerifier struct{}
|
type RSAPSSVerifier struct{}
|
||||||
|
|
||||||
// Verify does the actual check.
|
// Verify does the actual check.
|
||||||
// N.B. We have not been able to make this work in a way that is compatible
|
|
||||||
// with PyCrypto.
|
|
||||||
func (v RSAPSSVerifier) Verify(key data.Key, sig []byte, msg []byte) error {
|
func (v RSAPSSVerifier) Verify(key data.Key, sig []byte, msg []byte) error {
|
||||||
digest := sha256.Sum256(msg)
|
digest := sha256.Sum256(msg)
|
||||||
|
|
||||||
|
pub, err := x509.ParsePKIXPublicKey(key.Public())
|
||||||
|
if err != nil {
|
||||||
|
logrus.Infof("Failed to parse public key: %s\n", err)
|
||||||
|
return ErrInvalid
|
||||||
|
}
|
||||||
|
|
||||||
|
return verifyPSS(pub, digest[:], sig)
|
||||||
|
}
|
||||||
|
|
||||||
|
// RSAPSSVerifier checks RSASSA-PSS signatures
|
||||||
|
type RSAPyCryptoVerifier struct{}
|
||||||
|
|
||||||
|
// Verify does the actual check.
|
||||||
|
// N.B. We have not been able to make this work in a way that is compatible
|
||||||
|
// with PyCrypto.
|
||||||
|
func (v RSAPyCryptoVerifier) Verify(key data.Key, sig []byte, msg []byte) error {
|
||||||
|
digest := sha256.Sum256(msg)
|
||||||
|
|
||||||
k, _ := pem.Decode([]byte(key.Public()))
|
k, _ := pem.Decode([]byte(key.Public()))
|
||||||
|
if k == nil {
|
||||||
|
logrus.Infof("Failed to decode PEM-encoded x509 certificate")
|
||||||
|
return ErrInvalid
|
||||||
|
}
|
||||||
|
|
||||||
pub, err := x509.ParsePKIXPublicKey(k.Bytes)
|
pub, err := x509.ParsePKIXPublicKey(k.Bytes)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logrus.Infof("Failed to parse public key: %s\n", err)
|
logrus.Infof("Failed to parse public key: %s\n", err)
|
||||||
return ErrInvalid
|
return ErrInvalid
|
||||||
}
|
}
|
||||||
|
|
||||||
rsaPub, ok := pub.(*rsa.PublicKey)
|
return verifyPSS(pub, digest[:], sig)
|
||||||
if !ok {
|
}
|
||||||
logrus.Infof("Value returned from ParsePKIXPublicKey was not an RSA public key")
|
|
||||||
|
// RSAPSSPEMVerifier checks RSASSA-PSS signatures, extracting the public key
|
||||||
|
// from an X509 certificate.
|
||||||
|
type RSAPSSX509Verifier struct{}
|
||||||
|
|
||||||
|
// Verify does the actual check.
|
||||||
|
func (v RSAPSSX509Verifier) Verify(key data.Key, sig []byte, msg []byte) error {
|
||||||
|
digest := sha256.Sum256(msg)
|
||||||
|
|
||||||
|
k, _ := pem.Decode([]byte(key.Public()))
|
||||||
|
if k == nil {
|
||||||
|
logrus.Infof("Failed to decode PEM-encoded x509 certificate")
|
||||||
|
return ErrInvalid
|
||||||
|
}
|
||||||
|
cert, err := x509.ParseCertificate(k.Bytes)
|
||||||
|
if err != nil {
|
||||||
|
logrus.Infof("Failed to parse x509 certificate: %s\n", err)
|
||||||
return ErrInvalid
|
return ErrInvalid
|
||||||
}
|
}
|
||||||
|
|
||||||
opts := rsa.PSSOptions{SaltLength: sha256.Size, Hash: crypto.SHA256}
|
return verifyPSS(cert.PublicKey, digest[:], sig)
|
||||||
if err = rsa.VerifyPSS(rsaPub, crypto.SHA256, digest[:], sig, &opts); err != nil {
|
|
||||||
logrus.Infof("Failed verification: %s", err)
|
|
||||||
return ErrInvalid
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,6 @@ package store
|
||||||
import (
|
import (
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"encoding/pem"
|
|
||||||
"net/http"
|
"net/http"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
@ -27,7 +26,7 @@ func TestGetMeta(t *testing.T) {
|
||||||
"txt",
|
"txt",
|
||||||
"targets",
|
"targets",
|
||||||
"key",
|
"key",
|
||||||
&TestRoundTripper{},
|
&http.Transport{},
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
|
@ -42,8 +41,7 @@ func TestGetMeta(t *testing.T) {
|
||||||
t.Fatal(err)
|
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-----"
|
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-----"
|
||||||
testKey, _ := pem.Decode([]byte(rootPem))
|
k := data.NewPublicKey("RSA", []byte(rootPem))
|
||||||
k := data.NewPublicKey("rsa", testKey.Bytes)
|
|
||||||
|
|
||||||
sigBytes, err := hex.DecodeString(p.Signatures[0].Signature.String())
|
sigBytes, err := hex.DecodeString(p.Signatures[0].Signature.String())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -70,8 +68,7 @@ func TestPyCryptoRSAPSSCompat(t *testing.T) {
|
||||||
//privPem := "-----BEGIN RSA PRIVATE KEY-----\n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\n-----END RSA PRIVATE KEY-----"
|
//privPem := "-----BEGIN RSA PRIVATE KEY-----\n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\n-----END RSA PRIVATE KEY-----"
|
||||||
testStr := "The quick brown fox jumps over the lazy dog."
|
testStr := "The quick brown fox jumps over the lazy dog."
|
||||||
sigHex := "4e05ee9e435653549ac4eddbc43e1a6868636e8ea6dbec2564435afcb0de47e0824cddbd88776ddb20728c53ecc90b5d543d5c37575fda8bd0317025fc07de62ee8084b1a75203b1a23d1ef4ac285da3d1fc63317d5b2cf1aafa3e522acedd366ccd5fe4a7f02a42922237426ca3dc154c57408638b9bfaf0d0213855d4e9ee621db204151bcb13d4dbb18f930ec601469c992c84b14e9e0b6f91ac9517bb3b749dd117e1cbac2e4acb0e549f44558a2005898a226d5b6c8b9291d7abae0d9e0a16858b89662a085f74a202deb867acab792bdbd2c36731217caea8b17bd210c29b890472f11e5afdd1dd7b69004db070e04201778f2c49f5758643881403d45a58d08f51b5c63910c6185892f0b590f191d760b669eff2464456f130239bba94acf54a0cb98f6939ff84ae26a37f9b890be259d9b5d636f6eb367b53e895227d7d79a3a88afd6d28c198ee80f6527437c5fbf63accb81709925c4e03d1c9eaee86f58e4bd1c669d6af042dbd412de0d13b98b1111e2fadbe34b45de52125e9a"
|
sigHex := "4e05ee9e435653549ac4eddbc43e1a6868636e8ea6dbec2564435afcb0de47e0824cddbd88776ddb20728c53ecc90b5d543d5c37575fda8bd0317025fc07de62ee8084b1a75203b1a23d1ef4ac285da3d1fc63317d5b2cf1aafa3e522acedd366ccd5fe4a7f02a42922237426ca3dc154c57408638b9bfaf0d0213855d4e9ee621db204151bcb13d4dbb18f930ec601469c992c84b14e9e0b6f91ac9517bb3b749dd117e1cbac2e4acb0e549f44558a2005898a226d5b6c8b9291d7abae0d9e0a16858b89662a085f74a202deb867acab792bdbd2c36731217caea8b17bd210c29b890472f11e5afdd1dd7b69004db070e04201778f2c49f5758643881403d45a58d08f51b5c63910c6185892f0b590f191d760b669eff2464456f130239bba94acf54a0cb98f6939ff84ae26a37f9b890be259d9b5d636f6eb367b53e895227d7d79a3a88afd6d28c198ee80f6527437c5fbf63accb81709925c4e03d1c9eaee86f58e4bd1c669d6af042dbd412de0d13b98b1111e2fadbe34b45de52125e9a"
|
||||||
testKey, _ := pem.Decode([]byte(pubPem))
|
k := data.NewPublicKey("RSA", []byte(pubPem))
|
||||||
k := data.NewPublicKey("rsa", testKey.Bytes)
|
|
||||||
|
|
||||||
sigBytes, err := hex.DecodeString(sigHex)
|
sigBytes, err := hex.DecodeString(sigHex)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -91,11 +88,11 @@ func TestPyNaCled25519Compat(t *testing.T) {
|
||||||
sigHex := "166e7013e48f26dccb4e68fe4cf558d1cd3af902f8395534336a7f8b4c56588694aa3ac671767246298a59d5ef4224f02c854f41bfcfe70241db4be1546d6a00"
|
sigHex := "166e7013e48f26dccb4e68fe4cf558d1cd3af902f8395534336a7f8b4c56588694aa3ac671767246298a59d5ef4224f02c854f41bfcfe70241db4be1546d6a00"
|
||||||
|
|
||||||
pub, _ := hex.DecodeString(pubHex)
|
pub, _ := hex.DecodeString(pubHex)
|
||||||
k := data.NewPublicKey("ed25519", pub)
|
k := data.NewPublicKey("ED25519", pub)
|
||||||
|
|
||||||
sigBytes, _ := hex.DecodeString(sigHex)
|
sigBytes, _ := hex.DecodeString(sigHex)
|
||||||
|
|
||||||
err := signed.Verifiers["ed25519"].Verify(k, sigBytes, []byte(testStr))
|
err := signed.Verifiers["ED25519"].Verify(k, sigBytes, []byte(testStr))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,21 +0,0 @@
|
||||||
package store
|
|
||||||
|
|
||||||
import "bytes"
|
|
||||||
import "reflect"
|
|
||||||
import "testing"
|
|
||||||
|
|
||||||
func testMeta(t *testing.T, s *MetadataStore) {
|
|
||||||
storeName := reflect.TypeOf(s).Name()
|
|
||||||
testData := []byte{}
|
|
||||||
err := s.SetMeta(testName, testData)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
out, err := s.GetMeta(testName, len(testData))
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
if bytes.Compare(testData, out) != 0 {
|
|
||||||
t.Fatalf("%s mangled data", storeName)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -23,12 +23,16 @@ func SampleMeta() data.FileMeta {
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetSqliteDB() *sql.DB {
|
func GetSqliteDB() *sql.DB {
|
||||||
|
os.Mkdir("/tmp/sqlite", 0755)
|
||||||
conn, err := sql.Open("sqlite3", fmt.Sprintf("/tmp/sqlite/file%d.db", counter))
|
conn, err := sql.Open("sqlite3", fmt.Sprintf("/tmp/sqlite/file%d.db", counter))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic("can't connect to db")
|
panic("can't connect to db")
|
||||||
}
|
}
|
||||||
counter++
|
counter++
|
||||||
tx, _ := conn.Begin()
|
tx, err := conn.Begin()
|
||||||
|
if err != nil {
|
||||||
|
panic("can't begin db transaction")
|
||||||
|
}
|
||||||
tx.Exec("CREATE TABLE keys (id int auto_increment, namespace varchar(255) not null, role varchar(255) not null, key text not null, primary key (id));")
|
tx.Exec("CREATE TABLE keys (id int auto_increment, namespace varchar(255) not null, role varchar(255) not null, key text not null, primary key (id));")
|
||||||
tx.Exec("CREATE TABLE filehashes(namespace varchar(255) not null, path varchar(255) not null, alg varchar(10) not null, hash varchar(128) not null, primary key (namespace, path, alg));")
|
tx.Exec("CREATE TABLE filehashes(namespace varchar(255) not null, path varchar(255) not null, alg varchar(10) not null, hash varchar(128) not null, primary key (namespace, path, alg));")
|
||||||
tx.Exec("CREATE TABLE filemeta(namespace varchar(255) not null, path varchar(255) not null, size int not null, custom text default null, primary key (namespace, path));")
|
tx.Exec("CREATE TABLE filemeta(namespace varchar(255) not null, path varchar(255) not null, size int not null, custom text default null, primary key (namespace, path));")
|
||||||
|
|
|
@ -177,16 +177,13 @@ func (tr *TufRepo) UpdateDelegations(role *data.Role, keys []data.Key, before st
|
||||||
// also relies on the keysDB having already been populated with the keys and
|
// also relies on the keysDB having already been populated with the keys and
|
||||||
// roles.
|
// roles.
|
||||||
func (tr *TufRepo) InitRepo(consistent bool) error {
|
func (tr *TufRepo) InitRepo(consistent bool) error {
|
||||||
err := tr.InitRoot(consistent)
|
if err := tr.InitRoot(consistent); err != nil {
|
||||||
if err != nil {
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
tr.InitTargets()
|
if err := tr.InitTargets(); err != nil {
|
||||||
if err != nil {
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
tr.InitSnapshot()
|
if err := tr.InitSnapshot(); err != nil {
|
||||||
if err != nil {
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return tr.InitTimestamp()
|
return tr.InitTimestamp()
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
package utils
|
package utils
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
@ -16,40 +15,6 @@ type UtilSuite struct{}
|
||||||
|
|
||||||
var _ = Suite(&UtilSuite{})
|
var _ = Suite(&UtilSuite{})
|
||||||
|
|
||||||
func (UtilSuite) TestGenerateFileMetaDefault(c *C) {
|
|
||||||
// default is sha512
|
|
||||||
r := bytes.NewReader([]byte("foo"))
|
|
||||||
meta, err := GenerateFileMeta(r)
|
|
||||||
c.Assert(err, IsNil)
|
|
||||||
c.Assert(meta.Length, Equals, int64(3))
|
|
||||||
hashes := meta.Hashes
|
|
||||||
c.Assert(hashes, HasLen, 1)
|
|
||||||
hash, ok := hashes["sha512"]
|
|
||||||
if !ok {
|
|
||||||
c.Fatal("missing sha512 hash")
|
|
||||||
}
|
|
||||||
c.Assert(hash.String(), DeepEquals, "f7fbba6e0636f890e56fbbf3283e524c6fa3204ae298382d624741d0dc6638326e282c41be5e4254d8820772c5518a2c5a8c0c7f7eda19594a7eb539453e1ed7")
|
|
||||||
}
|
|
||||||
|
|
||||||
func (UtilSuite) TestGenerateFileMetaExplicit(c *C) {
|
|
||||||
r := bytes.NewReader([]byte("foo"))
|
|
||||||
meta, err := GenerateFileMeta(r, "sha256", "sha512")
|
|
||||||
c.Assert(err, IsNil)
|
|
||||||
c.Assert(meta.Length, Equals, int64(3))
|
|
||||||
hashes := meta.Hashes
|
|
||||||
c.Assert(hashes, HasLen, 2)
|
|
||||||
for name, val := range map[string]string{
|
|
||||||
"sha256": "2c26b46b68ffc68ff99b453c1d30413413422d706483bfa0f98a5e886266e7ae",
|
|
||||||
"sha512": "f7fbba6e0636f890e56fbbf3283e524c6fa3204ae298382d624741d0dc6638326e282c41be5e4254d8820772c5518a2c5a8c0c7f7eda19594a7eb539453e1ed7",
|
|
||||||
} {
|
|
||||||
hash, ok := hashes[name]
|
|
||||||
if !ok {
|
|
||||||
c.Fatalf("missing %s hash", name)
|
|
||||||
}
|
|
||||||
c.Assert(hash.String(), DeepEquals, val)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (UtilSuite) TestFileMetaEqual(c *C) {
|
func (UtilSuite) TestFileMetaEqual(c *C) {
|
||||||
type test struct {
|
type test struct {
|
||||||
name string
|
name string
|
||||||
|
|
|
@ -6,9 +6,9 @@ import (
|
||||||
"crypto/rsa"
|
"crypto/rsa"
|
||||||
"crypto/sha256"
|
"crypto/sha256"
|
||||||
"crypto/x509"
|
"crypto/x509"
|
||||||
"errors"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/docker/notary/trustmanager"
|
"github.com/docker/notary/trustmanager"
|
||||||
"github.com/endophage/gotuf/data"
|
"github.com/endophage/gotuf/data"
|
||||||
|
@ -17,16 +17,9 @@ import (
|
||||||
// CryptoService implements Sign and Create, holding a specific GUN and keystore to
|
// CryptoService implements Sign and Create, holding a specific GUN and keystore to
|
||||||
// operate on
|
// operate on
|
||||||
type CryptoService struct {
|
type CryptoService struct {
|
||||||
gun string
|
gun string
|
||||||
keyStore *trustmanager.KeyFileStore
|
passphrase string
|
||||||
}
|
keyStore *trustmanager.KeyFileStore
|
||||||
|
|
||||||
// RootCryptoService implements Sign and Create and operates on a rootKeyStore,
|
|
||||||
// taking in a passphrase and calling decrypt when signing.
|
|
||||||
type RootCryptoService struct {
|
|
||||||
// TODO(diogo): support multiple passphrases per key
|
|
||||||
passphrase string
|
|
||||||
rootKeyStore *trustmanager.KeyFileStore
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewCryptoService returns an instance of CryptoService
|
// NewCryptoService returns an instance of CryptoService
|
||||||
|
@ -34,11 +27,6 @@ func NewCryptoService(gun string, keyStore *trustmanager.KeyFileStore) *CryptoSe
|
||||||
return &CryptoService{gun: gun, keyStore: keyStore}
|
return &CryptoService{gun: gun, keyStore: keyStore}
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewRootCryptoService returns an instance of CryptoService
|
|
||||||
func NewRootCryptoService(rootKeyStore *trustmanager.KeyFileStore, passphrase string) *RootCryptoService {
|
|
||||||
return &RootCryptoService{rootKeyStore: rootKeyStore, passphrase: passphrase}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create is used to generate keys for targets, snapshots and timestamps
|
// Create is used to generate keys for targets, snapshots and timestamps
|
||||||
func (ccs *CryptoService) Create(role string) (*data.PublicKey, error) {
|
func (ccs *CryptoService) Create(role string) (*data.PublicKey, error) {
|
||||||
privKey, err := trustmanager.GenerateRSAKey(rand.Reader, rsaKeySize)
|
privKey, err := trustmanager.GenerateRSAKey(rand.Reader, rsaKeySize)
|
||||||
|
@ -52,7 +40,14 @@ func (ccs *CryptoService) Create(role string) (*data.PublicKey, error) {
|
||||||
return data.PublicKeyFromPrivate(*privKey), nil
|
return data.PublicKeyFromPrivate(*privKey), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sign returns the signatures for data with the given keyIDs
|
// SetPassphrase tells the cryptoservice the passphrase. Use only if the key needs
|
||||||
|
// to be decrypted.
|
||||||
|
func (ccs *CryptoService) SetPassphrase(passphrase string) {
|
||||||
|
ccs.passphrase = passphrase
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sign returns the signatures for data with the given root Key ID, falling back
|
||||||
|
// if not rootKeyID is found
|
||||||
func (ccs *CryptoService) Sign(keyIDs []string, payload []byte) ([]data.Signature, error) {
|
func (ccs *CryptoService) Sign(keyIDs []string, payload []byte) ([]data.Signature, error) {
|
||||||
// Create hasher and hash data
|
// Create hasher and hash data
|
||||||
hash := crypto.SHA256
|
hash := crypto.SHA256
|
||||||
|
@ -60,11 +55,27 @@ func (ccs *CryptoService) Sign(keyIDs []string, payload []byte) ([]data.Signatur
|
||||||
|
|
||||||
signatures := make([]data.Signature, 0, len(keyIDs))
|
signatures := make([]data.Signature, 0, len(keyIDs))
|
||||||
for _, fingerprint := range keyIDs {
|
for _, fingerprint := range keyIDs {
|
||||||
// Get the PrivateKey filename
|
// ccs.gun will be empty if this is the root key
|
||||||
privKeyFilename := filepath.Join(ccs.gun, fingerprint)
|
keyName := filepath.Join(ccs.gun, fingerprint)
|
||||||
|
|
||||||
|
var privKey *data.PrivateKey
|
||||||
|
var err error
|
||||||
|
var method string
|
||||||
|
|
||||||
// Read PrivateKey from file
|
// Read PrivateKey from file
|
||||||
privKey, err := ccs.keyStore.GetKey(privKeyFilename)
|
if ccs.passphrase != "" {
|
||||||
|
// This is a root key
|
||||||
|
privKey, err = ccs.keyStore.GetDecryptedKey(keyName, ccs.passphrase)
|
||||||
|
method = "RSASSA-PSS-X509"
|
||||||
|
} else {
|
||||||
|
privKey, err = ccs.keyStore.GetKey(keyName)
|
||||||
|
method = "RSASSA-PSS"
|
||||||
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
// Note that GetDecryptedKey always fails on InitRepo.
|
||||||
|
// InitRepo gets a signer that doesn't have access to
|
||||||
|
// the root keys. Continuing here is safe because we
|
||||||
|
// end up not returning any signatures.
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -76,44 +87,7 @@ func (ccs *CryptoService) Sign(keyIDs []string, payload []byte) ([]data.Signatur
|
||||||
// Append signatures to result array
|
// Append signatures to result array
|
||||||
signatures = append(signatures, data.Signature{
|
signatures = append(signatures, data.Signature{
|
||||||
KeyID: fingerprint,
|
KeyID: fingerprint,
|
||||||
Method: "RSA",
|
Method: method,
|
||||||
Signature: sig[:],
|
|
||||||
})
|
|
||||||
}
|
|
||||||
return signatures, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create in a root crypto service is not implemented
|
|
||||||
func (rcs *RootCryptoService) Create(role string) (*data.PublicKey, error) {
|
|
||||||
return nil, errors.New("create on a root key filestore is not implemented")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Sign returns the signatures for data with the given root Key ID, falling back
|
|
||||||
// if not rootKeyID is found
|
|
||||||
// TODO(diogo): This code has 1 line change from the Sign from Crypto service. DRY it up.
|
|
||||||
func (rcs *RootCryptoService) Sign(keyIDs []string, payload []byte) ([]data.Signature, error) {
|
|
||||||
// Create hasher and hash data
|
|
||||||
hash := crypto.SHA256
|
|
||||||
hashed := sha256.Sum256(payload)
|
|
||||||
|
|
||||||
signatures := make([]data.Signature, 0, len(keyIDs))
|
|
||||||
for _, fingerprint := range keyIDs {
|
|
||||||
// Read PrivateKey from file
|
|
||||||
privKey, err := rcs.rootKeyStore.GetDecryptedKey(fingerprint, rcs.passphrase)
|
|
||||||
if err != nil {
|
|
||||||
// TODO(diogo): This error should be returned to the user in someway
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
sig, err := sign(privKey, hash, hashed[:])
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Append signatures to result array
|
|
||||||
signatures = append(signatures, data.Signature{
|
|
||||||
KeyID: fingerprint,
|
|
||||||
Method: "RSASSA-PKCS1-V1_5-SIGN",
|
|
||||||
Signature: sig[:],
|
Signature: sig[:],
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -123,7 +97,7 @@ func (rcs *RootCryptoService) Sign(keyIDs []string, payload []byte) ([]data.Sign
|
||||||
|
|
||||||
func sign(privKey *data.PrivateKey, hash crypto.Hash, hashed []byte) ([]byte, error) {
|
func sign(privKey *data.PrivateKey, hash crypto.Hash, hashed []byte) ([]byte, error) {
|
||||||
// TODO(diogo): Implement support for ECDSA.
|
// TODO(diogo): Implement support for ECDSA.
|
||||||
if privKey.Cipher() != "RSA" {
|
if strings.ToLower(privKey.Cipher()) != "rsa" {
|
||||||
return nil, fmt.Errorf("private key type not supported: %s", privKey.Cipher())
|
return nil, fmt.Errorf("private key type not supported: %s", privKey.Cipher())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -134,7 +108,7 @@ func sign(privKey *data.PrivateKey, hash crypto.Hash, hashed []byte) ([]byte, er
|
||||||
}
|
}
|
||||||
|
|
||||||
// Use the RSA key to sign the data
|
// Use the RSA key to sign the data
|
||||||
sig, err := rsa.SignPKCS1v15(rand.Reader, rsaPrivKey, hash, hashed[:])
|
sig, err := rsa.SignPSS(rand.Reader, rsaPrivKey, hash, hashed[:], &rsa.PSSOptions{SaltLength: rsa.PSSSaltLengthEqualsHash})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -62,7 +62,7 @@ type UnlockedSigner struct {
|
||||||
// repository.
|
// repository.
|
||||||
type NotaryRepository struct {
|
type NotaryRepository struct {
|
||||||
baseDir string
|
baseDir string
|
||||||
Gun string
|
gun string
|
||||||
baseURL string
|
baseURL string
|
||||||
tufRepoPath string
|
tufRepoPath string
|
||||||
caStore trustmanager.X509Store
|
caStore trustmanager.X509Store
|
||||||
|
@ -111,10 +111,11 @@ func NewNotaryRepository(baseDir, gun, baseURL string, rt http.RoundTripper) (*N
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fmt.Println("creating non-root cryptoservice")
|
||||||
signer := signed.NewSigner(NewCryptoService(gun, privKeyStore))
|
signer := signed.NewSigner(NewCryptoService(gun, privKeyStore))
|
||||||
|
|
||||||
nRepo := &NotaryRepository{
|
nRepo := &NotaryRepository{
|
||||||
Gun: gun,
|
gun: gun,
|
||||||
baseDir: baseDir,
|
baseDir: baseDir,
|
||||||
baseURL: baseURL,
|
baseURL: baseURL,
|
||||||
tufRepoPath: filepath.Join(baseDir, tufDir, gun),
|
tufRepoPath: filepath.Join(baseDir, tufDir, gun),
|
||||||
|
@ -133,7 +134,7 @@ func NewNotaryRepository(baseDir, gun, baseURL string, rt http.RoundTripper) (*N
|
||||||
// Initialize creates a new repository by using rootKey as the root Key for the
|
// Initialize creates a new repository by using rootKey as the root Key for the
|
||||||
// TUF repository.
|
// TUF repository.
|
||||||
func (r *NotaryRepository) Initialize(uSigner *UnlockedSigner) error {
|
func (r *NotaryRepository) Initialize(uSigner *UnlockedSigner) error {
|
||||||
rootCert, err := uSigner.GenerateCertificate(r.Gun)
|
rootCert, err := uSigner.GenerateCertificate(r.gun)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -144,7 +145,7 @@ func (r *NotaryRepository) Initialize(uSigner *UnlockedSigner) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
remote, err := getRemoteStore(r.baseURL, r.Gun, r.roundTrip)
|
remote, err := getRemoteStore(r.baseURL, r.gun, r.roundTrip)
|
||||||
rawTSKey, err := remote.GetKey("timestamp")
|
rawTSKey, err := remote.GetKey("timestamp")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -377,7 +378,7 @@ func (r *NotaryRepository) Publish(getPass passwordRetriever) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
remote, err := getRemoteStore(r.baseURL, r.Gun, r.roundTrip)
|
remote, err := getRemoteStore(r.baseURL, r.gun, r.roundTrip)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -554,14 +555,14 @@ func (r *NotaryRepository) validateRoot(root *data.Signed) error {
|
||||||
// Cert.Raw. It's included to prevent breaking logic with changes of how the
|
// Cert.Raw. It's included to prevent breaking logic with changes of how the
|
||||||
// ID gets computed.
|
// ID gets computed.
|
||||||
_, err = r.certificateStore.GetCertificateByFingerprint(leafID)
|
_, err = r.certificateStore.GetCertificateByFingerprint(leafID)
|
||||||
if err == nil && leafCert.Subject.CommonName == r.Gun {
|
if err == nil && leafCert.Subject.CommonName == r.gun {
|
||||||
certs[fingerprint] = rootSigned.Keys[fingerprint]
|
certs[fingerprint] = rootSigned.Keys[fingerprint]
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check to see if this leafCertificate has a chain to one of the Root CAs
|
// Check to see if this leafCertificate has a chain to one of the Root CAs
|
||||||
// of our CA Store.
|
// of our CA Store.
|
||||||
certList := []*x509.Certificate{leafCert}
|
certList := []*x509.Certificate{leafCert}
|
||||||
err = trustmanager.Verify(r.caStore, r.Gun, certList)
|
err = trustmanager.Verify(r.caStore, r.gun, certList)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
certs[fingerprint] = rootSigned.Keys[fingerprint]
|
certs[fingerprint] = rootSigned.Keys[fingerprint]
|
||||||
}
|
}
|
||||||
|
@ -577,7 +578,7 @@ func (r *NotaryRepository) validateRoot(root *data.Signed) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *NotaryRepository) bootstrapClient() (*tufclient.Client, error) {
|
func (r *NotaryRepository) bootstrapClient() (*tufclient.Client, error) {
|
||||||
remote, err := getRemoteStore(r.baseURL, r.Gun, r.roundTrip)
|
remote, err := getRemoteStore(r.baseURL, r.gun, r.roundTrip)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -638,7 +639,12 @@ func (r *NotaryRepository) GetRootSigner(rootKeyID, passphrase string) (*Unlocke
|
||||||
|
|
||||||
// This signer will be used for all of the normal TUF operations, except for
|
// This signer will be used for all of the normal TUF operations, except for
|
||||||
// when a root key is needed.
|
// when a root key is needed.
|
||||||
signer := signed.NewSigner(NewRootCryptoService(r.rootKeyStore, passphrase))
|
|
||||||
|
// Passing an empty GUN because root keys aren't associated with a GUN.
|
||||||
|
fmt.Println("creating root cryptoservice with passphrase", passphrase)
|
||||||
|
ccs := NewCryptoService("", r.rootKeyStore)
|
||||||
|
ccs.SetPassphrase(passphrase)
|
||||||
|
signer := signed.NewSigner(ccs)
|
||||||
|
|
||||||
return &UnlockedSigner{
|
return &UnlockedSigner{
|
||||||
privKey: privKey,
|
privKey: privKey,
|
||||||
|
|
|
@ -46,23 +46,23 @@ func TestGetTimestampKey(t *testing.T) {
|
||||||
//_, _, err := s.GetTimestampKey("gun")
|
//_, _, err := s.GetTimestampKey("gun")
|
||||||
//assert.IsType(t, &ErrNoKey{}, err, "Expected err to be ErrNoKey")
|
//assert.IsType(t, &ErrNoKey{}, err, "Expected err to be ErrNoKey")
|
||||||
|
|
||||||
s.SetTimestampKey("gun", "rsa", []byte("test"))
|
s.SetTimestampKey("gun", "RSA", []byte("test"))
|
||||||
|
|
||||||
c, k, err := s.GetTimestampKey("gun")
|
c, k, err := s.GetTimestampKey("gun")
|
||||||
assert.Nil(t, err, "Expected error to be nil")
|
assert.Nil(t, err, "Expected error to be nil")
|
||||||
assert.Equal(t, "rsa", c, "Expected cipher rsa, received %s", c)
|
assert.Equal(t, "RSA", c, "Expected cipher rsa, received %s", c)
|
||||||
assert.Equal(t, []byte("test"), k, "Key data was wrong")
|
assert.Equal(t, []byte("test"), k, "Key data was wrong")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestSetTimestampKey(t *testing.T) {
|
func TestSetTimestampKey(t *testing.T) {
|
||||||
s := NewMemStorage()
|
s := NewMemStorage()
|
||||||
s.SetTimestampKey("gun", "rsa", []byte("test"))
|
s.SetTimestampKey("gun", "RSA", []byte("test"))
|
||||||
|
|
||||||
err := s.SetTimestampKey("gun", "rsa", []byte("test2"))
|
err := s.SetTimestampKey("gun", "RSA", []byte("test2"))
|
||||||
assert.IsType(t, &ErrTimestampKeyExists{}, err, "Expected err to be ErrTimestampKeyExists")
|
assert.IsType(t, &ErrTimestampKeyExists{}, err, "Expected err to be ErrTimestampKeyExists")
|
||||||
|
|
||||||
k := s.tsKeys["gun"]
|
k := s.tsKeys["gun"]
|
||||||
assert.Equal(t, "rsa", k.cipher, "Expected cipher to be rsa, received %s", k.cipher)
|
assert.Equal(t, "RSA", k.cipher, "Expected cipher to be rsa, received %s", k.cipher)
|
||||||
assert.Equal(t, []byte("test"), k.public, "Public key did not match expected")
|
assert.Equal(t, []byte("test"), k.public, "Public key did not match expected")
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue