mirror of https://github.com/docker/docs.git
creating concrete types for the various key ciphers
Signed-off-by: David Lawrence <david.lawrence@docker.com> (github: endophage)
This commit is contained in:
parent
daa36b43b7
commit
f73560d839
|
@ -38,8 +38,8 @@ type TufChange struct {
|
|||
// TufRootData represents a modification of the keys associated
|
||||
// with a role that appears in the root.json
|
||||
type TufRootData struct {
|
||||
Keys []data.TUFKey `json:"keys"`
|
||||
RoleName string `json:"role"`
|
||||
Keys data.KeyList `json:"keys"`
|
||||
RoleName string `json:"role"`
|
||||
}
|
||||
|
||||
// NewTufChange initializes a tufChange object
|
||||
|
|
|
@ -149,20 +149,16 @@ func (r *NotaryRepository) Initialize(uCryptoService *cryptoservice.UnlockedCryp
|
|||
// If the key is RSA, we store it as type RSAx509, if it is ECDSA we store it
|
||||
// as ECDSAx509 to allow the gotuf verifiers to correctly decode the
|
||||
// key on verification of signatures.
|
||||
var algorithmType data.KeyAlgorithm
|
||||
algorithm := uCryptoService.PrivKey.Algorithm()
|
||||
switch algorithm {
|
||||
var rootKey data.PublicKey
|
||||
switch uCryptoService.PrivKey.Algorithm() {
|
||||
case data.RSAKey:
|
||||
algorithmType = data.RSAx509Key
|
||||
rootKey = data.NewRSAx509PublicKey(trustmanager.CertToPEM(rootCert))
|
||||
case data.ECDSAKey:
|
||||
algorithmType = data.ECDSAx509Key
|
||||
rootKey = data.NewECDSAx509PublicKey(trustmanager.CertToPEM(rootCert))
|
||||
default:
|
||||
return fmt.Errorf("invalid format for root key: %s", algorithm)
|
||||
return fmt.Errorf("invalid format for root key: %s", uCryptoService.PrivKey.Algorithm())
|
||||
}
|
||||
|
||||
// Generate a x509Key using the rootCert as the public key
|
||||
rootKey := data.NewPublicKey(algorithmType, trustmanager.CertToPEM(rootCert))
|
||||
|
||||
// All the timestamp keys are generated by the remote server.
|
||||
remote, err := getRemoteStore(r.baseURL, r.gun, r.roundTrip)
|
||||
if err != nil {
|
||||
|
@ -173,15 +169,12 @@ func (r *NotaryRepository) Initialize(uCryptoService *cryptoservice.UnlockedCryp
|
|||
return err
|
||||
}
|
||||
|
||||
parsedKey := &data.TUFKey{}
|
||||
err = json.Unmarshal(rawTSKey, parsedKey)
|
||||
timestampKey, err := data.UnmarshalPublicKey(rawTSKey)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Turn the JSON timestamp key from the remote server into a TUFKey
|
||||
timestampKey := data.NewPublicKey(parsedKey.Algorithm(), parsedKey.Public())
|
||||
logrus.Debugf("got remote %s timestamp key with keyID: %s", parsedKey.Algorithm(), timestampKey.ID())
|
||||
logrus.Debugf("got remote %s timestamp key with keyID: %s", timestampKey.Algorithm(), timestampKey.ID())
|
||||
|
||||
// This is currently hardcoding the targets and snapshots keys to ECDSA
|
||||
// Targets and snapshot keys are always generated locally.
|
||||
|
@ -631,14 +624,9 @@ func (r *NotaryRepository) rootFileKeyChange(role, action string, key data.Publi
|
|||
}
|
||||
defer cl.Close()
|
||||
|
||||
k, ok := key.(*data.TUFKey)
|
||||
if !ok {
|
||||
return errors.New("Invalid key type found during rotation.")
|
||||
}
|
||||
|
||||
meta := changelist.TufRootData{
|
||||
RoleName: role,
|
||||
Keys: []data.TUFKey{*k},
|
||||
Keys: data.KeyList{key},
|
||||
}
|
||||
metaJSON, err := json.Marshal(meta)
|
||||
if err != nil {
|
||||
|
|
|
@ -28,7 +28,7 @@ func TestValidateRoot(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func validateRootSuccessfully(t *testing.T, rootType data.KeyAlgorithm) {
|
||||
func validateRootSuccessfully(t *testing.T, rootType string) {
|
||||
// Temporary directory where test files will be created
|
||||
tempBaseDir, err := ioutil.TempDir("", "notary-test-")
|
||||
defer os.RemoveAll(tempBaseDir)
|
||||
|
@ -43,7 +43,7 @@ func validateRootSuccessfully(t *testing.T, rootType data.KeyAlgorithm) {
|
|||
repo, err := NewNotaryRepository(tempBaseDir, gun, ts.URL, http.DefaultTransport, passphraseRetriever)
|
||||
assert.NoError(t, err, "error creating repository: %s", err)
|
||||
|
||||
rootKeyID, err := repo.KeyStoreManager.GenRootKey(rootType.String())
|
||||
rootKeyID, err := repo.KeyStoreManager.GenRootKey(rootType)
|
||||
assert.NoError(t, err, "error generating root key: %s", err)
|
||||
|
||||
rootCryptoService, err := repo.KeyStoreManager.GetRootCryptoService(rootKeyID)
|
||||
|
@ -63,10 +63,10 @@ func validateRootSuccessfully(t *testing.T, rootType data.KeyAlgorithm) {
|
|||
|
||||
// Now test ListTargets. In preparation, we need to expose some signed
|
||||
// metadata files on the internal HTTP server.
|
||||
var tempKey data.TUFKey
|
||||
json.Unmarshal([]byte(timestampECDSAKeyJSON), &tempKey)
|
||||
tempKey, err := data.UnmarshalPrivateKey([]byte(timestampECDSAKeyJSON))
|
||||
assert.NoError(t, err)
|
||||
|
||||
repo.KeyStoreManager.KeyStore.AddKey(filepath.Join(filepath.FromSlash(gun), tempKey.ID()), "root", &tempKey)
|
||||
repo.KeyStoreManager.KeyStore.AddKey(filepath.Join(filepath.FromSlash(gun), tempKey.ID()), "root", tempKey)
|
||||
|
||||
// Because ListTargets will clear this
|
||||
savedTUFRepo := repo.tufRepo
|
||||
|
|
|
@ -53,7 +53,7 @@ func TestInitRepo(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func testInitRepo(t *testing.T, rootType data.KeyAlgorithm) {
|
||||
func testInitRepo(t *testing.T, rootType string) {
|
||||
gun := "docker.com/notary"
|
||||
// Temporary directory where test files will be created
|
||||
tempBaseDir, err := ioutil.TempDir("", "notary-test-")
|
||||
|
@ -67,7 +67,7 @@ func testInitRepo(t *testing.T, rootType data.KeyAlgorithm) {
|
|||
repo, err := NewNotaryRepository(tempBaseDir, gun, ts.URL, http.DefaultTransport, passphraseRetriever)
|
||||
assert.NoError(t, err, "error creating repo: %s", err)
|
||||
|
||||
rootKeyID, err := repo.KeyStoreManager.GenRootKey(rootType.String())
|
||||
rootKeyID, err := repo.KeyStoreManager.GenRootKey(rootType)
|
||||
assert.NoError(t, err, "error generating root key: %s", err)
|
||||
|
||||
rootCryptoService, err := repo.KeyStoreManager.GetRootCryptoService(rootKeyID)
|
||||
|
@ -180,7 +180,7 @@ func TestAddListTarget(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func testAddListTarget(t *testing.T, rootType data.KeyAlgorithm) {
|
||||
func testAddListTarget(t *testing.T, rootType string) {
|
||||
// Temporary directory where test files will be created
|
||||
tempBaseDir, err := ioutil.TempDir("", "notary-test-")
|
||||
defer os.RemoveAll(tempBaseDir)
|
||||
|
@ -195,7 +195,7 @@ func testAddListTarget(t *testing.T, rootType data.KeyAlgorithm) {
|
|||
repo, err := NewNotaryRepository(tempBaseDir, gun, ts.URL, http.DefaultTransport, passphraseRetriever)
|
||||
assert.NoError(t, err, "error creating repository: %s", err)
|
||||
|
||||
rootKeyID, err := repo.KeyStoreManager.GenRootKey(rootType.String())
|
||||
rootKeyID, err := repo.KeyStoreManager.GenRootKey(rootType)
|
||||
assert.NoError(t, err, "error generating root key: %s", err)
|
||||
|
||||
rootCryptoService, err := repo.KeyStoreManager.GetRootCryptoService(rootKeyID)
|
||||
|
@ -298,10 +298,10 @@ func testAddListTarget(t *testing.T, rootType data.KeyAlgorithm) {
|
|||
err = applyChangelist(repo.tufRepo, cl)
|
||||
assert.NoError(t, err, "could not apply changelist")
|
||||
|
||||
var tempKey data.TUFKey
|
||||
json.Unmarshal([]byte(timestampECDSAKeyJSON), &tempKey)
|
||||
tempKey, err := data.UnmarshalPrivateKey([]byte(timestampECDSAKeyJSON))
|
||||
assert.NoError(t, err)
|
||||
|
||||
repo.KeyStoreManager.KeyStore.AddKey(filepath.Join(filepath.FromSlash(gun), tempKey.ID()), "nonroot", &tempKey)
|
||||
repo.KeyStoreManager.KeyStore.AddKey(filepath.Join(filepath.FromSlash(gun), tempKey.ID()), "nonroot", tempKey)
|
||||
|
||||
// Because ListTargets will clear this
|
||||
savedTUFRepo := repo.tufRepo
|
||||
|
@ -373,7 +373,7 @@ func TestValidateRootKey(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func testValidateRootKey(t *testing.T, rootType data.KeyAlgorithm) {
|
||||
func testValidateRootKey(t *testing.T, rootType string) {
|
||||
// Temporary directory where test files will be created
|
||||
tempBaseDir, err := ioutil.TempDir("", "notary-test-")
|
||||
defer os.RemoveAll(tempBaseDir)
|
||||
|
@ -388,7 +388,7 @@ func testValidateRootKey(t *testing.T, rootType data.KeyAlgorithm) {
|
|||
repo, err := NewNotaryRepository(tempBaseDir, gun, ts.URL, http.DefaultTransport, passphraseRetriever)
|
||||
assert.NoError(t, err, "error creating repository: %s", err)
|
||||
|
||||
rootKeyID, err := repo.KeyStoreManager.GenRootKey(rootType.String())
|
||||
rootKeyID, err := repo.KeyStoreManager.GenRootKey(rootType)
|
||||
assert.NoError(t, err, "error generating root key: %s", err)
|
||||
|
||||
rootCryptoService, err := repo.KeyStoreManager.GetRootCryptoService(rootKeyID)
|
||||
|
@ -438,7 +438,7 @@ func TestPublish(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func testPublish(t *testing.T, rootType data.KeyAlgorithm) {
|
||||
func testPublish(t *testing.T, rootType string) {
|
||||
// Temporary directory where test files will be created
|
||||
tempBaseDir, err := ioutil.TempDir("", "notary-test-")
|
||||
defer os.RemoveAll(tempBaseDir)
|
||||
|
@ -471,7 +471,7 @@ func testPublish(t *testing.T, rootType data.KeyAlgorithm) {
|
|||
repo, err := NewNotaryRepository(tempBaseDir, gun, ts.URL, http.DefaultTransport, passphraseRetriever)
|
||||
assert.NoError(t, err, "error creating repository: %s", err)
|
||||
|
||||
rootKeyID, err := repo.KeyStoreManager.GenRootKey(rootType.String())
|
||||
rootKeyID, err := repo.KeyStoreManager.GenRootKey(rootType)
|
||||
assert.NoError(t, err, "error generating root key: %s", err)
|
||||
|
||||
rootCryptoService, err := repo.KeyStoreManager.GetRootCryptoService(rootKeyID)
|
||||
|
@ -660,7 +660,7 @@ func TestRotate(t *testing.T) {
|
|||
repo, err := NewNotaryRepository(tempBaseDir, gun, ts.URL, http.DefaultTransport, passphraseRetriever)
|
||||
assert.NoError(t, err, "error creating repository: %s", err)
|
||||
|
||||
rootKeyID, err := repo.KeyStoreManager.GenRootKey(data.ECDSAKey.String())
|
||||
rootKeyID, err := repo.KeyStoreManager.GenRootKey(data.ECDSAKey)
|
||||
assert.NoError(t, err, "error generating root key: %s", err)
|
||||
|
||||
rootCryptoService, err := repo.KeyStoreManager.GetRootCryptoService(rootKeyID)
|
||||
|
|
|
@ -97,11 +97,7 @@ func applyRootRoleChange(repo *tuf.Repo, c changelist.Change) error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
k := []data.PublicKey{}
|
||||
for _, key := range d.Keys {
|
||||
k = append(k, data.NewPublicKey(key.Algorithm(), key.Public()))
|
||||
}
|
||||
err = repo.ReplaceBaseKeys(d.RoleName, k...)
|
||||
err = repo.ReplaceBaseKeys(d.RoleName, d.Keys...)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -33,7 +33,7 @@ func NewCryptoService(gun string, keyStore trustmanager.KeyStore) *CryptoService
|
|||
}
|
||||
|
||||
// Create is used to generate keys for targets, snapshots and timestamps
|
||||
func (ccs *CryptoService) Create(role string, algorithm data.KeyAlgorithm) (data.PublicKey, error) {
|
||||
func (ccs *CryptoService) Create(role string, algorithm string) (data.PublicKey, error) {
|
||||
var privKey data.PrivateKey
|
||||
var err error
|
||||
|
||||
|
|
|
@ -19,7 +19,7 @@ func TestCryptoService(t *testing.T) {
|
|||
|
||||
var passphraseRetriever = func(string, string, bool, int) (string, bool, error) { return "", false, nil }
|
||||
|
||||
func testCryptoService(t *testing.T, keyAlgo data.KeyAlgorithm, verifier signed.Verifier) {
|
||||
func testCryptoService(t *testing.T, keyAlgo string, verifier signed.Verifier) {
|
||||
content := []byte("this is a secret")
|
||||
|
||||
keyStore := trustmanager.NewKeyMemoryStore(passphraseRetriever)
|
||||
|
|
|
@ -57,7 +57,7 @@ func TestImportExportZip(t *testing.T) {
|
|||
repo, err := client.NewNotaryRepository(tempBaseDir, gun, ts.URL, http.DefaultTransport, oldPassphraseRetriever)
|
||||
assert.NoError(t, err, "error creating repo: %s", err)
|
||||
|
||||
rootKeyID, err := repo.KeyStoreManager.GenRootKey(data.ECDSAKey.String())
|
||||
rootKeyID, err := repo.KeyStoreManager.GenRootKey(data.ECDSAKey)
|
||||
assert.NoError(t, err, "error generating root key: %s", err)
|
||||
|
||||
rootCryptoService, err := repo.KeyStoreManager.GetRootCryptoService(rootKeyID)
|
||||
|
@ -138,7 +138,7 @@ func TestImportExportZip(t *testing.T) {
|
|||
repo2, err := client.NewNotaryRepository(tempBaseDir2, gun, ts.URL, http.DefaultTransport, newPassphraseRetriever)
|
||||
assert.NoError(t, err, "error creating repo: %s", err)
|
||||
|
||||
rootKeyID2, err := repo2.KeyStoreManager.GenRootKey(data.ECDSAKey.String())
|
||||
rootKeyID2, err := repo2.KeyStoreManager.GenRootKey(data.ECDSAKey)
|
||||
assert.NoError(t, err, "error generating root key: %s", err)
|
||||
|
||||
rootCryptoService2, err := repo2.KeyStoreManager.GetRootCryptoService(rootKeyID2)
|
||||
|
@ -194,7 +194,7 @@ func TestImportExportGUN(t *testing.T) {
|
|||
repo, err := client.NewNotaryRepository(tempBaseDir, gun, ts.URL, http.DefaultTransport, oldPassphraseRetriever)
|
||||
assert.NoError(t, err, "error creating repo: %s", err)
|
||||
|
||||
rootKeyID, err := repo.KeyStoreManager.GenRootKey(data.ECDSAKey.String())
|
||||
rootKeyID, err := repo.KeyStoreManager.GenRootKey(data.ECDSAKey)
|
||||
assert.NoError(t, err, "error generating root key: %s", err)
|
||||
|
||||
rootCryptoService, err := repo.KeyStoreManager.GetRootCryptoService(rootKeyID)
|
||||
|
@ -278,7 +278,7 @@ func TestImportExportGUN(t *testing.T) {
|
|||
repo2, err := client.NewNotaryRepository(tempBaseDir2, gun, ts.URL, http.DefaultTransport, oldPassphraseRetriever)
|
||||
assert.NoError(t, err, "error creating repo: %s", err)
|
||||
|
||||
rootKeyID2, err := repo2.KeyStoreManager.GenRootKey(data.ECDSAKey.String())
|
||||
rootKeyID2, err := repo2.KeyStoreManager.GenRootKey(data.ECDSAKey)
|
||||
assert.NoError(t, err, "error generating root key: %s", err)
|
||||
|
||||
rootCryptoService2, err := repo2.KeyStoreManager.GetRootCryptoService(rootKeyID2)
|
||||
|
@ -327,7 +327,7 @@ func TestImportExportRootKey(t *testing.T) {
|
|||
repo, err := client.NewNotaryRepository(tempBaseDir, gun, ts.URL, http.DefaultTransport, oldPassphraseRetriever)
|
||||
assert.NoError(t, err, "error creating repo: %s", err)
|
||||
|
||||
rootKeyID, err := repo.KeyStoreManager.GenRootKey(data.ECDSAKey.String())
|
||||
rootKeyID, err := repo.KeyStoreManager.GenRootKey(data.ECDSAKey)
|
||||
assert.NoError(t, err, "error generating root key: %s", err)
|
||||
|
||||
rootCryptoService, err := repo.KeyStoreManager.GetRootCryptoService(rootKeyID)
|
||||
|
@ -353,7 +353,7 @@ func TestImportExportRootKey(t *testing.T) {
|
|||
repo2, err := client.NewNotaryRepository(tempBaseDir2, gun, ts.URL, http.DefaultTransport, oldPassphraseRetriever)
|
||||
assert.NoError(t, err, "error creating repo: %s", err)
|
||||
|
||||
rootKeyID2, err := repo2.KeyStoreManager.GenRootKey(data.ECDSAKey.String())
|
||||
rootKeyID2, err := repo2.KeyStoreManager.GenRootKey(data.ECDSAKey)
|
||||
assert.NoError(t, err, "error generating root key: %s", err)
|
||||
|
||||
rootCryptoService2, err := repo2.KeyStoreManager.GetRootCryptoService(rootKeyID2)
|
||||
|
@ -414,7 +414,7 @@ func TestImportExportRootKeyReencrypt(t *testing.T) {
|
|||
repo, err := client.NewNotaryRepository(tempBaseDir, gun, ts.URL, http.DefaultTransport, oldPassphraseRetriever)
|
||||
assert.NoError(t, err, "error creating repo: %s", err)
|
||||
|
||||
rootKeyID, err := repo.KeyStoreManager.GenRootKey(data.ECDSAKey.String())
|
||||
rootKeyID, err := repo.KeyStoreManager.GenRootKey(data.ECDSAKey)
|
||||
assert.NoError(t, err, "error generating root key: %s", err)
|
||||
|
||||
rootCryptoService, err := repo.KeyStoreManager.GetRootCryptoService(rootKeyID)
|
||||
|
@ -440,7 +440,7 @@ func TestImportExportRootKeyReencrypt(t *testing.T) {
|
|||
repo2, err := client.NewNotaryRepository(tempBaseDir2, gun, ts.URL, http.DefaultTransport, newPassphraseRetriever)
|
||||
assert.NoError(t, err, "error creating repo: %s", err)
|
||||
|
||||
rootKeyID2, err := repo2.KeyStoreManager.GenRootKey(data.ECDSAKey.String())
|
||||
rootKeyID2, err := repo2.KeyStoreManager.GenRootKey(data.ECDSAKey)
|
||||
assert.NoError(t, err, "error generating root key: %s", err)
|
||||
|
||||
rootCryptoService2, err := repo2.KeyStoreManager.GetRootCryptoService(rootKeyID2)
|
||||
|
|
|
@ -127,7 +127,7 @@ func (km *KeyStoreManager) GenRootKey(algorithm string) (string, error) {
|
|||
// We don't want external API callers to rely on internal TUF data types, so
|
||||
// the API here should continue to receive a string algorithm, and ensure
|
||||
// that it is downcased
|
||||
switch data.KeyAlgorithm(strings.ToLower(algorithm)) {
|
||||
switch strings.ToLower(algorithm) {
|
||||
case data.RSAKey:
|
||||
privKey, err = trustmanager.GenerateRSAKey(rand.Reader, rsaRootKeySize)
|
||||
case data.ECDSAKey:
|
||||
|
|
|
@ -220,7 +220,7 @@ func TestValidateSuccessfulRootRotation(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func testValidateSuccessfulRootRotation(t *testing.T, keyAlg data.KeyAlgorithm, rootKeyType data.KeyAlgorithm) {
|
||||
func testValidateSuccessfulRootRotation(t *testing.T, keyAlg string, rootKeyType string) {
|
||||
// Temporary directory where test files will be created
|
||||
tempBaseDir, err := ioutil.TempDir("", "notary-test-")
|
||||
defer os.RemoveAll(tempBaseDir)
|
||||
|
@ -233,10 +233,10 @@ func testValidateSuccessfulRootRotation(t *testing.T, keyAlg data.KeyAlgorithm,
|
|||
keyStoreManager, err := NewKeyStoreManager(tempBaseDir, passphraseRetriever)
|
||||
assert.NoError(t, err)
|
||||
|
||||
origRootKeyID, err := keyStoreManager.GenRootKey(keyAlg.String())
|
||||
origRootKeyID, err := keyStoreManager.GenRootKey(keyAlg)
|
||||
assert.NoError(t, err)
|
||||
|
||||
replRootKeyID, err := keyStoreManager.GenRootKey(keyAlg.String())
|
||||
replRootKeyID, err := keyStoreManager.GenRootKey(keyAlg)
|
||||
assert.NoError(t, err)
|
||||
|
||||
origUnlockedCryptoService, err := keyStoreManager.GetRootCryptoService(origRootKeyID)
|
||||
|
@ -306,7 +306,7 @@ func TestValidateRootRotationMissingOrigSig(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func testValidateRootRotationMissingOrigSig(t *testing.T, keyAlg data.KeyAlgorithm, rootKeyType data.KeyAlgorithm) {
|
||||
func testValidateRootRotationMissingOrigSig(t *testing.T, keyAlg string, rootKeyType string) {
|
||||
// Temporary directory where test files will be created
|
||||
tempBaseDir, err := ioutil.TempDir("", "notary-test-")
|
||||
defer os.RemoveAll(tempBaseDir)
|
||||
|
@ -319,10 +319,10 @@ func testValidateRootRotationMissingOrigSig(t *testing.T, keyAlg data.KeyAlgorit
|
|||
keyStoreManager, err := NewKeyStoreManager(tempBaseDir, passphraseRetriever)
|
||||
assert.NoError(t, err)
|
||||
|
||||
origRootKeyID, err := keyStoreManager.GenRootKey(keyAlg.String())
|
||||
origRootKeyID, err := keyStoreManager.GenRootKey(keyAlg)
|
||||
assert.NoError(t, err)
|
||||
|
||||
replRootKeyID, err := keyStoreManager.GenRootKey(keyAlg.String())
|
||||
replRootKeyID, err := keyStoreManager.GenRootKey(keyAlg)
|
||||
assert.NoError(t, err)
|
||||
|
||||
origUnlockedCryptoService, err := keyStoreManager.GetRootCryptoService(origRootKeyID)
|
||||
|
@ -389,7 +389,7 @@ func TestValidateRootRotationMissingNewSig(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func testValidateRootRotationMissingNewSig(t *testing.T, keyAlg data.KeyAlgorithm, rootKeyType data.KeyAlgorithm) {
|
||||
func testValidateRootRotationMissingNewSig(t *testing.T, keyAlg string, rootKeyType string) {
|
||||
// Temporary directory where test files will be created
|
||||
tempBaseDir, err := ioutil.TempDir("", "notary-test-")
|
||||
defer os.RemoveAll(tempBaseDir)
|
||||
|
@ -402,10 +402,10 @@ func testValidateRootRotationMissingNewSig(t *testing.T, keyAlg data.KeyAlgorith
|
|||
keyStoreManager, err := NewKeyStoreManager(tempBaseDir, passphraseRetriever)
|
||||
assert.NoError(t, err)
|
||||
|
||||
origRootKeyID, err := keyStoreManager.GenRootKey(keyAlg.String())
|
||||
origRootKeyID, err := keyStoreManager.GenRootKey(keyAlg)
|
||||
assert.NoError(t, err)
|
||||
|
||||
replRootKeyID, err := keyStoreManager.GenRootKey(keyAlg.String())
|
||||
replRootKeyID, err := keyStoreManager.GenRootKey(keyAlg)
|
||||
assert.NoError(t, err)
|
||||
|
||||
origUnlockedCryptoService, err := keyStoreManager.GetRootCryptoService(origRootKeyID)
|
||||
|
|
|
@ -192,7 +192,7 @@ func GetTimestampKeyHandler(ctx context.Context, w http.ResponseWriter, r *http.
|
|||
logger.Error("500 GET key algorithm not configured")
|
||||
return errors.ErrNoKeyAlgorithm.WithDetail(nil)
|
||||
}
|
||||
keyAlgorithm := data.KeyAlgorithm(keyAlgo)
|
||||
keyAlgorithm := keyAlgo
|
||||
|
||||
key, err := timestamp.GetOrCreateTimestampKey(gun, store, crypto, keyAlgorithm)
|
||||
if err != nil {
|
||||
|
|
|
@ -239,7 +239,7 @@ func TestValidateRootRotation(t *testing.T) {
|
|||
delete(repo.Root.Signed.Keys, oldRootRole.KeyIDs[0])
|
||||
|
||||
repo.Root.Signed.Roles["root"] = &rootRole.RootRole
|
||||
repo.Root.Signed.Keys[rootKey.ID()] = data.NewPrivateKey(rootKey.Algorithm(), rootKey.Public(), nil)
|
||||
repo.Root.Signed.Keys[rootKey.ID()] = rootKey
|
||||
|
||||
r, err = repo.SignRoot(data.DefaultExpires(data.CanonicalRootRole), nil)
|
||||
assert.NoError(t, err)
|
||||
|
|
|
@ -4,7 +4,6 @@ import (
|
|||
"fmt"
|
||||
|
||||
"github.com/Sirupsen/logrus"
|
||||
"github.com/docker/notary/tuf/data"
|
||||
"github.com/go-sql-driver/mysql"
|
||||
"github.com/jinzhu/gorm"
|
||||
"github.com/mattn/go-sqlite3"
|
||||
|
@ -138,7 +137,7 @@ func (db *SQLStorage) Delete(gun string) error {
|
|||
}
|
||||
|
||||
// GetTimestampKey returns the timestamps Public Key data
|
||||
func (db *SQLStorage) GetTimestampKey(gun string) (algorithm data.KeyAlgorithm, public []byte, err error) {
|
||||
func (db *SQLStorage) GetTimestampKey(gun string) (algorithm string, public []byte, err error) {
|
||||
logrus.Debug("retrieving timestamp key for ", gun)
|
||||
|
||||
var row TimestampKey
|
||||
|
@ -150,11 +149,11 @@ func (db *SQLStorage) GetTimestampKey(gun string) (algorithm data.KeyAlgorithm,
|
|||
return "", nil, query.Error
|
||||
}
|
||||
|
||||
return data.KeyAlgorithm(row.Cipher), row.Public, nil
|
||||
return row.Cipher, row.Public, nil
|
||||
}
|
||||
|
||||
// SetTimestampKey attempts to write a TimeStamp key and returns an error if it already exists
|
||||
func (db *SQLStorage) SetTimestampKey(gun string, algorithm data.KeyAlgorithm, public []byte) error {
|
||||
func (db *SQLStorage) SetTimestampKey(gun string, algorithm string, public []byte) error {
|
||||
|
||||
entry := TimestampKey{
|
||||
Gun: gun,
|
||||
|
|
|
@ -5,7 +5,6 @@ import (
|
|||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/docker/notary/tuf/data"
|
||||
"github.com/jinzhu/gorm"
|
||||
_ "github.com/mattn/go-sqlite3"
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
@ -264,7 +263,7 @@ func TestSQLGetTimestampKeyNoKey(t *testing.T) {
|
|||
defer os.RemoveAll(tempBaseDir)
|
||||
|
||||
cipher, public, err := dbStore.GetTimestampKey("testGUN")
|
||||
assert.Equal(t, data.KeyAlgorithm(""), cipher)
|
||||
assert.Equal(t, "", cipher)
|
||||
assert.Nil(t, public)
|
||||
assert.IsType(t, &ErrNoKey{}, err,
|
||||
"Expected ErrNoKey from GetTimestampKey")
|
||||
|
@ -278,7 +277,7 @@ func TestSQLGetTimestampKeyNoKey(t *testing.T) {
|
|||
t, query.Error, "Inserting timestamp into empty DB should succeed")
|
||||
|
||||
cipher, public, err = dbStore.GetTimestampKey("testGUN")
|
||||
assert.Equal(t, data.KeyAlgorithm("testCipher"), cipher,
|
||||
assert.Equal(t, "testCipher", cipher,
|
||||
"Returned cipher was incorrect")
|
||||
assert.Equal(t, []byte("1"), public, "Returned pubkey was incorrect")
|
||||
}
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
package storage
|
||||
|
||||
import "github.com/docker/notary/tuf/data"
|
||||
|
||||
// MetaStore holds the methods that are used for a Metadata Store
|
||||
type MetaStore interface {
|
||||
// UpdateCurrent adds new metadata version for the given GUN if and only
|
||||
|
@ -26,9 +24,9 @@ type MetaStore interface {
|
|||
|
||||
// GetTimestampKey returns the algorithm and public key for the given GUN.
|
||||
// If the GUN doesn't exist, returns an error.
|
||||
GetTimestampKey(gun string) (algorithm data.KeyAlgorithm, public []byte, err error)
|
||||
GetTimestampKey(gun string) (algorithm string, public []byte, err error)
|
||||
|
||||
// SetTimeStampKey sets the algorithm and public key for the given GUN if
|
||||
// it doesn't already exist. Otherwise an error is returned.
|
||||
SetTimestampKey(gun string, algorithm data.KeyAlgorithm, public []byte) error
|
||||
SetTimestampKey(gun string, algorithm string, public []byte) error
|
||||
}
|
||||
|
|
|
@ -4,12 +4,10 @@ import (
|
|||
"fmt"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"github.com/docker/notary/tuf/data"
|
||||
)
|
||||
|
||||
type key struct {
|
||||
algorithm data.KeyAlgorithm
|
||||
algorithm string
|
||||
public []byte
|
||||
}
|
||||
|
||||
|
@ -83,7 +81,7 @@ func (st *MemStorage) Delete(gun string) error {
|
|||
}
|
||||
|
||||
// GetTimestampKey returns the public key material of the timestamp key of a given gun
|
||||
func (st *MemStorage) GetTimestampKey(gun string) (algorithm data.KeyAlgorithm, public []byte, err error) {
|
||||
func (st *MemStorage) GetTimestampKey(gun string) (algorithm string, public []byte, err error) {
|
||||
// no need for lock. It's ok to return nil if an update
|
||||
// wasn't observed
|
||||
k, ok := st.tsKeys[gun]
|
||||
|
@ -95,7 +93,7 @@ func (st *MemStorage) GetTimestampKey(gun string) (algorithm data.KeyAlgorithm,
|
|||
}
|
||||
|
||||
// SetTimestampKey sets a Timestamp key under a gun
|
||||
func (st *MemStorage) SetTimestampKey(gun string, algorithm data.KeyAlgorithm, public []byte) error {
|
||||
func (st *MemStorage) SetTimestampKey(gun string, algorithm string, public []byte) error {
|
||||
k := &key{algorithm: algorithm, public: public}
|
||||
st.lock.Lock()
|
||||
defer st.lock.Unlock()
|
||||
|
|
|
@ -16,7 +16,7 @@ import (
|
|||
// found. It attempts to handle the race condition that may occur if 2 servers try to
|
||||
// create the key at the same time by simply querying the store a second time if it
|
||||
// receives a conflict when writing.
|
||||
func GetOrCreateTimestampKey(gun string, store storage.MetaStore, crypto signed.CryptoService, fallBackAlgorithm data.KeyAlgorithm) (data.PublicKey, error) {
|
||||
func GetOrCreateTimestampKey(gun string, store storage.MetaStore, crypto signed.CryptoService, fallBackAlgorithm string) (data.PublicKey, error) {
|
||||
keyAlgorithm, public, err := store.GetTimestampKey(gun)
|
||||
if err == nil {
|
||||
return data.NewPublicKey(keyAlgorithm, public), nil
|
||||
|
|
|
@ -6,7 +6,6 @@ import (
|
|||
|
||||
"github.com/docker/notary/signer"
|
||||
"github.com/docker/notary/signer/keys"
|
||||
"github.com/docker/notary/tuf/data"
|
||||
"github.com/docker/notary/tuf/signed"
|
||||
"github.com/gorilla/mux"
|
||||
|
||||
|
@ -34,7 +33,7 @@ func getCryptoService(w http.ResponseWriter, algorithm string, cryptoServices si
|
|||
return nil
|
||||
}
|
||||
|
||||
service := cryptoServices[data.KeyAlgorithm(algorithm)]
|
||||
service := cryptoServices[algorithm]
|
||||
|
||||
if service == nil {
|
||||
http.Error(w, "algorithm "+algorithm+" not supported", http.StatusBadRequest)
|
||||
|
@ -67,7 +66,7 @@ func KeyInfo(cryptoServices signer.CryptoServiceIndex) http.Handler {
|
|||
key := &pb.PublicKey{
|
||||
KeyInfo: &pb.KeyInfo{
|
||||
KeyID: &pb.KeyID{ID: tufKey.ID()},
|
||||
Algorithm: &pb.Algorithm{Algorithm: tufKey.Algorithm().String()},
|
||||
Algorithm: &pb.Algorithm{Algorithm: tufKey.Algorithm()},
|
||||
},
|
||||
PublicKey: tufKey.Public(),
|
||||
}
|
||||
|
@ -86,7 +85,7 @@ func CreateKey(cryptoServices signer.CryptoServiceIndex) http.Handler {
|
|||
return
|
||||
}
|
||||
|
||||
tufKey, err := cryptoService.Create("", data.KeyAlgorithm(vars["Algorithm"]))
|
||||
tufKey, err := cryptoService.Create("", vars["Algorithm"])
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
w.Write([]byte(err.Error()))
|
||||
|
@ -95,7 +94,7 @@ func CreateKey(cryptoServices signer.CryptoServiceIndex) http.Handler {
|
|||
key := &pb.PublicKey{
|
||||
KeyInfo: &pb.KeyInfo{
|
||||
KeyID: &pb.KeyID{ID: tufKey.ID()},
|
||||
Algorithm: &pb.Algorithm{Algorithm: tufKey.Algorithm().String()},
|
||||
Algorithm: &pb.Algorithm{Algorithm: tufKey.Algorithm()},
|
||||
},
|
||||
PublicKey: tufKey.Public(),
|
||||
}
|
||||
|
@ -188,7 +187,7 @@ func Sign(cryptoServices signer.CryptoServiceIndex) http.Handler {
|
|||
signature := &pb.Signature{
|
||||
KeyInfo: &pb.KeyInfo{
|
||||
KeyID: &pb.KeyID{ID: tufKey.ID()},
|
||||
Algorithm: &pb.Algorithm{Algorithm: tufKey.Algorithm().String()},
|
||||
Algorithm: &pb.Algorithm{Algorithm: tufKey.Algorithm()},
|
||||
},
|
||||
Content: signatures[0].Signature,
|
||||
}
|
||||
|
|
|
@ -14,7 +14,7 @@ import (
|
|||
// or ErrInvalidKeyID if the key is not found in any of the signing services.
|
||||
// It also returns the CryptoService associated with the key, so the caller
|
||||
// can perform operations with the key (such as signing).
|
||||
func FindKeyByID(cryptoServices signer.CryptoServiceIndex, keyID *pb.KeyID) (data.Key, signed.CryptoService, error) {
|
||||
func FindKeyByID(cryptoServices signer.CryptoServiceIndex, keyID *pb.KeyID) (data.PublicKey, signed.CryptoService, error) {
|
||||
for _, service := range cryptoServices {
|
||||
key := service.GetKey(keyID.ID)
|
||||
if key != nil {
|
||||
|
|
|
@ -6,7 +6,6 @@ import (
|
|||
ctxu "github.com/docker/distribution/context"
|
||||
"github.com/docker/notary/signer"
|
||||
"github.com/docker/notary/signer/keys"
|
||||
"github.com/docker/notary/tuf/data"
|
||||
"golang.org/x/net/context"
|
||||
|
||||
"google.golang.org/grpc"
|
||||
|
@ -29,7 +28,7 @@ type SignerServer struct {
|
|||
|
||||
//CreateKey returns a PublicKey created using KeyManagementServer's SigningService
|
||||
func (s *KeyManagementServer) CreateKey(ctx context.Context, algorithm *pb.Algorithm) (*pb.PublicKey, error) {
|
||||
keyAlgo := data.KeyAlgorithm(algorithm.Algorithm)
|
||||
keyAlgo := algorithm.Algorithm
|
||||
|
||||
service := s.CryptoServices[keyAlgo]
|
||||
|
||||
|
@ -49,7 +48,7 @@ func (s *KeyManagementServer) CreateKey(ctx context.Context, algorithm *pb.Algor
|
|||
return &pb.PublicKey{
|
||||
KeyInfo: &pb.KeyInfo{
|
||||
KeyID: &pb.KeyID{ID: tufKey.ID()},
|
||||
Algorithm: &pb.Algorithm{Algorithm: tufKey.Algorithm().String()},
|
||||
Algorithm: &pb.Algorithm{Algorithm: tufKey.Algorithm()},
|
||||
},
|
||||
PublicKey: tufKey.Public(),
|
||||
}, nil
|
||||
|
@ -102,7 +101,7 @@ func (s *KeyManagementServer) GetKeyInfo(ctx context.Context, keyID *pb.KeyID) (
|
|||
return &pb.PublicKey{
|
||||
KeyInfo: &pb.KeyInfo{
|
||||
KeyID: &pb.KeyID{ID: tufKey.ID()},
|
||||
Algorithm: &pb.Algorithm{Algorithm: tufKey.Algorithm().String()},
|
||||
Algorithm: &pb.Algorithm{Algorithm: tufKey.Algorithm()},
|
||||
},
|
||||
PublicKey: tufKey.Public(),
|
||||
}, nil
|
||||
|
@ -137,7 +136,7 @@ func (s *SignerServer) Sign(ctx context.Context, sr *pb.SignatureRequest) (*pb.S
|
|||
signature := &pb.Signature{
|
||||
KeyInfo: &pb.KeyInfo{
|
||||
KeyID: &pb.KeyID{ID: tufKey.ID()},
|
||||
Algorithm: &pb.Algorithm{Algorithm: tufKey.Algorithm().String()},
|
||||
Algorithm: &pb.Algorithm{Algorithm: tufKey.Algorithm()},
|
||||
},
|
||||
Algorithm: &pb.Algorithm{Algorithm: signatures[0].Method.String()},
|
||||
Content: signatures[0].Signature,
|
||||
|
|
|
@ -79,7 +79,7 @@ func TestDeleteKeyHandlerReturnsNotFoundWithNonexistentKey(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestCreateKeyHandlerCreatesKey(t *testing.T) {
|
||||
publicKey, err := kmClient.CreateKey(context.Background(), &pb.Algorithm{Algorithm: data.ED25519Key.String()})
|
||||
publicKey, err := kmClient.CreateKey(context.Background(), &pb.Algorithm{Algorithm: data.ED25519Key})
|
||||
assert.NotNil(t, publicKey)
|
||||
assert.NotEmpty(t, publicKey.PublicKey)
|
||||
assert.NotEmpty(t, publicKey.KeyInfo)
|
||||
|
@ -88,14 +88,14 @@ func TestCreateKeyHandlerCreatesKey(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestDeleteKeyHandlerDeletesCreatedKey(t *testing.T) {
|
||||
publicKey, err := kmClient.CreateKey(context.Background(), &pb.Algorithm{Algorithm: data.ED25519Key.String()})
|
||||
publicKey, err := kmClient.CreateKey(context.Background(), &pb.Algorithm{Algorithm: data.ED25519Key})
|
||||
ret, err := kmClient.DeleteKey(context.Background(), publicKey.KeyInfo.KeyID)
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, ret, void)
|
||||
}
|
||||
|
||||
func TestKeyInfoReturnsCreatedKeys(t *testing.T) {
|
||||
publicKey, err := kmClient.CreateKey(context.Background(), &pb.Algorithm{Algorithm: data.ED25519Key.String()})
|
||||
publicKey, err := kmClient.CreateKey(context.Background(), &pb.Algorithm{Algorithm: data.ED25519Key})
|
||||
fmt.Println("Pubkey ID: " + publicKey.GetKeyInfo().KeyID.ID)
|
||||
returnedPublicKey, err := kmClient.GetKeyInfo(context.Background(), publicKey.KeyInfo.KeyID)
|
||||
fmt.Println("returnedPublicKey ID: " + returnedPublicKey.GetKeyInfo().KeyID.ID)
|
||||
|
@ -106,9 +106,9 @@ func TestKeyInfoReturnsCreatedKeys(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestCreateKeyCreatesNewKeys(t *testing.T) {
|
||||
publicKey1, err := kmClient.CreateKey(context.Background(), &pb.Algorithm{Algorithm: data.ED25519Key.String()})
|
||||
publicKey1, err := kmClient.CreateKey(context.Background(), &pb.Algorithm{Algorithm: data.ED25519Key})
|
||||
assert.Nil(t, err)
|
||||
publicKey2, err := kmClient.CreateKey(context.Background(), &pb.Algorithm{Algorithm: data.ED25519Key.String()})
|
||||
publicKey2, err := kmClient.CreateKey(context.Background(), &pb.Algorithm{Algorithm: data.ED25519Key})
|
||||
assert.Nil(t, err)
|
||||
assert.NotEqual(t, publicKey1, publicKey2)
|
||||
assert.NotEqual(t, publicKey1.KeyInfo, publicKey2.KeyInfo)
|
||||
|
@ -128,7 +128,7 @@ func TestGetKeyInfoReturnsNotFoundOnNonexistKeys(t *testing.T) {
|
|||
func TestCreatedKeysCanBeUsedToSign(t *testing.T) {
|
||||
message := []byte{0, 0, 0, 0}
|
||||
|
||||
publicKey, err := kmClient.CreateKey(context.Background(), &pb.Algorithm{Algorithm: data.ED25519Key.String()})
|
||||
publicKey, err := kmClient.CreateKey(context.Background(), &pb.Algorithm{Algorithm: data.ED25519Key})
|
||||
assert.Nil(t, err)
|
||||
assert.NotNil(t, publicKey)
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@ type RSAHardwareCryptoService struct {
|
|||
}
|
||||
|
||||
// Create creates a key and returns its public components
|
||||
func (s *RSAHardwareCryptoService) Create(role string, algo data.KeyAlgorithm) (data.PublicKey, error) {
|
||||
func (s *RSAHardwareCryptoService) Create(role string, algo string) (data.PublicKey, error) {
|
||||
// For now generate random labels for keys
|
||||
// (diogo): add link between keyID and label in database so we can support multiple keys
|
||||
randomLabel := make([]byte, 32)
|
||||
|
|
|
@ -77,7 +77,7 @@ func (s *KeyDBStore) AddKey(name, alias string, privKey data.PrivateKey) error {
|
|||
EncryptionAlg: EncryptionAlg,
|
||||
KeywrapAlg: KeywrapAlg,
|
||||
PassphraseAlias: s.defaultPassAlias,
|
||||
Algorithm: privKey.Algorithm().String(),
|
||||
Algorithm: privKey.Algorithm(),
|
||||
Public: string(privKey.Public()),
|
||||
Private: encryptedKey}
|
||||
|
||||
|
@ -124,8 +124,9 @@ func (s *KeyDBStore) GetKey(name string) (data.PrivateKey, string, error) {
|
|||
return nil, "", err
|
||||
}
|
||||
|
||||
pubKey := data.NewPublicKey(dbPrivateKey.Algorithm, []byte(dbPrivateKey.Public))
|
||||
// Create a new PrivateKey with unencrypted bytes
|
||||
privKey := data.NewPrivateKey(data.KeyAlgorithm(dbPrivateKey.Algorithm), []byte(dbPrivateKey.Public), []byte(decryptedPrivKey))
|
||||
privKey := data.NewPrivateKey(pubKey, []byte(decryptedPrivKey))
|
||||
|
||||
// Add the key to cache
|
||||
s.cachedKeys[privKey.ID()] = privKey
|
||||
|
|
|
@ -32,7 +32,7 @@ func NewHSMRSAKey(public []byte, private pkcs11.ObjectHandle) *HSMRSAKey {
|
|||
}
|
||||
|
||||
// Algorithm implements a method of the data.Key interface
|
||||
func (rsa *HSMRSAKey) Algorithm() data.KeyAlgorithm {
|
||||
func (rsa *HSMRSAKey) Algorithm() string {
|
||||
return data.RSAKey
|
||||
}
|
||||
|
||||
|
|
|
@ -2,7 +2,6 @@ package signer
|
|||
|
||||
import (
|
||||
pb "github.com/docker/notary/proto"
|
||||
"github.com/docker/notary/tuf/data"
|
||||
"github.com/docker/notary/tuf/signed"
|
||||
)
|
||||
|
||||
|
@ -16,7 +15,7 @@ type SigningService interface {
|
|||
|
||||
// CryptoServiceIndex represents a mapping between a service algorithm string
|
||||
// and a CryptoService
|
||||
type CryptoServiceIndex map[data.KeyAlgorithm]signed.CryptoService
|
||||
type CryptoServiceIndex map[string]signed.CryptoService
|
||||
|
||||
// KeyManager is the interface to implement key management (possibly a key database)
|
||||
type KeyManager interface {
|
||||
|
|
|
@ -77,12 +77,12 @@ func (trust *NotarySigner) Sign(keyIDs []string, toSign []byte) ([]data.Signatur
|
|||
}
|
||||
|
||||
// Create creates a remote key and returns the PublicKey associated with the remote private key
|
||||
func (trust *NotarySigner) Create(role string, algorithm data.KeyAlgorithm) (data.PublicKey, error) {
|
||||
publicKey, err := trust.kmClient.CreateKey(context.Background(), &pb.Algorithm{Algorithm: algorithm.String()})
|
||||
func (trust *NotarySigner) Create(role string, algorithm string) (data.PublicKey, error) {
|
||||
publicKey, err := trust.kmClient.CreateKey(context.Background(), &pb.Algorithm{Algorithm: algorithm})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
public := data.NewPublicKey(data.KeyAlgorithm(publicKey.KeyInfo.Algorithm.Algorithm), publicKey.PublicKey)
|
||||
public := data.NewPublicKey(publicKey.KeyInfo.Algorithm.Algorithm, publicKey.PublicKey)
|
||||
return public, nil
|
||||
}
|
||||
|
||||
|
@ -98,7 +98,7 @@ func (trust *NotarySigner) GetKey(keyid string) data.PublicKey {
|
|||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
return data.NewPublicKey(data.KeyAlgorithm(publicKey.KeyInfo.Algorithm.Algorithm), publicKey.PublicKey)
|
||||
return data.NewPublicKey(publicKey.KeyInfo.Algorithm.Algorithm, publicKey.PublicKey)
|
||||
}
|
||||
|
||||
// CheckHealth checks the health of one of the clients, since both clients run
|
||||
|
|
|
@ -9,7 +9,7 @@ import (
|
|||
"testing"
|
||||
|
||||
"github.com/docker/notary/pkg/passphrase"
|
||||
"github.com/endophage/gotuf/data"
|
||||
"github.com/docker/notary/tuf/data"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
|
|
|
@ -102,19 +102,16 @@ func fingerprintCert(cert *x509.Certificate) (CertID, error) {
|
|||
block := pem.Block{Type: "CERTIFICATE", Bytes: cert.Raw}
|
||||
pemdata := pem.EncodeToMemory(&block)
|
||||
|
||||
var keyType data.KeyAlgorithm
|
||||
var tufKey data.PublicKey
|
||||
switch cert.PublicKeyAlgorithm {
|
||||
case x509.RSA:
|
||||
keyType = data.RSAx509Key
|
||||
tufKey = data.NewRSAx509PublicKey(pemdata)
|
||||
case x509.ECDSA:
|
||||
keyType = data.ECDSAx509Key
|
||||
tufKey = data.NewECDSAx509PublicKey(pemdata)
|
||||
default:
|
||||
return "", fmt.Errorf("got Unknown key type while fingerprinting certificate")
|
||||
}
|
||||
|
||||
// Create new TUF Key so we can compute the TUF-compliant CertID
|
||||
tufKey := data.NewPublicKey(keyType, pemdata)
|
||||
|
||||
return CertID(tufKey.ID()), nil
|
||||
}
|
||||
|
||||
|
@ -327,7 +324,8 @@ func RSAToPrivateKey(rsaPrivKey *rsa.PrivateKey) (data.PrivateKey, error) {
|
|||
// Get a DER-encoded representation of the PrivateKey
|
||||
rsaPrivBytes := x509.MarshalPKCS1PrivateKey(rsaPrivKey)
|
||||
|
||||
return data.NewPrivateKey(data.RSAKey, rsaPubBytes, rsaPrivBytes), nil
|
||||
pubKey := data.NewRSAPublicKey(rsaPubBytes)
|
||||
return data.NewRSAPrivateKey(*pubKey, rsaPrivBytes), nil
|
||||
}
|
||||
|
||||
// GenerateECDSAKey generates an ECDSA Private key and returns a TUF PrivateKey
|
||||
|
@ -384,7 +382,8 @@ func ECDSAToPrivateKey(ecdsaPrivKey *ecdsa.PrivateKey) (data.PrivateKey, error)
|
|||
return nil, fmt.Errorf("failed to marshal private key: %v", err)
|
||||
}
|
||||
|
||||
return data.NewPrivateKey(data.ECDSAKey, ecdsaPubBytes, ecdsaPrivKeyBytes), nil
|
||||
pubKey := data.NewECDSAPublicKey(ecdsaPubBytes)
|
||||
return data.NewECDSAPrivateKey(*pubKey, ecdsaPrivKeyBytes), nil
|
||||
}
|
||||
|
||||
// ED25519ToPrivateKey converts a serialized ED25519 key to a TUF
|
||||
|
@ -394,36 +393,37 @@ func ED25519ToPrivateKey(privKeyBytes []byte) (data.PrivateKey, error) {
|
|||
return nil, errors.New("malformed ed25519 private key")
|
||||
}
|
||||
|
||||
return data.NewPrivateKey(data.ED25519Key, privKeyBytes[:ed25519.PublicKeySize], privKeyBytes), nil
|
||||
pubKey := data.NewED25519PublicKey(privKeyBytes[:ed25519.PublicKeySize])
|
||||
return data.NewED25519PrivateKey(*pubKey, privKeyBytes), nil
|
||||
}
|
||||
|
||||
func blockType(algorithm data.KeyAlgorithm) (string, error) {
|
||||
switch algorithm {
|
||||
case data.RSAKey:
|
||||
func blockType(k data.PrivateKey) (string, error) {
|
||||
switch k.(type) {
|
||||
case *data.RSAPrivateKey:
|
||||
return "RSA PRIVATE KEY", nil
|
||||
case data.ECDSAKey:
|
||||
case *data.ECDSAPrivateKey:
|
||||
return "EC PRIVATE KEY", nil
|
||||
case data.ED25519Key:
|
||||
case *data.ED25519PrivateKey:
|
||||
return "ED25519 PRIVATE KEY", nil
|
||||
default:
|
||||
return "", fmt.Errorf("algorithm %s not supported", algorithm)
|
||||
return "", fmt.Errorf("algorithm %s not supported", k.Algorithm())
|
||||
}
|
||||
}
|
||||
|
||||
// KeyToPEM returns a PEM encoded key from a Private Key
|
||||
func KeyToPEM(privKey data.PrivateKey) ([]byte, error) {
|
||||
blockType, err := blockType(privKey.Algorithm())
|
||||
bt, err := blockType(privKey)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return pem.EncodeToMemory(&pem.Block{Type: blockType, Bytes: privKey.Private()}), nil
|
||||
return pem.EncodeToMemory(&pem.Block{Type: bt, Bytes: privKey.Private()}), nil
|
||||
}
|
||||
|
||||
// EncryptPrivateKey returns an encrypted PEM key given a Privatekey
|
||||
// and a passphrase
|
||||
func EncryptPrivateKey(key data.PrivateKey, passphrase string) ([]byte, error) {
|
||||
blockType, err := blockType(key.Algorithm())
|
||||
bt, err := blockType(key)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -432,7 +432,7 @@ func EncryptPrivateKey(key data.PrivateKey, passphrase string) ([]byte, error) {
|
|||
cipherType := x509.PEMCipherAES256
|
||||
|
||||
encryptedPEMBlock, err := x509.EncryptPEMBlock(rand.Reader,
|
||||
blockType,
|
||||
bt,
|
||||
key.Private(),
|
||||
password,
|
||||
cipherType)
|
||||
|
@ -449,17 +449,15 @@ func CertToKey(cert *x509.Certificate) data.PublicKey {
|
|||
block := pem.Block{Type: "CERTIFICATE", Bytes: cert.Raw}
|
||||
pemdata := pem.EncodeToMemory(&block)
|
||||
|
||||
var keyType data.KeyAlgorithm
|
||||
switch cert.PublicKeyAlgorithm {
|
||||
case x509.RSA:
|
||||
keyType = data.RSAx509Key
|
||||
return data.NewRSAx509PublicKey(pemdata)
|
||||
case x509.ECDSA:
|
||||
keyType = data.ECDSAx509Key
|
||||
return data.NewECDSAx509PublicKey(pemdata)
|
||||
default:
|
||||
logrus.Debugf("unknown certificate type found, ignoring")
|
||||
logrus.Debugf("Unknown key type parsed from certificate: %v", cert.PublicKeyAlgorithm)
|
||||
return nil
|
||||
}
|
||||
|
||||
return data.NewPublicKey(keyType, pemdata)
|
||||
}
|
||||
|
||||
// CertsToKeys transforms each of the input certificates into it's corresponding
|
||||
|
@ -507,18 +505,18 @@ func X509PublicKeyID(certPubKey data.PublicKey) (string, error) {
|
|||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
var finalAlgorithm data.KeyAlgorithm
|
||||
|
||||
switch certPubKey.Algorithm() {
|
||||
case data.ECDSAx509Key:
|
||||
finalAlgorithm = data.ECDSAKey
|
||||
case data.RSAx509Key:
|
||||
finalAlgorithm = data.RSAKey
|
||||
}
|
||||
|
||||
pubKeyBytes, err := x509.MarshalPKIXPublicKey(cert.PublicKey)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return data.NewPublicKey(finalAlgorithm, pubKeyBytes).ID(), nil
|
||||
|
||||
var key data.PublicKey
|
||||
switch certPubKey.Algorithm() {
|
||||
case data.ECDSAx509Key:
|
||||
key = data.NewECDSAPublicKey(pubKeyBytes)
|
||||
case data.RSAx509Key:
|
||||
key = data.NewRSAPublicKey(pubKeyBytes)
|
||||
}
|
||||
|
||||
return key.ID(), nil
|
||||
}
|
||||
|
|
372
tuf/data/keys.go
372
tuf/data/keys.go
|
@ -8,22 +8,16 @@ import (
|
|||
"github.com/jfrazelle/go/canonical/json"
|
||||
)
|
||||
|
||||
// Key is the minimal interface for a public key. It is declared
|
||||
// independently of PublicKey for composability.
|
||||
type Key interface {
|
||||
ID() string
|
||||
Algorithm() KeyAlgorithm
|
||||
Public() []byte
|
||||
}
|
||||
|
||||
// PublicKey is the necessary interface for public keys
|
||||
type PublicKey interface {
|
||||
Key
|
||||
ID() string
|
||||
Algorithm() string
|
||||
Public() []byte
|
||||
}
|
||||
|
||||
// PrivateKey adds the ability to access the private key
|
||||
type PrivateKey interface {
|
||||
Key
|
||||
PublicKey
|
||||
|
||||
Private() []byte
|
||||
}
|
||||
|
@ -34,38 +28,165 @@ type KeyPair struct {
|
|||
Private []byte `json:"private"`
|
||||
}
|
||||
|
||||
// TUFKey is the structure used for both public and private keys in TUF.
|
||||
type Keys map[string]PublicKey
|
||||
|
||||
func (ks *Keys) UnmarshalJSON(data []byte) error {
|
||||
parsed := make(map[string]tufKey)
|
||||
err := json.Unmarshal(data, &parsed)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
final := make(map[string]PublicKey)
|
||||
for k, tk := range parsed {
|
||||
final[k] = typedPublicKey(tk)
|
||||
}
|
||||
*ks = final
|
||||
return nil
|
||||
}
|
||||
|
||||
type KeyList []PublicKey
|
||||
|
||||
func (ks *KeyList) UnmarshalJSON(data []byte) error {
|
||||
parsed := make([]tufKey, 0, 1)
|
||||
err := json.Unmarshal(data, &parsed)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
final := make([]PublicKey, 0, len(parsed))
|
||||
for _, tk := range parsed {
|
||||
final = append(final, typedPublicKey(tk))
|
||||
}
|
||||
*ks = final
|
||||
return nil
|
||||
}
|
||||
|
||||
func typedPublicKey(tk tufKey) PublicKey {
|
||||
switch tk.Algorithm() {
|
||||
case ECDSAKey:
|
||||
return &ECDSAPublicKey{tufKey: tk}
|
||||
case ECDSAx509Key:
|
||||
return &ECDSAx509PublicKey{tufKey: tk}
|
||||
case RSAKey:
|
||||
return &RSAPublicKey{tufKey: tk}
|
||||
case RSAx509Key:
|
||||
return &RSAx509PublicKey{tufKey: tk}
|
||||
case ED25519Key:
|
||||
return &ED25519PublicKey{tufKey: tk}
|
||||
}
|
||||
return &UnknownPublicKey{tufKey: tk}
|
||||
}
|
||||
|
||||
func typedPrivateKey(tk tufKey) PrivateKey {
|
||||
private := tk.Value.Private
|
||||
tk.Value.Private = nil
|
||||
switch tk.Algorithm() {
|
||||
case ECDSAKey:
|
||||
return &ECDSAPrivateKey{
|
||||
ECDSAPublicKey: ECDSAPublicKey{
|
||||
tufKey: tk,
|
||||
},
|
||||
private: private,
|
||||
}
|
||||
case ECDSAx509Key:
|
||||
return &ECDSAx509PrivateKey{
|
||||
ECDSAx509PublicKey: ECDSAx509PublicKey{
|
||||
tufKey: tk,
|
||||
},
|
||||
private: private,
|
||||
}
|
||||
case RSAKey:
|
||||
return &RSAPrivateKey{
|
||||
RSAPublicKey: RSAPublicKey{
|
||||
tufKey: tk,
|
||||
},
|
||||
private: private,
|
||||
}
|
||||
case RSAx509Key:
|
||||
return &RSAx509PrivateKey{
|
||||
RSAx509PublicKey: RSAx509PublicKey{
|
||||
tufKey: tk,
|
||||
},
|
||||
private: private,
|
||||
}
|
||||
case ED25519Key:
|
||||
return &ED25519PrivateKey{
|
||||
ED25519PublicKey: ED25519PublicKey{
|
||||
tufKey: tk,
|
||||
},
|
||||
private: private,
|
||||
}
|
||||
}
|
||||
return &UnknownPrivateKey{
|
||||
tufKey: tk,
|
||||
private: private,
|
||||
}
|
||||
}
|
||||
|
||||
func NewPublicKey(alg string, public []byte) PublicKey {
|
||||
tk := tufKey{
|
||||
Type: alg,
|
||||
Value: KeyPair{
|
||||
Public: public,
|
||||
},
|
||||
}
|
||||
return typedPublicKey(tk)
|
||||
}
|
||||
|
||||
func NewPrivateKey(pubKey PublicKey, private []byte) PrivateKey {
|
||||
tk := tufKey{
|
||||
Type: pubKey.Algorithm(),
|
||||
Value: KeyPair{
|
||||
Public: pubKey.Public(),
|
||||
Private: private, // typedPrivateKey moves this value
|
||||
},
|
||||
}
|
||||
return typedPrivateKey(tk)
|
||||
}
|
||||
|
||||
func UnmarshalPublicKey(data []byte) (PublicKey, error) {
|
||||
var parsed tufKey
|
||||
err := json.Unmarshal(data, &parsed)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return typedPublicKey(parsed), nil
|
||||
}
|
||||
|
||||
func UnmarshalPrivateKey(data []byte) (PrivateKey, error) {
|
||||
var parsed tufKey
|
||||
err := json.Unmarshal(data, &parsed)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return typedPrivateKey(parsed), nil
|
||||
}
|
||||
|
||||
// tufKey is the structure used for both public and private keys in TUF.
|
||||
// Normally it would make sense to use a different structures for public and
|
||||
// private keys, but that would change the key ID algorithm (since the canonical
|
||||
// JSON would be different). This structure should normally be accessed through
|
||||
// the PublicKey or PrivateKey interfaces.
|
||||
type TUFKey struct {
|
||||
type tufKey struct {
|
||||
id string
|
||||
Type KeyAlgorithm `json:"keytype"`
|
||||
Value KeyPair `json:"keyval"`
|
||||
}
|
||||
|
||||
// NewPrivateKey instantiates a new TUFKey with the private key component
|
||||
// populated
|
||||
func NewPrivateKey(algorithm KeyAlgorithm, public, private []byte) *TUFKey {
|
||||
return &TUFKey{
|
||||
Type: algorithm,
|
||||
Value: KeyPair{
|
||||
Public: public,
|
||||
Private: private,
|
||||
},
|
||||
}
|
||||
Type string `json:"keytype"`
|
||||
Value KeyPair `json:"keyval"`
|
||||
}
|
||||
|
||||
// Algorithm returns the algorithm of the key
|
||||
func (k TUFKey) Algorithm() KeyAlgorithm {
|
||||
func (k tufKey) Algorithm() string {
|
||||
return k.Type
|
||||
}
|
||||
|
||||
// ID efficiently generates if necessary, and caches the ID of the key
|
||||
func (k *TUFKey) ID() string {
|
||||
func (k *tufKey) ID() string {
|
||||
if k.id == "" {
|
||||
pubK := NewPublicKey(k.Algorithm(), k.Public())
|
||||
pubK := tufKey{
|
||||
Type: k.Algorithm(),
|
||||
Value: KeyPair{
|
||||
Public: k.Public(),
|
||||
Private: nil,
|
||||
},
|
||||
}
|
||||
data, err := json.MarshalCanonical(&pubK)
|
||||
if err != nil {
|
||||
logrus.Error("Error generating key ID:", err)
|
||||
|
@ -77,35 +198,198 @@ func (k *TUFKey) ID() string {
|
|||
}
|
||||
|
||||
// Public returns the public bytes
|
||||
func (k TUFKey) Public() []byte {
|
||||
func (k tufKey) Public() []byte {
|
||||
return k.Value.Public
|
||||
}
|
||||
|
||||
// Private returns the private bytes
|
||||
func (k TUFKey) Private() []byte {
|
||||
return k.Value.Private
|
||||
// Public key types
|
||||
|
||||
type ECDSAPublicKey struct {
|
||||
tufKey
|
||||
}
|
||||
|
||||
// NewPublicKey instantiates a new TUFKey where the private bytes are
|
||||
// guaranteed to be nil
|
||||
func NewPublicKey(algorithm KeyAlgorithm, public []byte) PublicKey {
|
||||
return &TUFKey{
|
||||
Type: algorithm,
|
||||
Value: KeyPair{
|
||||
Public: public,
|
||||
Private: nil,
|
||||
type ECDSAx509PublicKey struct {
|
||||
tufKey
|
||||
}
|
||||
|
||||
type RSAPublicKey struct {
|
||||
tufKey
|
||||
}
|
||||
|
||||
type RSAx509PublicKey struct {
|
||||
tufKey
|
||||
}
|
||||
|
||||
type ED25519PublicKey struct {
|
||||
tufKey
|
||||
}
|
||||
|
||||
type UnknownPublicKey struct {
|
||||
tufKey
|
||||
}
|
||||
|
||||
func NewECDSAPublicKey(public []byte) *ECDSAPublicKey {
|
||||
return &ECDSAPublicKey{
|
||||
tufKey: tufKey{
|
||||
Type: ECDSAKey,
|
||||
Value: KeyPair{
|
||||
Public: public,
|
||||
Private: nil,
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// PublicKeyFromPrivate returns a new TUFKey based on a private key, with
|
||||
func NewECDSAx509PublicKey(public []byte) *ECDSAx509PublicKey {
|
||||
return &ECDSAx509PublicKey{
|
||||
tufKey: tufKey{
|
||||
Type: ECDSAx509Key,
|
||||
Value: KeyPair{
|
||||
Public: public,
|
||||
Private: nil,
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func NewRSAPublicKey(public []byte) *RSAPublicKey {
|
||||
return &RSAPublicKey{
|
||||
tufKey: tufKey{
|
||||
Type: RSAKey,
|
||||
Value: KeyPair{
|
||||
Public: public,
|
||||
Private: nil,
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func NewRSAx509PublicKey(public []byte) *RSAx509PublicKey {
|
||||
return &RSAx509PublicKey{
|
||||
tufKey: tufKey{
|
||||
Type: RSAx509Key,
|
||||
Value: KeyPair{
|
||||
Public: public,
|
||||
Private: nil,
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func NewED25519PublicKey(public []byte) *ED25519PublicKey {
|
||||
return &ED25519PublicKey{
|
||||
tufKey: tufKey{
|
||||
Type: ED25519Key,
|
||||
Value: KeyPair{
|
||||
Public: public,
|
||||
Private: nil,
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// Private key types
|
||||
|
||||
// ECDSAPrivateKey
|
||||
type ECDSAPrivateKey struct {
|
||||
ECDSAPublicKey
|
||||
private []byte `json:"-"`
|
||||
}
|
||||
|
||||
type ECDSAx509PrivateKey struct {
|
||||
ECDSAx509PublicKey
|
||||
private []byte `json:"-"`
|
||||
}
|
||||
|
||||
type RSAPrivateKey struct {
|
||||
RSAPublicKey
|
||||
private []byte `json:"-"`
|
||||
}
|
||||
|
||||
type RSAx509PrivateKey struct {
|
||||
RSAx509PublicKey
|
||||
private []byte `json:"-"`
|
||||
}
|
||||
|
||||
type ED25519PrivateKey struct {
|
||||
ED25519PublicKey
|
||||
private []byte `json:"-"`
|
||||
}
|
||||
|
||||
type UnknownPrivateKey struct {
|
||||
tufKey
|
||||
private []byte `json:"-"`
|
||||
}
|
||||
|
||||
func NewECDSAPrivateKey(public ECDSAPublicKey, private []byte) *ECDSAPrivateKey {
|
||||
return &ECDSAPrivateKey{
|
||||
ECDSAPublicKey: public,
|
||||
private: private,
|
||||
}
|
||||
}
|
||||
|
||||
func NewECDSAx509PrivateKey(public ECDSAx509PublicKey, private []byte) *ECDSAx509PrivateKey {
|
||||
return &ECDSAx509PrivateKey{
|
||||
ECDSAx509PublicKey: public,
|
||||
private: private,
|
||||
}
|
||||
}
|
||||
|
||||
func NewRSAPrivateKey(public RSAPublicKey, private []byte) *RSAPrivateKey {
|
||||
return &RSAPrivateKey{
|
||||
RSAPublicKey: public,
|
||||
private: private,
|
||||
}
|
||||
}
|
||||
|
||||
func NewRSAx509PrivateKey(public RSAx509PublicKey, private []byte) *RSAx509PrivateKey {
|
||||
return &RSAx509PrivateKey{
|
||||
RSAx509PublicKey: public,
|
||||
private: private,
|
||||
}
|
||||
}
|
||||
|
||||
func NewED25519PrivateKey(public ED25519PublicKey, private []byte) *ED25519PrivateKey {
|
||||
return &ED25519PrivateKey{
|
||||
ED25519PublicKey: public,
|
||||
private: private,
|
||||
}
|
||||
}
|
||||
|
||||
func (k ECDSAPrivateKey) Private() []byte {
|
||||
return k.private
|
||||
}
|
||||
|
||||
func (k ECDSAx509PrivateKey) Private() []byte {
|
||||
return k.private
|
||||
}
|
||||
|
||||
func (k RSAPrivateKey) Private() []byte {
|
||||
return k.private
|
||||
}
|
||||
|
||||
func (k RSAx509PrivateKey) Private() []byte {
|
||||
return k.private
|
||||
}
|
||||
|
||||
func (k ED25519PrivateKey) Private() []byte {
|
||||
return k.private
|
||||
}
|
||||
|
||||
func (k UnknownPrivateKey) Private() []byte {
|
||||
return k.private
|
||||
}
|
||||
|
||||
// PublicKeyFromPrivate returns a new tufKey based on a private key, with
|
||||
// the private key bytes guaranteed to be nil.
|
||||
func PublicKeyFromPrivate(pk PrivateKey) PublicKey {
|
||||
return &TUFKey{
|
||||
return typedPublicKey(tufKey{
|
||||
Type: pk.Algorithm(),
|
||||
Value: KeyPair{
|
||||
Public: pk.Public(),
|
||||
Private: nil,
|
||||
},
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
type ed25519PrivateKey []byte
|
||||
|
|
|
@ -15,12 +15,10 @@ type SignedRoot struct {
|
|||
|
||||
// Root is the Signed component of a root.json
|
||||
type Root struct {
|
||||
Type string `json:"_type"`
|
||||
Version int `json:"version"`
|
||||
Expires time.Time `json:"expires"`
|
||||
// These keys are public keys. We use TUFKey instead of PublicKey to
|
||||
// support direct JSON unmarshaling.
|
||||
Keys map[string]*TUFKey `json:"keys"`
|
||||
Type string `json:"_type"`
|
||||
Version int `json:"version"`
|
||||
Expires time.Time `json:"expires"`
|
||||
Keys Keys `json:"keys"`
|
||||
Roles map[string]*RootRole `json:"roles"`
|
||||
ConsistentSnapshot bool `json:"consistent_snapshot"`
|
||||
}
|
||||
|
@ -33,29 +31,13 @@ func NewRoot(keys map[string]PublicKey, roles map[string]*RootRole, consistent b
|
|||
Type: TUFTypes["root"],
|
||||
Version: 0,
|
||||
Expires: DefaultExpires("root"),
|
||||
Keys: make(map[string]*TUFKey),
|
||||
Keys: keys,
|
||||
Roles: roles,
|
||||
ConsistentSnapshot: consistent,
|
||||
},
|
||||
Dirty: true,
|
||||
}
|
||||
|
||||
// Convert PublicKeys to TUFKey structures
|
||||
// The Signed.Keys map needs to have *TUFKey values, since this
|
||||
// structure gets directly unmarshalled from JSON, and it's not
|
||||
// possible to unmarshal into an interface type. But this function
|
||||
// takes a map with PublicKey values to avoid exposing this ugliness.
|
||||
// The loop below converts to the TUFKey type.
|
||||
for k, v := range keys {
|
||||
signedRoot.Signed.Keys[k] = &TUFKey{
|
||||
Type: v.Algorithm(),
|
||||
Value: KeyPair{
|
||||
Public: v.Public(),
|
||||
Private: nil,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
return signedRoot, nil
|
||||
}
|
||||
|
||||
|
|
|
@ -14,13 +14,6 @@ import (
|
|||
"github.com/jfrazelle/go/canonical/json"
|
||||
)
|
||||
|
||||
// KeyAlgorithm for types of keys
|
||||
type KeyAlgorithm string
|
||||
|
||||
func (k KeyAlgorithm) String() string {
|
||||
return string(k)
|
||||
}
|
||||
|
||||
// SigAlgorithm for types of signatures
|
||||
type SigAlgorithm string
|
||||
|
||||
|
@ -41,11 +34,11 @@ const (
|
|||
|
||||
// Key types
|
||||
const (
|
||||
ED25519Key KeyAlgorithm = "ed25519"
|
||||
RSAKey KeyAlgorithm = "rsa"
|
||||
RSAx509Key KeyAlgorithm = "rsa-x509"
|
||||
ECDSAKey KeyAlgorithm = "ecdsa"
|
||||
ECDSAx509Key KeyAlgorithm = "ecdsa-x509"
|
||||
ED25519Key = "ed25519"
|
||||
RSAKey = "rsa"
|
||||
RSAx509Key = "rsa-x509"
|
||||
ECDSAKey = "ecdsa"
|
||||
ECDSAx509Key = "ecdsa-x509"
|
||||
)
|
||||
|
||||
// TUFTypes is the set of metadata types
|
||||
|
@ -167,8 +160,8 @@ func NewFileMeta(r io.Reader, hashAlgorithms ...string) (FileMeta, error) {
|
|||
|
||||
// Delegations holds a tier of targets delegations
|
||||
type Delegations struct {
|
||||
Keys map[string]PublicKey `json:"keys"`
|
||||
Roles []*Role `json:"roles"`
|
||||
Keys Keys `json:"keys"`
|
||||
Roles []*Role `json:"roles"`
|
||||
}
|
||||
|
||||
// NewDelegations initializes an empty Delegations object
|
||||
|
|
|
@ -50,7 +50,7 @@ func (e *Ed25519) Sign(keyIDs []string, toSign []byte) ([]data.Signature, error)
|
|||
}
|
||||
|
||||
// Create generates a new key and returns the public part
|
||||
func (e *Ed25519) Create(role string, algorithm data.KeyAlgorithm) (data.PublicKey, error) {
|
||||
func (e *Ed25519) Create(role string, algorithm string) (data.PublicKey, error) {
|
||||
if algorithm != data.ED25519Key {
|
||||
return nil, errors.New("only ED25519 supported by this cryptoservice")
|
||||
}
|
||||
|
@ -59,8 +59,8 @@ func (e *Ed25519) Create(role string, algorithm data.KeyAlgorithm) (data.PublicK
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
public := data.NewPublicKey(data.ED25519Key, pub[:])
|
||||
private := data.NewPrivateKey(data.ED25519Key, pub[:], priv[:])
|
||||
public := data.NewED25519PublicKey(pub[:])
|
||||
private := data.NewED25519PrivateKey(*public, priv[:])
|
||||
e.addKey(private)
|
||||
return public, nil
|
||||
}
|
||||
|
|
|
@ -20,7 +20,7 @@ type KeyService interface {
|
|||
// the private key into the appropriate signing service.
|
||||
// The role isn't currently used for anything, but it's here to support
|
||||
// future features
|
||||
Create(role string, algorithm data.KeyAlgorithm) (data.PublicKey, error)
|
||||
Create(role string, algorithm string) (data.PublicKey, error)
|
||||
|
||||
// GetKey retrieves the public key if present, otherwise it returns nil
|
||||
GetKey(keyID string) data.PublicKey
|
||||
|
|
|
@ -29,7 +29,7 @@ func (mts *FailingCryptoService) Sign(keyIDs []string, _ []byte) ([]data.Signatu
|
|||
return sigs, nil
|
||||
}
|
||||
|
||||
func (mts *FailingCryptoService) Create(_ string, _ data.KeyAlgorithm) (data.PublicKey, error) {
|
||||
func (mts *FailingCryptoService) Create(_ string, _ string) (data.PublicKey, error) {
|
||||
return mts.testKey, nil
|
||||
}
|
||||
|
||||
|
@ -56,7 +56,7 @@ func (mts *MockCryptoService) Sign(keyIDs []string, _ []byte) ([]data.Signature,
|
|||
return sigs, nil
|
||||
}
|
||||
|
||||
func (mts *MockCryptoService) Create(_ string, _ data.KeyAlgorithm) (data.PublicKey, error) {
|
||||
func (mts *MockCryptoService) Create(_ string, _ string) (data.PublicKey, error) {
|
||||
return mts.testKey, nil
|
||||
}
|
||||
|
||||
|
|
|
@ -10,7 +10,6 @@ import (
|
|||
"crypto/sha256"
|
||||
"crypto/x509"
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"testing"
|
||||
"text/template"
|
||||
|
@ -20,7 +19,7 @@ import (
|
|||
)
|
||||
|
||||
type KeyTemplate struct {
|
||||
KeyType data.KeyAlgorithm
|
||||
KeyType string
|
||||
}
|
||||
|
||||
const baseRSAKey = `{"keytype":"{{.KeyType}}","keyval":{"public":"MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyyvBtTg2xzYS+MTTIBqSpI4V78tt8Yzqi7Jki/Z6NqjiDvcnbgcTqNR2t6B2W5NjGdp/hSaT2jyHM+kdmEGaPxg/zIuHbL3NIp4e0qwovWiEgACPIaELdn8O/kt5swsSKl1KMvLCH1sM86qMibNMAZ/hXOwd90TcHXCgZ91wHEAmsdjDC3dB0TT+FBgOac8RM01Y196QrZoOaDMTWh0EQfw7YbXAElhFVDFxBzDdYWbcIHSIogXQmq0CP+zaL/1WgcZZIClt2M6WCaxxF1S34wNn45gCvVZiZQ/iKWHerSr/2dGQeGo+7ezMSutRzvJ+01fInD86RS/CEtBCFZ1VyQIDAQAB","private":"MIIEpAIBAAKCAQEAyyvBtTg2xzYS+MTTIBqSpI4V78tt8Yzqi7Jki/Z6NqjiDvcnbgcTqNR2t6B2W5NjGdp/hSaT2jyHM+kdmEGaPxg/zIuHbL3NIp4e0qwovWiEgACPIaELdn8O/kt5swsSKl1KMvLCH1sM86qMibNMAZ/hXOwd90TcHXCgZ91wHEAmsdjDC3dB0TT+FBgOac8RM01Y196QrZoOaDMTWh0EQfw7YbXAElhFVDFxBzDdYWbcIHSIogXQmq0CP+zaL/1WgcZZIClt2M6WCaxxF1S34wNn45gCvVZiZQ/iKWHerSr/2dGQeGo+7ezMSutRzvJ+01fInD86RS/CEtBCFZ1VyQIDAQABAoIBAHar8FFxrE1gAGTeUpOF8fG8LIQMRwO4U6eVY7V9GpWiv6gOJTHXYFxU/aL0Ty3eQRxwy9tyVRo8EJz5pRex+e6ws1M+jLOviYqW4VocxQ8dZYd+zBvQfWmRfah7XXJ/HPUx2I05zrmR7VbGX6Bu4g5w3KnyIO61gfyQNKF2bm2Q3yblfupx3URvX0bl180R/+QN2Aslr4zxULFE6b+qJqBydrztq+AAP3WmskRxGa6irFnKxkspJqUpQN1mFselj6iQrzAcwkRPoCw0RwCCMq1/OOYvQtgxTJcO4zDVlbw54PvnxPZtcCWw7fO8oZ2Fvo2SDo75CDOATOGaT4Y9iqECgYEAzWZSpFbN9ZHmvq1lJQg//jFAyjsXRNn/nSvyLQILXltz6EHatImnXo3v+SivG91tfzBI1GfDvGUGaJpvKHoomB+qmhd8KIQhO5MBdAKZMf9fZqZofOPTD9xRXECCwdi+XqHBmL+l1OWz+O9Bh+Qobs2as/hQVgHaoXhQpE0NkTcCgYEA/Tjf6JBGl1+WxQDoGZDJrXoejzG9OFW19RjMdmPrg3t4fnbDtqTpZtCzXxPTCSeMrvplKbqAqZglWyq227ksKw4p7O6YfyhdtvC58oJmivlLr6sFaTsER7mDcYce8sQpqm+XQ8IPbnOk0Z1l6g56euTwTnew49uy25M6U1xL0P8CgYEAxEXv2Kw+OVhHV5PX4BBHHj6we88FiDyMfwM8cvfOJ0datekf9X7ImZkmZEAVPJpWBMD+B0J0jzU2b4SLjfFVkzBHVOH2Ob0xCH2MWPAWtekin7OKizUlPbW5ZV8b0+Kq30DQ/4a7D3rEhK8UPqeuX1tHZox1MAqrgbq3zJj4yvcCgYEAktYPKPm4pYCdmgFrlZ+bA0iEPf7Wvbsd91F5BtHsOOM5PQQ7e0bnvWIaEXEad/2CG9lBHlBy2WVLjDEZthILpa/h6e11ao8KwNGY0iKBuebT17rxOVMqqTjPGt8CuD2994IcEgOPFTpkAdUmyvG4XlkxbB8F6St17NPUB5DGuhsCgYA//Lfytk0FflXEeRQ16LT1YXgV7pcR2jsha4+4O5pxSFw/kTsOfJaYHg8StmROoyFnyE3sg76dCgLn0LENRCe5BvDhJnp5bMpQldG3XwcAxH8FGFNY4LtV/2ZKnJhxcONkfmzQPOmTyedOzrKQ+bNURsqLukCypP7/by6afBY4dA=="}}`
|
||||
|
@ -31,38 +30,40 @@ const baseECDSAx509Key = `{"keytype":"ecdsa-x509","keyval":{"public":"LS0tLS1CRU
|
|||
|
||||
func TestRSAPSSVerifier(t *testing.T) {
|
||||
// Unmarshal our private RSA Key
|
||||
var testRSAKey data.TUFKey
|
||||
var testRSAKey data.PrivateKey
|
||||
var jsonKey bytes.Buffer
|
||||
|
||||
// Execute our template
|
||||
templ, _ := template.New("KeyTemplate").Parse(baseRSAKey)
|
||||
templ.Execute(&jsonKey, KeyTemplate{KeyType: data.RSAKey})
|
||||
|
||||
json.Unmarshal(jsonKey.Bytes(), &testRSAKey)
|
||||
testRSAKey, err := data.UnmarshalPrivateKey(jsonKey.Bytes())
|
||||
assert.NoError(t, err)
|
||||
|
||||
// Sign some data using RSAPSS
|
||||
message := []byte("test data for signing")
|
||||
hash := crypto.SHA256
|
||||
hashed := sha256.Sum256(message)
|
||||
signedData, err := rsaPSSSign(&testRSAKey, hash, hashed[:])
|
||||
signedData, err := rsaPSSSign(testRSAKey, hash, hashed[:])
|
||||
assert.NoError(t, err)
|
||||
|
||||
// Create and call Verify on the verifier
|
||||
rsaVerifier := RSAPSSVerifier{}
|
||||
err = rsaVerifier.Verify(&testRSAKey, signedData, message)
|
||||
err = rsaVerifier.Verify(testRSAKey, signedData, message)
|
||||
assert.NoError(t, err, "expecting success but got error while verifying data using RSA PSS")
|
||||
}
|
||||
|
||||
func TestRSAPSSx509Verifier(t *testing.T) {
|
||||
// Unmarshal our public RSA Key
|
||||
var testRSAKey data.TUFKey
|
||||
var testRSAKey data.PrivateKey
|
||||
var jsonKey bytes.Buffer
|
||||
|
||||
// Execute our template
|
||||
templ, _ := template.New("KeyTemplate").Parse(baseRSAx509Key)
|
||||
templ.Execute(&jsonKey, KeyTemplate{KeyType: data.RSAx509Key})
|
||||
|
||||
json.Unmarshal(jsonKey.Bytes(), &testRSAKey)
|
||||
testRSAKey, err := data.UnmarshalPrivateKey(jsonKey.Bytes())
|
||||
assert.NoError(t, err)
|
||||
|
||||
// Valid signed message
|
||||
signedData, _ := hex.DecodeString("3de02fa54cdba45c67860f058b7cff1ba264610dc3c5b466b7df027bc52068bdf2956fe438dba08b0b71daa0780a3037bf8f50a09d91ca81fa872bbdbbbff6ef17e04df8741ad5c2f2c3ea5de97d6ffaf4999c83fdfba4b6cb2443da11c7b7eea84123c2fdaf3319fa6342cbbdbd1aa25d1ac20aeee687e48cbf191cc8f68049230261469eeada33dec0af74287766bd984dd01820a7edfb8b0d030e2fcf00886c578b07eb905a2eebc81fd982a578e717c7ac773cab345950c71e1eaf81b70401e5bf3c67cdcb9068bf4b50ff0456b530b3cec5586827eb39b123f9d666a65f4b418a355438ed1753da8a27577ab9cd791d7b840c7e34ecc1290c46d98aa0dd73c0427f6ef8f63e36af42e9657520b8f56c9231ba7e0172dfc3456c63c54e9eae95d06bafe571e91afa1e42d4010e60dd5c441df112cc8474253eee7f1d6c5350039ffcd1f8b0bb013e4403c16fc5b40d6bd56b742ea1ed82c87880147db194b33b022077cc2e8d31ef3eada3e46683ad437ad8ef7ecbe03c29d7a53a9771e42cc4f9d782813c491186fde2cd1dfa408c4e21dd4c3ca1664e901772ffe1713e37b07c9287572114865a05e17cbe29d8622c6b033dcb43c9721d0943c58098607cc28bd58b3caf3dfc1f66d01ebfaf1aa5c2c5945c23af83fe114e587fa7bcbaea6bdccff3c0ad03ce3328f67af30168e225e5827ad9e94b4702de984e6dd775")
|
||||
|
@ -70,19 +71,20 @@ func TestRSAPSSx509Verifier(t *testing.T) {
|
|||
|
||||
// Create and call Verify on the verifier
|
||||
rsaVerifier := RSAPSSVerifier{}
|
||||
err := rsaVerifier.Verify(&testRSAKey, signedData, message)
|
||||
err = rsaVerifier.Verify(testRSAKey, signedData, message)
|
||||
assert.NoError(t, err, "expecting success but got error while verifying data using RSAPSS and an X509 encoded Key")
|
||||
}
|
||||
|
||||
func TestRSAPSSVerifierWithInvalidKeyType(t *testing.T) {
|
||||
var testRSAKey data.TUFKey
|
||||
var testRSAKey data.PrivateKey
|
||||
var jsonKey bytes.Buffer
|
||||
|
||||
// Execute our template
|
||||
templ, _ := template.New("KeyTemplate").Parse(baseRSAKey)
|
||||
templ.Execute(&jsonKey, KeyTemplate{KeyType: "rsa-invalid"})
|
||||
|
||||
json.Unmarshal(jsonKey.Bytes(), &testRSAKey)
|
||||
testRSAKey, err := data.UnmarshalPrivateKey(jsonKey.Bytes())
|
||||
assert.NoError(t, err)
|
||||
|
||||
// Valid signed data with invalidRsaKeyJSON
|
||||
signedData, _ := hex.DecodeString("2741a57a5ef89f841b4e0a6afbcd7940bc982cd919fbd11dfc21b5ccfe13855b9c401e3df22da5480cef2fa585d0f6dfc6c35592ed92a2a18001362c3a17f74da3906684f9d81c5846bf6a09e2ede6c009ae164f504e6184e666adb14eadf5f6e12e07ff9af9ad49bf1ea9bcfa3bebb2e33be7d4c0fabfe39534f98f1e3c4bff44f637cff3dae8288aea54d86476a3f1320adc39008eae24b991c1de20744a7967d2e685ac0bcc0bc725947f01c9192ffd3e9300eba4b7faa826e84478493fdf97c705dd331dd46072050d6c5e317c2d63df21694dbaf909ebf46ce0ff04f3979fe13723ae1a823c65f27e56efa19e88f9e7b8ee56eac34353b944067deded3a")
|
||||
|
@ -90,7 +92,7 @@ func TestRSAPSSVerifierWithInvalidKeyType(t *testing.T) {
|
|||
|
||||
// Create and call Verify on the verifier
|
||||
rsaVerifier := RSAPSSVerifier{}
|
||||
err := rsaVerifier.Verify(&testRSAKey, signedData, message)
|
||||
err = rsaVerifier.Verify(testRSAKey, signedData, message)
|
||||
assert.Error(t, err, "invalid key type for RSAPSS verifier: rsa-invalid")
|
||||
}
|
||||
|
||||
|
@ -104,14 +106,15 @@ func TestRSAPSSVerifierWithInvalidKeyLength(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestRSAPSSVerifierWithInvalidKey(t *testing.T) {
|
||||
var testRSAKey data.TUFKey
|
||||
var testRSAKey data.PrivateKey
|
||||
var jsonKey bytes.Buffer
|
||||
|
||||
// Execute our template
|
||||
templ, _ := template.New("KeyTemplate").Parse(baseECDSAKey)
|
||||
templ.Execute(&jsonKey, KeyTemplate{KeyType: "ecdsa"})
|
||||
|
||||
json.Unmarshal(jsonKey.Bytes(), &testRSAKey)
|
||||
testRSAKey, err := data.UnmarshalPrivateKey(jsonKey.Bytes())
|
||||
assert.NoError(t, err)
|
||||
|
||||
// Valid signed data with invalidRsaKeyJSON
|
||||
signedData, _ := hex.DecodeString("2741a57a5ef89f841b4e0a6afbcd7940bc982cd919fbd11dfc21b5ccfe13855b9c401e3df22da5480cef2fa585d0f6dfc6c35592ed92a2a18001362c3a17f74da3906684f9d81c5846bf6a09e2ede6c009ae164f504e6184e666adb14eadf5f6e12e07ff9af9ad49bf1ea9bcfa3bebb2e33be7d4c0fabfe39534f98f1e3c4bff44f637cff3dae8288aea54d86476a3f1320adc39008eae24b991c1de20744a7967d2e685ac0bcc0bc725947f01c9192ffd3e9300eba4b7faa826e84478493fdf97c705dd331dd46072050d6c5e317c2d63df21694dbaf909ebf46ce0ff04f3979fe13723ae1a823c65f27e56efa19e88f9e7b8ee56eac34353b944067deded3a")
|
||||
|
@ -119,25 +122,26 @@ func TestRSAPSSVerifierWithInvalidKey(t *testing.T) {
|
|||
|
||||
// Create and call Verify on the verifier
|
||||
rsaVerifier := RSAPSSVerifier{}
|
||||
err := rsaVerifier.Verify(&testRSAKey, signedData, message)
|
||||
err = rsaVerifier.Verify(testRSAKey, signedData, message)
|
||||
assert.Error(t, err, "invalid key type for RSAPSS verifier: ecdsa")
|
||||
}
|
||||
|
||||
func TestRSAPSSVerifierWithInvalidSignature(t *testing.T) {
|
||||
var testRSAKey data.TUFKey
|
||||
var testRSAKey data.PrivateKey
|
||||
var jsonKey bytes.Buffer
|
||||
|
||||
// Execute our template
|
||||
templ, _ := template.New("KeyTemplate").Parse(baseRSAKey)
|
||||
templ.Execute(&jsonKey, KeyTemplate{KeyType: data.RSAKey})
|
||||
|
||||
json.Unmarshal(jsonKey.Bytes(), &testRSAKey)
|
||||
testRSAKey, err := data.UnmarshalPrivateKey(jsonKey.Bytes())
|
||||
assert.NoError(t, err)
|
||||
|
||||
// Sign some data using RSAPSS
|
||||
message := []byte("test data for signing")
|
||||
hash := crypto.SHA256
|
||||
hashed := sha256.Sum256(message)
|
||||
signedData, err := rsaPSSSign(&testRSAKey, hash, hashed[:])
|
||||
signedData, err := rsaPSSSign(testRSAKey, hash, hashed[:])
|
||||
assert.NoError(t, err)
|
||||
|
||||
// Modify the signature
|
||||
|
@ -145,44 +149,46 @@ func TestRSAPSSVerifierWithInvalidSignature(t *testing.T) {
|
|||
|
||||
// Create and call Verify on the verifier
|
||||
rsaVerifier := RSAPSSVerifier{}
|
||||
err = rsaVerifier.Verify(&testRSAKey, signedData, message)
|
||||
err = rsaVerifier.Verify(testRSAKey, signedData, message)
|
||||
assert.Error(t, err, "signature verification failed")
|
||||
}
|
||||
|
||||
func TestRSAPKCS1v15Verifier(t *testing.T) {
|
||||
// Unmarshal our private RSA Key
|
||||
var testRSAKey data.TUFKey
|
||||
var testRSAKey data.PrivateKey
|
||||
var jsonKey bytes.Buffer
|
||||
|
||||
// Execute our template
|
||||
templ, _ := template.New("KeyTemplate").Parse(baseRSAKey)
|
||||
templ.Execute(&jsonKey, KeyTemplate{KeyType: data.RSAKey})
|
||||
|
||||
json.Unmarshal(jsonKey.Bytes(), &testRSAKey)
|
||||
testRSAKey, err := data.UnmarshalPrivateKey(jsonKey.Bytes())
|
||||
assert.NoError(t, err)
|
||||
|
||||
// Sign some data using RSAPKCS1v15
|
||||
message := []byte("test data for signing")
|
||||
hash := crypto.SHA256
|
||||
hashed := sha256.Sum256(message)
|
||||
signedData, err := rsaPKCS1v15Sign(&testRSAKey, hash, hashed[:])
|
||||
signedData, err := rsaPKCS1v15Sign(testRSAKey, hash, hashed[:])
|
||||
assert.NoError(t, err)
|
||||
|
||||
// Create and call Verify on the verifier
|
||||
rsaVerifier := RSAPKCS1v15Verifier{}
|
||||
err = rsaVerifier.Verify(&testRSAKey, signedData, message)
|
||||
err = rsaVerifier.Verify(testRSAKey, signedData, message)
|
||||
assert.NoError(t, err, "expecting success but got error while verifying data using RSAPKCS1v15")
|
||||
}
|
||||
|
||||
func TestRSAPKCS1v15x509Verifier(t *testing.T) {
|
||||
// Unmarshal our public RSA Key
|
||||
var testRSAKey data.TUFKey
|
||||
var testRSAKey data.PrivateKey
|
||||
var jsonKey bytes.Buffer
|
||||
|
||||
// Execute our template
|
||||
templ, _ := template.New("KeyTemplate").Parse(baseRSAx509Key)
|
||||
templ.Execute(&jsonKey, KeyTemplate{KeyType: data.RSAx509Key})
|
||||
|
||||
json.Unmarshal(jsonKey.Bytes(), &testRSAKey)
|
||||
testRSAKey, err := data.UnmarshalPrivateKey(jsonKey.Bytes())
|
||||
assert.NoError(t, err)
|
||||
|
||||
// Valid signed message
|
||||
signedData, _ := hex.DecodeString("a19602f609646d57f3d0db930bbe491a997baf33f13191916713734ae778ddb4898ece2078741bb0c24d726514c6b4538c3665c374b0b8ec9ff234b45459633268224c9962756ad3684aca5f13a286657375e798ddcb857ed2707c900f097666b958df56b43b790357430c2e7a5c379ba9972c8b008363c144aac5c7e0fbfad83cf6855cf73baf8e3ad774e910ba6ac8dc4cce58fe19cffb7b0a1feaa73d23ebd2d59de2d7d9e98a809d73a310c5396df64ff7a22d735e661e39d37a6c4a013caa6005e91f597ea35db24e6c750d704d292a180128dcf72a818c53a96b0a83ba0414a3611097905262eb79a6ced1484af27c7da6809aa21ae7c6f05ae6568d5e5d9c170470213a30caf2340c3d52e7bd4056d22074daffee6e29d0a6fd3ca6dbd001831fb1e48573f3663b63e110cde19efaf56e49a835aeda82e4d7286de591376ecd03de36d402ec703f39f79b2f764f991d8950a119f2618f6d4e4618114900597a1e89ced609949410623a17b97095afe08babc4c295ade954f055ca01b7909f5585e98eb99bd916583476aa877d20da8f4fe35c0867e934f41c935d469664b80904a93f9f4d9432cabd9383e08559d6452f8e12b2d861412c450709ff874ad63c25a640605a41c4073f0eb4e16e1965abf8e088e210cbf9d3ca884ec2c13fc8a288cfcef2425d9607fcab01dab45c5c346671a9ae1d0e52c81379fa212c")
|
||||
|
@ -190,19 +196,20 @@ func TestRSAPKCS1v15x509Verifier(t *testing.T) {
|
|||
|
||||
// Create and call Verify on the verifier
|
||||
rsaVerifier := RSAPKCS1v15Verifier{}
|
||||
err := rsaVerifier.Verify(&testRSAKey, signedData, message)
|
||||
err = rsaVerifier.Verify(testRSAKey, signedData, message)
|
||||
assert.NoError(t, err, "expecting success but got error while verifying data using RSAPKCS1v15 and an X509 encoded Key")
|
||||
}
|
||||
|
||||
func TestRSAPKCS1v15VerifierWithInvalidKeyType(t *testing.T) {
|
||||
var testRSAKey data.TUFKey
|
||||
var testRSAKey data.PrivateKey
|
||||
var jsonKey bytes.Buffer
|
||||
|
||||
// Execute our template
|
||||
templ, _ := template.New("KeyTemplate").Parse(baseRSAKey)
|
||||
templ.Execute(&jsonKey, KeyTemplate{KeyType: "rsa-invalid"})
|
||||
|
||||
json.Unmarshal(jsonKey.Bytes(), &testRSAKey)
|
||||
testRSAKey, err := data.UnmarshalPrivateKey(jsonKey.Bytes())
|
||||
assert.NoError(t, err)
|
||||
|
||||
// Valid signed data with invalidRsaKeyJSON
|
||||
signedData, _ := hex.DecodeString("2741a57a5ef89f841b4e0a6afbcd7940bc982cd919fbd11dfc21b5ccfe13855b9c401e3df22da5480cef2fa585d0f6dfc6c35592ed92a2a18001362c3a17f74da3906684f9d81c5846bf6a09e2ede6c009ae164f504e6184e666adb14eadf5f6e12e07ff9af9ad49bf1ea9bcfa3bebb2e33be7d4c0fabfe39534f98f1e3c4bff44f637cff3dae8288aea54d86476a3f1320adc39008eae24b991c1de20744a7967d2e685ac0bcc0bc725947f01c9192ffd3e9300eba4b7faa826e84478493fdf97c705dd331dd46072050d6c5e317c2d63df21694dbaf909ebf46ce0ff04f3979fe13723ae1a823c65f27e56efa19e88f9e7b8ee56eac34353b944067deded3a")
|
||||
|
@ -210,19 +217,20 @@ func TestRSAPKCS1v15VerifierWithInvalidKeyType(t *testing.T) {
|
|||
|
||||
// Create and call Verify on the verifier
|
||||
rsaVerifier := RSAPKCS1v15Verifier{}
|
||||
err := rsaVerifier.Verify(&testRSAKey, signedData, message)
|
||||
err = rsaVerifier.Verify(testRSAKey, signedData, message)
|
||||
assert.Error(t, err, "invalid key type for RSAPKCS1v15 verifier: rsa-invalid")
|
||||
}
|
||||
|
||||
func TestRSAPKCS1v15VerifierWithInvalidKey(t *testing.T) {
|
||||
var testRSAKey data.TUFKey
|
||||
var testRSAKey data.PrivateKey
|
||||
var jsonKey bytes.Buffer
|
||||
|
||||
// Execute our template
|
||||
templ, _ := template.New("KeyTemplate").Parse(baseECDSAKey)
|
||||
templ.Execute(&jsonKey, KeyTemplate{KeyType: "ecdsa"})
|
||||
|
||||
json.Unmarshal(jsonKey.Bytes(), &testRSAKey)
|
||||
testRSAKey, err := data.UnmarshalPrivateKey(jsonKey.Bytes())
|
||||
assert.NoError(t, err)
|
||||
|
||||
// Valid signed data with invalidRsaKeyJSON
|
||||
signedData, _ := hex.DecodeString("2741a57a5ef89f841b4e0a6afbcd7940bc982cd919fbd11dfc21b5ccfe13855b9c401e3df22da5480cef2fa585d0f6dfc6c35592ed92a2a18001362c3a17f74da3906684f9d81c5846bf6a09e2ede6c009ae164f504e6184e666adb14eadf5f6e12e07ff9af9ad49bf1ea9bcfa3bebb2e33be7d4c0fabfe39534f98f1e3c4bff44f637cff3dae8288aea54d86476a3f1320adc39008eae24b991c1de20744a7967d2e685ac0bcc0bc725947f01c9192ffd3e9300eba4b7faa826e84478493fdf97c705dd331dd46072050d6c5e317c2d63df21694dbaf909ebf46ce0ff04f3979fe13723ae1a823c65f27e56efa19e88f9e7b8ee56eac34353b944067deded3a")
|
||||
|
@ -230,25 +238,26 @@ func TestRSAPKCS1v15VerifierWithInvalidKey(t *testing.T) {
|
|||
|
||||
// Create and call Verify on the verifier
|
||||
rsaVerifier := RSAPKCS1v15Verifier{}
|
||||
err := rsaVerifier.Verify(&testRSAKey, signedData, message)
|
||||
err = rsaVerifier.Verify(testRSAKey, signedData, message)
|
||||
assert.Error(t, err, "invalid key type for RSAPKCS1v15 verifier: ecdsa")
|
||||
}
|
||||
|
||||
func TestRSAPKCS1v15VerifierWithInvalidSignature(t *testing.T) {
|
||||
var testRSAKey data.TUFKey
|
||||
var testRSAKey data.PrivateKey
|
||||
var jsonKey bytes.Buffer
|
||||
|
||||
// Execute our template
|
||||
templ, _ := template.New("KeyTemplate").Parse(baseRSAKey)
|
||||
templ.Execute(&jsonKey, KeyTemplate{KeyType: data.RSAKey})
|
||||
|
||||
json.Unmarshal(jsonKey.Bytes(), &testRSAKey)
|
||||
testRSAKey, err := data.UnmarshalPrivateKey(jsonKey.Bytes())
|
||||
assert.NoError(t, err)
|
||||
|
||||
// Sign some data using RSAPKCS1v15
|
||||
message := []byte("test data for signing")
|
||||
hash := crypto.SHA256
|
||||
hashed := sha256.Sum256(message)
|
||||
signedData, err := rsaPKCS1v15Sign(&testRSAKey, hash, hashed[:])
|
||||
signedData, err := rsaPKCS1v15Sign(testRSAKey, hash, hashed[:])
|
||||
assert.NoError(t, err)
|
||||
|
||||
// Modify the signature
|
||||
|
@ -256,29 +265,30 @@ func TestRSAPKCS1v15VerifierWithInvalidSignature(t *testing.T) {
|
|||
|
||||
// Create and call Verify on the verifier
|
||||
rsaVerifier := RSAPKCS1v15Verifier{}
|
||||
err = rsaVerifier.Verify(&testRSAKey, signedData, message)
|
||||
err = rsaVerifier.Verify(testRSAKey, signedData, message)
|
||||
assert.Error(t, err, "signature verification failed")
|
||||
}
|
||||
|
||||
func TestECDSAVerifier(t *testing.T) {
|
||||
var testECDSAKey data.TUFKey
|
||||
var testECDSAKey data.PrivateKey
|
||||
var jsonKey bytes.Buffer
|
||||
|
||||
// Execute our template
|
||||
templ, _ := template.New("KeyTemplate").Parse(baseECDSAKey)
|
||||
templ.Execute(&jsonKey, KeyTemplate{KeyType: data.ECDSAKey})
|
||||
|
||||
json.Unmarshal(jsonKey.Bytes(), &testECDSAKey)
|
||||
testECDSAKey, err := data.UnmarshalPrivateKey(jsonKey.Bytes())
|
||||
assert.NoError(t, err)
|
||||
|
||||
// Sign some data using ECDSA
|
||||
message := []byte("test data for signing")
|
||||
hashed := sha256.Sum256(message)
|
||||
signedData, err := ecdsaSign(&testECDSAKey, hashed[:])
|
||||
signedData, err := ecdsaSign(testECDSAKey, hashed[:])
|
||||
assert.NoError(t, err)
|
||||
|
||||
// Create and call Verify on the verifier
|
||||
ecdsaVerifier := ECDSAVerifier{}
|
||||
err = ecdsaVerifier.Verify(&testECDSAKey, signedData, message)
|
||||
err = ecdsaVerifier.Verify(testECDSAKey, signedData, message)
|
||||
assert.NoError(t, err, "expecting success but got error while verifying data using ECDSA")
|
||||
}
|
||||
|
||||
|
@ -296,7 +306,8 @@ func TestECDSAVerifierOtherCurves(t *testing.T) {
|
|||
ecdsaPrivKeyBytes, err := x509.MarshalECPrivateKey(ecdsaPrivKey)
|
||||
assert.NoError(t, err, "failed to marshal private key")
|
||||
|
||||
testECDSAKey := data.NewPrivateKey(data.ECDSAKey, ecdsaPubBytes, ecdsaPrivKeyBytes)
|
||||
testECDSAPubKey := data.NewECDSAPublicKey(ecdsaPubBytes)
|
||||
testECDSAKey := data.NewECDSAPrivateKey(*testECDSAPubKey, ecdsaPrivKeyBytes)
|
||||
|
||||
// Sign some data using ECDSA
|
||||
message := []byte("test data for signing")
|
||||
|
@ -317,14 +328,15 @@ func TestECDSAVerifierOtherCurves(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestECDSAx509Verifier(t *testing.T) {
|
||||
var testECDSAKey data.TUFKey
|
||||
var testECDSAKey data.PrivateKey
|
||||
var jsonKey bytes.Buffer
|
||||
|
||||
// Execute our template
|
||||
templ, _ := template.New("KeyTemplate").Parse(baseECDSAx509Key)
|
||||
templ.Execute(&jsonKey, KeyTemplate{KeyType: data.ECDSAx509Key})
|
||||
|
||||
json.Unmarshal(jsonKey.Bytes(), &testECDSAKey)
|
||||
testECDSAKey, err := data.UnmarshalPrivateKey(jsonKey.Bytes())
|
||||
assert.NoError(t, err)
|
||||
|
||||
// Valid signature for message
|
||||
signedData, _ := hex.DecodeString("b82e0ed5c5dddd74c8d3602bfd900c423511697c3cfe54e1d56b9c1df599695c53aa0caafcdc40df3ef496d78ccf67750ba9413f1ccbd8b0ef137f0da1ee9889")
|
||||
|
@ -332,19 +344,20 @@ func TestECDSAx509Verifier(t *testing.T) {
|
|||
|
||||
// Create and call Verify on the verifier
|
||||
ecdsaVerifier := ECDSAVerifier{}
|
||||
err := ecdsaVerifier.Verify(&testECDSAKey, signedData, message)
|
||||
err = ecdsaVerifier.Verify(testECDSAKey, signedData, message)
|
||||
assert.NoError(t, err, "expecting success but got error while verifying data using ECDSA and an x509 encoded key")
|
||||
}
|
||||
|
||||
func TestECDSAVerifierWithInvalidKeyType(t *testing.T) {
|
||||
var testECDSAKey data.TUFKey
|
||||
var testECDSAKey data.PrivateKey
|
||||
var jsonKey bytes.Buffer
|
||||
|
||||
// Execute our template
|
||||
templ, _ := template.New("KeyTemplate").Parse(baseECDSAKey)
|
||||
templ.Execute(&jsonKey, KeyTemplate{KeyType: "ecdsa-invalid"})
|
||||
|
||||
json.Unmarshal(jsonKey.Bytes(), &testECDSAKey)
|
||||
testECDSAKey, err := data.UnmarshalPrivateKey(jsonKey.Bytes())
|
||||
assert.NoError(t, err)
|
||||
|
||||
// Valid signature using invalidECDSAx509Key
|
||||
signedData, _ := hex.DecodeString("7b1c45a4dd488a087db46ee459192d890d4f52352620cb84c2c10e0ce8a67fd6826936463a91ffdffab8e6f962da6fc3d3e5735412f7cd161a9fcf97ba1a7033")
|
||||
|
@ -352,19 +365,20 @@ func TestECDSAVerifierWithInvalidKeyType(t *testing.T) {
|
|||
|
||||
// Create and call Verify on the verifier
|
||||
ecdsaVerifier := ECDSAVerifier{}
|
||||
err := ecdsaVerifier.Verify(&testECDSAKey, signedData, message)
|
||||
err = ecdsaVerifier.Verify(testECDSAKey, signedData, message)
|
||||
assert.Error(t, err, "invalid key type for ECDSA verifier: ecdsa-invalid")
|
||||
}
|
||||
|
||||
func TestECDSAVerifierWithInvalidKey(t *testing.T) {
|
||||
var testECDSAKey data.TUFKey
|
||||
var testECDSAKey data.PrivateKey
|
||||
var jsonKey bytes.Buffer
|
||||
|
||||
// Execute our template
|
||||
templ, _ := template.New("KeyTemplate").Parse(baseRSAKey)
|
||||
templ.Execute(&jsonKey, KeyTemplate{KeyType: "rsa"})
|
||||
|
||||
json.Unmarshal(jsonKey.Bytes(), &testECDSAKey)
|
||||
testECDSAKey, err := data.UnmarshalPrivateKey(jsonKey.Bytes())
|
||||
assert.NoError(t, err)
|
||||
|
||||
// Valid signature using invalidECDSAx509Key
|
||||
signedData, _ := hex.DecodeString("7b1c45a4dd488a087db46ee459192d890d4f52352620cb84c2c10e0ce8a67fd6826936463a91ffdffab8e6f962da6fc3d3e5735412f7cd161a9fcf97ba1a7033")
|
||||
|
@ -372,24 +386,25 @@ func TestECDSAVerifierWithInvalidKey(t *testing.T) {
|
|||
|
||||
// Create and call Verify on the verifier
|
||||
ecdsaVerifier := ECDSAVerifier{}
|
||||
err := ecdsaVerifier.Verify(&testECDSAKey, signedData, message)
|
||||
err = ecdsaVerifier.Verify(testECDSAKey, signedData, message)
|
||||
assert.Error(t, err, "invalid key type for ECDSA verifier: rsa")
|
||||
}
|
||||
|
||||
func TestECDSAVerifierWithInvalidSignature(t *testing.T) {
|
||||
var testECDSAKey data.TUFKey
|
||||
var testECDSAKey data.PrivateKey
|
||||
var jsonKey bytes.Buffer
|
||||
|
||||
// Execute our template
|
||||
templ, _ := template.New("KeyTemplate").Parse(baseECDSAKey)
|
||||
templ.Execute(&jsonKey, KeyTemplate{KeyType: data.ECDSAKey})
|
||||
|
||||
json.Unmarshal(jsonKey.Bytes(), &testECDSAKey)
|
||||
testECDSAKey, err := data.UnmarshalPrivateKey(jsonKey.Bytes())
|
||||
assert.NoError(t, err)
|
||||
|
||||
// Sign some data using ECDSA
|
||||
message := []byte("test data for signing")
|
||||
hashed := sha256.Sum256(message)
|
||||
signedData, err := ecdsaSign(&testECDSAKey, hashed[:])
|
||||
signedData, err := ecdsaSign(testECDSAKey, hashed[:])
|
||||
assert.NoError(t, err)
|
||||
|
||||
// Modify the signature
|
||||
|
@ -397,7 +412,7 @@ func TestECDSAVerifierWithInvalidSignature(t *testing.T) {
|
|||
|
||||
// Create and call Verify on the verifier
|
||||
ecdsaVerifier := ECDSAVerifier{}
|
||||
err = ecdsaVerifier.Verify(&testECDSAKey, signedData, message)
|
||||
err = ecdsaVerifier.Verify(testECDSAKey, signedData, message)
|
||||
assert.Error(t, err, "signature verification failed")
|
||||
|
||||
}
|
||||
|
@ -419,7 +434,7 @@ func TestRSAPyCryptoVerifierInvalidKeyType(t *testing.T) {
|
|||
}
|
||||
|
||||
func rsaPSSSign(privKey data.PrivateKey, hash crypto.Hash, hashed []byte) ([]byte, error) {
|
||||
if privKey.Algorithm() != data.RSAKey {
|
||||
if privKey, ok := privKey.(*data.RSAPrivateKey); !ok {
|
||||
return nil, fmt.Errorf("private key type not supported: %s", privKey.Algorithm())
|
||||
}
|
||||
|
||||
|
@ -439,7 +454,7 @@ func rsaPSSSign(privKey data.PrivateKey, hash crypto.Hash, hashed []byte) ([]byt
|
|||
}
|
||||
|
||||
func rsaPKCS1v15Sign(privKey data.PrivateKey, hash crypto.Hash, hashed []byte) ([]byte, error) {
|
||||
if privKey.Algorithm() != data.RSAKey {
|
||||
if privKey, ok := privKey.(*data.RSAPrivateKey); !ok {
|
||||
return nil, fmt.Errorf("private key type not supported: %s", privKey.Algorithm())
|
||||
}
|
||||
|
||||
|
@ -459,7 +474,7 @@ func rsaPKCS1v15Sign(privKey data.PrivateKey, hash crypto.Hash, hashed []byte) (
|
|||
}
|
||||
|
||||
func ecdsaSign(privKey data.PrivateKey, hashed []byte) ([]byte, error) {
|
||||
if privKey.Algorithm() != data.ECDSAKey {
|
||||
if _, ok := privKey.(*data.ECDSAPrivateKey); !ok {
|
||||
return nil, fmt.Errorf("private key type not supported: %s", privKey.Algorithm())
|
||||
}
|
||||
|
||||
|
@ -487,29 +502,3 @@ func ecdsaSign(privKey data.PrivateKey, hashed []byte) ([]byte, error) {
|
|||
|
||||
return append(rBuf, sBuf...), nil
|
||||
}
|
||||
|
||||
// Use this function to generate the X509 signatures that are hardcoded into
|
||||
// the test
|
||||
func signX509() {
|
||||
// Unmarshal our private RSA Key
|
||||
var testRSAKey data.TUFKey
|
||||
var jsonKey bytes.Buffer
|
||||
|
||||
// Execute our template
|
||||
templ, _ := template.New("KeyTemplate").Parse(baseRSAx509Key)
|
||||
templ.Execute(&jsonKey, KeyTemplate{KeyType: data.RSAKey})
|
||||
|
||||
json.Unmarshal(jsonKey.Bytes(), &testRSAKey)
|
||||
|
||||
message := []byte("test data for signing")
|
||||
hash := crypto.SHA256
|
||||
hashed := sha256.Sum256(message)
|
||||
|
||||
// Use the RSA key to RSAPKCS1v15 sign the data
|
||||
signedData, _ := rsaPKCS1v15Sign(&testRSAKey, hash, hashed[:])
|
||||
fmt.Println("signed with pkcs1v15:", hex.EncodeToString(signedData))
|
||||
|
||||
// Use the RSA key to RSAPSS sign the data
|
||||
signedData, _ = rsaPSSSign(&testRSAKey, hash, hashed[:])
|
||||
fmt.Println("signed with pss:", hex.EncodeToString(signedData))
|
||||
}
|
||||
|
|
22
tuf/tuf.go
22
tuf/tuf.go
|
@ -83,11 +83,10 @@ func (tr *Repo) AddBaseKeys(role string, keys ...data.PublicKey) error {
|
|||
ids := []string{}
|
||||
for _, k := range keys {
|
||||
// Store only the public portion
|
||||
pubKey := data.NewPrivateKey(k.Algorithm(), k.Public(), nil)
|
||||
tr.Root.Signed.Keys[pubKey.ID()] = pubKey
|
||||
tr.Root.Signed.Keys[k.ID()] = k
|
||||
tr.keysDB.AddKey(k)
|
||||
tr.Root.Signed.Roles[role].KeyIDs = append(tr.Root.Signed.Roles[role].KeyIDs, pubKey.ID())
|
||||
ids = append(ids, pubKey.ID())
|
||||
tr.Root.Signed.Roles[role].KeyIDs = append(tr.Root.Signed.Roles[role].KeyIDs, k.ID())
|
||||
ids = append(ids, k.ID())
|
||||
}
|
||||
r, err := data.NewRole(
|
||||
role,
|
||||
|
@ -162,7 +161,7 @@ func (tr *Repo) RemoveBaseKeys(role string, keyIDs ...string) error {
|
|||
// An empty before string indicates to add the role to the end of the
|
||||
// delegation list.
|
||||
// A new, empty, targets file will be created for the new role.
|
||||
func (tr *Repo) UpdateDelegations(role *data.Role, keys []data.Key, before string) error {
|
||||
func (tr *Repo) UpdateDelegations(role *data.Role, keys []data.PublicKey, before string) error {
|
||||
if !role.IsDelegation() || !role.IsValid() {
|
||||
return errors.ErrInvalidRole{}
|
||||
}
|
||||
|
@ -172,12 +171,11 @@ func (tr *Repo) UpdateDelegations(role *data.Role, keys []data.Key, before strin
|
|||
return errors.ErrInvalidRole{}
|
||||
}
|
||||
for _, k := range keys {
|
||||
key := data.NewPublicKey(k.Algorithm(), k.Public())
|
||||
if !utils.StrSliceContains(role.KeyIDs, key.ID()) {
|
||||
role.KeyIDs = append(role.KeyIDs, key.ID())
|
||||
if !utils.StrSliceContains(role.KeyIDs, k.ID()) {
|
||||
role.KeyIDs = append(role.KeyIDs, k.ID())
|
||||
}
|
||||
p.Signed.Delegations.Keys[key.ID()] = key
|
||||
tr.keysDB.AddKey(key)
|
||||
p.Signed.Delegations.Keys[k.ID()] = k
|
||||
tr.keysDB.AddKey(k)
|
||||
}
|
||||
|
||||
i := -1
|
||||
|
@ -234,9 +232,7 @@ func (tr *Repo) InitRoot(consistent bool) error {
|
|||
// don't need to check if GetKey returns nil, Key presence was
|
||||
// checked by KeyDB when role was added.
|
||||
key := tr.keysDB.GetKey(kid)
|
||||
// Create new key object to doubly ensure private key is excluded
|
||||
k := data.NewPublicKey(key.Algorithm(), key.Public())
|
||||
rootKeys[kid] = k
|
||||
rootKeys[kid] = key
|
||||
}
|
||||
}
|
||||
root, err := data.NewRoot(rootKeys, rootRoles, consistent)
|
||||
|
|
|
@ -142,7 +142,7 @@ func TestUpdateDelegations(t *testing.T) {
|
|||
t.Fatal(err)
|
||||
}
|
||||
|
||||
err = repo.UpdateDelegations(role, []data.Key{testKey}, "")
|
||||
err = repo.UpdateDelegations(role, data.KeyList{testKey}, "")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
@ -156,7 +156,7 @@ func TestUpdateDelegations(t *testing.T) {
|
|||
t.Fatal(err)
|
||||
}
|
||||
|
||||
err = repo.UpdateDelegations(roleDeep, []data.Key{testDeepKey}, "")
|
||||
err = repo.UpdateDelegations(roleDeep, data.KeyList{testDeepKey}, "")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue