mirror of
https://github.com/docker/docs.git
synced 2026-04-12 06:19:22 +07:00
Update swizzler so that if messing up the root file, we can still get the pub keys and sign.
Signed-off-by: Ying Li <ying.li@docker.com>
This commit is contained in:
@@ -32,21 +32,9 @@ type MetadataSwizzler struct {
|
||||
Roles []string // list of Roles in the metadataStore
|
||||
}
|
||||
|
||||
// signs the new metadata, replacing whatever signature was there
|
||||
func serializeMetadata(cs signed.CryptoService, s *data.Signed, role string,
|
||||
pubKeys ...data.PublicKey) ([]byte, error) {
|
||||
|
||||
// delete the existing signatures
|
||||
s.Signatures = []data.Signature{}
|
||||
|
||||
if len(pubKeys) > 0 {
|
||||
if err := signed.Sign(cs, s, pubKeys...); err != nil {
|
||||
if _, ok := err.(signed.ErrNoKeys); ok {
|
||||
return nil, ErrNoKeyForRole{Role: role}
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
} else if role == data.CanonicalRootRole {
|
||||
func getPubKeys(cs signed.CryptoService, s *data.Signed, role string) ([]data.PublicKey, error) {
|
||||
var pubKeys []data.PublicKey
|
||||
if role == data.CanonicalRootRole {
|
||||
// if this is root metadata, we have to get the keys from the root because they
|
||||
// are certs
|
||||
root := &data.Root{}
|
||||
@@ -54,24 +42,37 @@ func serializeMetadata(cs signed.CryptoService, s *data.Signed, role string,
|
||||
return nil, err
|
||||
}
|
||||
for _, pubKeyID := range root.Roles[data.CanonicalRootRole].KeyIDs {
|
||||
if err := signed.Sign(cs, s, root.Keys[pubKeyID]); err != nil {
|
||||
if _, ok := err.(signed.ErrNoKeys); ok {
|
||||
return nil, ErrNoKeyForRole{Role: role}
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
pubKeys = append(pubKeys, root.Keys[pubKeyID])
|
||||
}
|
||||
} else {
|
||||
pubKeyIDs := cs.ListKeys(role)
|
||||
if len(pubKeyIDs) < 1 {
|
||||
return nil, ErrNoKeyForRole{role}
|
||||
}
|
||||
for _, pubKeyID := range pubKeyIDs {
|
||||
if err := signed.Sign(cs, s, cs.GetKey(pubKeyID)); err != nil {
|
||||
return nil, err
|
||||
pubKey := cs.GetKey(pubKeyID)
|
||||
if pubKey != nil {
|
||||
pubKeys = append(pubKeys, pubKey)
|
||||
}
|
||||
}
|
||||
}
|
||||
return pubKeys, nil
|
||||
}
|
||||
|
||||
// signs the new metadata, replacing whatever signature was there
|
||||
func serializeMetadata(cs signed.CryptoService, s *data.Signed, role string,
|
||||
pubKeys ...data.PublicKey) ([]byte, error) {
|
||||
|
||||
// delete the existing signatures
|
||||
s.Signatures = []data.Signature{}
|
||||
|
||||
if len(pubKeys) < 1 {
|
||||
return nil, ErrNoKeyForRole{role}
|
||||
}
|
||||
|
||||
if err := signed.Sign(cs, s, pubKeys...); err != nil {
|
||||
if _, ok := err.(signed.ErrNoKeys); ok {
|
||||
return nil, ErrNoKeyForRole{Role: role}
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
|
||||
metaBytes, err := json.Marshal(s)
|
||||
if err != nil {
|
||||
@@ -160,6 +161,11 @@ func (m *MetadataSwizzler) SetInvalidSignedMeta(role string) error {
|
||||
return err
|
||||
}
|
||||
|
||||
pubKeys, err := getPubKeys(m.CryptoService, signedThing, role)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var unmarshalled map[string]interface{}
|
||||
if err := json.Unmarshal(signedThing.Signed, &unmarshalled); err != nil {
|
||||
return err
|
||||
@@ -175,7 +181,7 @@ func (m *MetadataSwizzler) SetInvalidSignedMeta(role string) error {
|
||||
}
|
||||
signedThing.Signed = json.RawMessage(metaBytes)
|
||||
|
||||
metaBytes, err = serializeMetadata(m.CryptoService, signedThing, role)
|
||||
metaBytes, err = serializeMetadata(m.CryptoService, signedThing, role, pubKeys...)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -206,7 +212,11 @@ func (m *MetadataSwizzler) SetInvalidMetadataType(role string) error {
|
||||
}
|
||||
signedThing.Signed = json.RawMessage(metaBytes)
|
||||
|
||||
metaBytes, err = serializeMetadata(m.CryptoService, signedThing, role)
|
||||
pubKeys, err := getPubKeys(m.CryptoService, signedThing, role)
|
||||
if err == nil {
|
||||
metaBytes, err = serializeMetadata(m.CryptoService, signedThing, role, pubKeys...)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -291,7 +301,11 @@ func (m *MetadataSwizzler) OffsetMetadataVersion(role string, offset int) error
|
||||
}
|
||||
signedThing.Signed = json.RawMessage(metaBytes)
|
||||
|
||||
metaBytes, err = serializeMetadata(m.CryptoService, signedThing, role)
|
||||
pubKeys, err := getPubKeys(m.CryptoService, signedThing, role)
|
||||
if err == nil {
|
||||
metaBytes, err = serializeMetadata(m.CryptoService, signedThing, role, pubKeys...)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -319,7 +333,11 @@ func (m *MetadataSwizzler) ExpireMetadata(role string) error {
|
||||
}
|
||||
signedThing.Signed = json.RawMessage(metaBytes)
|
||||
|
||||
metaBytes, err = serializeMetadata(m.CryptoService, signedThing, role)
|
||||
pubKeys, err := getPubKeys(m.CryptoService, signedThing, role)
|
||||
if err == nil {
|
||||
metaBytes, err = serializeMetadata(m.CryptoService, signedThing, role, pubKeys...)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -370,7 +388,12 @@ func (m *MetadataSwizzler) SetThreshold(role string, newThreshold int) error {
|
||||
}
|
||||
}
|
||||
|
||||
metaBytes, err := serializeMetadata(m.CryptoService, signedThing, roleSpecifier)
|
||||
var metaBytes []byte
|
||||
pubKeys, err := getPubKeys(m.CryptoService, signedThing, roleSpecifier)
|
||||
if err == nil {
|
||||
metaBytes, err = serializeMetadata(m.CryptoService, signedThing, roleSpecifier, pubKeys...)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -403,7 +426,12 @@ func (m *MetadataSwizzler) ChangeRootKey() error {
|
||||
return err
|
||||
}
|
||||
|
||||
metaBytes, err := serializeMetadata(m.CryptoService, signedThing, data.CanonicalRootRole)
|
||||
var metaBytes []byte
|
||||
pubKeys, err := getPubKeys(m.CryptoService, signedThing, data.CanonicalRootRole)
|
||||
if err == nil {
|
||||
metaBytes, err = serializeMetadata(m.CryptoService, signedThing, data.CanonicalRootRole, pubKeys...)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -450,7 +478,11 @@ func (m *MetadataSwizzler) UpdateSnapshotHashes(roles ...string) error {
|
||||
if snapshotSigned, err = snapshot.ToSigned(); err != nil {
|
||||
return err
|
||||
}
|
||||
metaBytes, err = serializeMetadata(m.CryptoService, snapshotSigned, data.CanonicalSnapshotRole)
|
||||
pubKeys, err := getPubKeys(m.CryptoService, snapshotSigned, data.CanonicalSnapshotRole)
|
||||
if err == nil {
|
||||
metaBytes, err = serializeMetadata(m.CryptoService, snapshotSigned, data.CanonicalSnapshotRole, pubKeys...)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -490,7 +522,11 @@ func (m *MetadataSwizzler) UpdateTimestampHash() error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
metaBytes, err = serializeMetadata(m.CryptoService, timestampSigned, data.CanonicalTimestampRole)
|
||||
pubKeys, err := getPubKeys(m.CryptoService, timestampSigned, data.CanonicalTimestampRole)
|
||||
if err == nil {
|
||||
metaBytes, err = serializeMetadata(m.CryptoService, timestampSigned, data.CanonicalTimestampRole, pubKeys...)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -159,13 +159,13 @@ func TestSwizzlerSetInvalidSigned(t *testing.T) {
|
||||
func TestSwizzlerSetInvalidSignedMeta(t *testing.T) {
|
||||
f, origMeta := createNewSwizzler(t)
|
||||
|
||||
f.SetInvalidSignedMeta(data.CanonicalTargetsRole)
|
||||
f.SetInvalidSignedMeta(data.CanonicalRootRole)
|
||||
|
||||
for role, metaBytes := range origMeta {
|
||||
newMeta, err := f.MetadataCache.GetMeta(role, -1)
|
||||
require.NoError(t, err)
|
||||
|
||||
if role != data.CanonicalTargetsRole {
|
||||
if role != data.CanonicalRootRole {
|
||||
require.True(t, bytes.Equal(metaBytes, newMeta), "bytes have changed for role %s", role)
|
||||
} else {
|
||||
require.False(t, bytes.Equal(metaBytes, newMeta))
|
||||
@@ -227,6 +227,7 @@ func TestSwizzlerInvalidateMetadataSignatures(t *testing.T) {
|
||||
require.Equal(t, origSigned.Signatures[i].KeyID, newSigned.Signatures[i].KeyID)
|
||||
require.Equal(t, origSigned.Signatures[i].Method, newSigned.Signatures[i].Method)
|
||||
require.NotEqual(t, origSigned.Signatures[i].Signature, newSigned.Signatures[i].Signature)
|
||||
require.Equal(t, []byte("invalid signature"), newSigned.Signatures[i].Signature)
|
||||
}
|
||||
require.True(t, bytes.Equal(origSigned.Signed, newSigned.Signed))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user