// GetKey returns the PrivateKey given a KeyID func (s *KeyDBStore) GetKey(name string) (data.PrivateKey, string, error) { s.Lock() defer s.Unlock() cachedKeyEntry, ok := s.cachedKeys[name] if ok { return cachedKeyEntry, "", nil } // Retrieve the GORM private key from the database dbPrivateKey := GormPrivateKey{} if s.db.Where(&GormPrivateKey{KeyID: name}).First(&dbPrivateKey).RecordNotFound() { return nil, "", ErrKeyNotFound{} } // Get the passphrase to use for this key passphrase, _, err := s.retriever(dbPrivateKey.KeyID, dbPrivateKey.PassphraseAlias, false, 1) if err != nil { return nil, "", err } // Decrypt private bytes from the gorm key decryptedPrivKey, _, err := jose.Decode(dbPrivateKey.Private, passphrase) if err != nil { return nil, "", err } // Create a new PrivateKey with unencrypted bytes privKey := data.NewPrivateKey(data.KeyAlgorithm(dbPrivateKey.Algorithm), []byte(dbPrivateKey.Public), []byte(decryptedPrivKey)) // Add the key to cache s.cachedKeys[privKey.ID()] = privKey return privKey, "", nil }
// GenRootKey generates a new root key protected by a given passphrase // TODO(diogo): show not create keys manually, should use a cryptoservice instead func (km *KeyStoreManager) GenRootKey(algorithm, passphrase string) (string, error) { var err error var privKey *data.PrivateKey // 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)) { case data.RSAKey: privKey, err = trustmanager.GenerateRSAKey(rand.Reader, rsaRootKeySize) case data.ECDSAKey: privKey, err = trustmanager.GenerateECDSAKey(rand.Reader) default: return "", fmt.Errorf("only RSA or ECDSA keys are currently supported. Found: %s", algorithm) } if err != nil { return "", fmt.Errorf("failed to generate private key: %v", err) } // Changing the root km.rootKeyStore.AddEncryptedKey(privKey.ID(), privKey, passphrase) return privKey.ID(), nil }
// GetKey retrieves a key func (trust *NotarySigner) GetKey(keyid string) data.PublicKey { publicKey, err := trust.kmClient.GetKeyInfo(context.Background(), &pb.KeyID{ID: keyid}) if err != nil { return nil } return data.NewPublicKey(data.KeyAlgorithm(publicKey.KeyInfo.Algorithm.Algorithm), publicKey.PublicKey) }
//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) service := s.CryptoServices[keyAlgo] logger := ctxu.GetLogger(ctx) if service == nil { logger.Error("CreateKey: unsupported algorithm: ", algorithm.Algorithm) return nil, fmt.Errorf("algorithm %s not supported for create key", algorithm.Algorithm) } tufKey, err := service.Create("", keyAlgo) if err != nil { logger.Error("CreateKey: failed to create key: ", err) return nil, grpc.Errorf(codes.Internal, "Key creation failed") } logger.Info("CreateKey: Created KeyID ", tufKey.ID()) return &pb.PublicKey{ KeyInfo: &pb.KeyInfo{ KeyID: &pb.KeyID{ID: tufKey.ID()}, Algorithm: &pb.Algorithm{Algorithm: tufKey.Algorithm().String()}, }, PublicKey: tufKey.Public(), }, nil }
// 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()}) if err != nil { return nil, err } public := data.NewPublicKey(data.KeyAlgorithm(publicKey.KeyInfo.Algorithm.Algorithm), publicKey.PublicKey) return public, nil }
// Create creates a remote key and returns the PublicKey associated with the remote private key // TODO(diogo): Ignoring algorithm for now until notary-signer supports it func (trust *NotarySigner) Create(role string, algorithm data.KeyAlgorithm) (*data.PublicKey, error) { publicKey, err := trust.kmClient.CreateKey(context.Background(), &pb.Algorithm{Algorithm: algorithm.String()}) if err != nil { return nil, err } //TODO(mccauley): Update API to return algorithm and/or take it as a param public := data.NewPublicKey(data.KeyAlgorithm(publicKey.KeyInfo.Algorithm.Algorithm), publicKey.PublicKey) return public, nil }
// PublicKeys returns the public key(s) associated with the passed in keyIDs func (trust *NotarySigner) PublicKeys(keyIDs ...string) (map[string]*data.PublicKey, error) { publicKeys := make(map[string]*data.PublicKey) for _, ID := range keyIDs { keyID := pb.KeyID{ID: ID} public, err := trust.kmClient.GetKeyInfo(context.Background(), &keyID) if err != nil { return nil, err } publicKeys[public.KeyInfo.KeyID.ID] = data.NewPublicKey(data.KeyAlgorithm(public.KeyInfo.Algorithm.Algorithm), public.PublicKey) } return publicKeys, nil }
// GetTimestampKey returns the timestamps Public Key data func (db *MySQLStorage) GetTimestampKey(gun string) (algorithm data.KeyAlgorithm, public []byte, err error) { stmt := "SELECT `cipher`, `public` FROM `timestamp_keys` WHERE `gun`=?;" row := db.QueryRow(stmt, gun) var cipher string err = row.Scan(&cipher, &public) if err == sql.ErrNoRows { return "", nil, &ErrNoKey{gun: gun} } else if err != nil { return "", nil, err } return data.KeyAlgorithm(cipher), public, err }
// GetTimestampKey returns the timestamps Public Key data func (db *SQLStorage) GetTimestampKey(gun string) (algorithm data.KeyAlgorithm, public []byte, err error) { logrus.Debug("retrieving timestamp key for ", gun) var row TimestampKey query := db.Select("cipher, public").Where(&TimestampKey{Gun: gun}).Find(&row) if query.RecordNotFound() { return "", nil, &ErrNoKey{gun: gun} } else if query.Error != nil { return "", nil, query.Error } return data.KeyAlgorithm(row.Cipher), row.Public, nil }
//CreateKey returns a PublicKey created using KeyManagementServer's SigningService func (s *KeyManagementServer) CreateKey(ctx context.Context, algorithm *pb.Algorithm) (*pb.PublicKey, error) { service := s.SigServices[data.KeyAlgorithm(algorithm.Algorithm)] if service == nil { return nil, fmt.Errorf("algorithm %s not supported for create key", algorithm.Algorithm) } key, err := service.CreateKey() if err != nil { return nil, grpc.Errorf(codes.Internal, "Key creation failed") } log.Println("[Notary-signer CreateKey] : Created KeyID ", key.KeyInfo.KeyID.ID) return key, nil }
func TestSQLGetTimestampKeyNoKey(t *testing.T) { tempBaseDir, err := ioutil.TempDir("", "notary-test-") gormDB, dbStore := SetUpSQLite(t, tempBaseDir) defer os.RemoveAll(tempBaseDir) cipher, public, err := dbStore.GetTimestampKey("testGUN") assert.Equal(t, data.KeyAlgorithm(""), cipher) assert.Nil(t, public) assert.IsType(t, &ErrNoKey{}, err, "Expected ErrNoKey from GetTimestampKey") query := gormDB.Create(&TimestampKey{ Gun: "testGUN", Cipher: "testCipher", Public: []byte("1"), }) assert.NoError( t, query.Error, "Inserting timestamp into empty DB should succeed") cipher, public, err = dbStore.GetTimestampKey("testGUN") assert.Equal(t, data.KeyAlgorithm("testCipher"), cipher, "Returned cipher was incorrect") assert.Equal(t, []byte("1"), public, "Returned pubkey was incorrect") }
// GetTimestampKeyHandler returns a timestamp public key, creating a new key-pair // it if it doesn't yet exist func GetTimestampKeyHandler(ctx context.Context, w http.ResponseWriter, r *http.Request) error { vars := mux.Vars(r) gun := vars["imageName"] logger := ctxu.GetLoggerWithField(ctx, gun, "gun") s := ctx.Value("metaStore") store, ok := s.(storage.MetaStore) if !ok { logger.Error("500 GET storage not configured") return errors.ErrNoStorage.WithDetail(nil) } c := ctx.Value("cryptoService") crypto, ok := c.(signed.CryptoService) if !ok { logger.Error("500 GET crypto service not configured") return errors.ErrNoCryptoService.WithDetail(nil) } algo := ctx.Value("keyAlgorithm") keyAlgo, ok := algo.(string) if !ok { logger.Error("500 GET key algorithm not configured") return errors.ErrNoKeyAlgorithm.WithDetail(nil) } keyAlgorithm := data.KeyAlgorithm(keyAlgo) key, err := timestamp.GetOrCreateTimestampKey(gun, store, crypto, keyAlgorithm) if err != nil { logger.Error("500 GET timestamp key: %v", err) return errors.ErrUnknown.WithDetail(err) } out, err := json.Marshal(key) if err != nil { logger.Error("500 GET timestamp key") return errors.ErrUnknown.WithDetail(err) } logger.Debug("200 GET timestamp key") w.Write(out) return nil }