Ejemplo n.º 1
0
Archivo: persist.go Proyecto: mm3/Sia
// saveSiafundTracking save the addresses that track siafunds.
func (w *Wallet) saveSiafundTracking(filepath string) error {
	// Put the siafund tracking addresses into a slice and write to disk.
	siafundSlice := make([]types.UnlockHash, 0, len(w.siafundAddresses))
	for sa, _ := range w.siafundAddresses {
		siafundSlice = append(siafundSlice, sa)
	}
	return encoding.WriteFile(filepath, siafundSlice)
}
Ejemplo n.º 2
0
Archivo: persist.go Proyecto: mm3/Sia
// saveKeys saves the current set of keys known to the wallet to a file.
func (w *Wallet) saveKeys(filepath string) error {
	// Convert the key map to a slice and write to disk.
	keySlice := make([]savedKey, 0, len(w.keys))
	for _, key := range w.keys {
		_, exists := w.visibleAddresses[key.unlockConditions.UnlockHash()]
		keySlice = append(keySlice, savedKey{key.secretKey, key.unlockConditions, exists})
	}
	return encoding.WriteFile(filepath, keySlice)
}
Ejemplo n.º 3
0
Archivo: keys_test.go Proyecto: mm3/Sia
// TestPrintKeyInfo probes the printKeyInfo function.
func TestPrintKeyInfo(t *testing.T) {
	if testing.Short() {
		t.SkipNow()
	}

	testDir := build.TempDir("siakg", "TestPrintKeyInfo")

	// Check that a corrupted header or version will trigger an error.
	keyname := "headerCheck"
	_, err := generateKeys(1, 1, testDir, keyname)
	if err != nil {
		t.Fatal(err)
	}
	var kp, badKP KeyPair
	keyfile := filepath.Join(testDir, keyname+"_Key0"+FileExtension)
	err = encoding.ReadFile(keyfile, &kp)
	if err != nil {
		t.Fatal(err)
	}
	badKP = kp
	badKP.Header = "bad"
	err = encoding.WriteFile(keyfile, badKP)
	if err != nil {
		t.Fatal(err)
	}
	err = printKeyInfo(keyfile)
	if err != ErrUnknownHeader {
		t.Error("Expected ErrUnknownHeader:", err)
	}
	badKP = kp
	badKP.Version = "bad"
	err = encoding.WriteFile(keyfile, badKP)
	if err != nil {
		t.Fatal(err)
	}
	err = printKeyInfo(keyfile)
	if err != ErrUnknownVersion {
		t.Error("Expected ErrUnknownVersion:", err)
	}
}
Ejemplo n.º 4
0
Archivo: keys_test.go Proyecto: mm3/Sia
// TestVerifyKeys proves the verifyKeys function.
func TestVerifyKeys(t *testing.T) {
	if testing.Short() {
		t.SkipNow()
	}

	testDir := build.TempDir("siag", "TestVerifyKeys")

	// Check that a corrupted header or version will trigger an error.
	keyname := "headerCheck"
	uc, err := generateKeys(1, 1, testDir, keyname)
	if err != nil {
		t.Fatal(err)
	}
	var kp, badKP KeyPair
	keyfile := filepath.Join(testDir, keyname+"_Key0"+FileExtension)
	err = encoding.ReadFile(keyfile, &kp)
	if err != nil {
		t.Fatal(err)
	}
	badKP = kp
	badKP.Header = "bad"
	err = encoding.WriteFile(keyfile, badKP)
	if err != nil {
		t.Fatal(err)
	}
	err = verifyKeys(uc, testDir, keyname)
	if err != ErrUnknownHeader {
		t.Error("Expected ErrUnknownHeader:", err)
	}
	badKP = kp
	badKP.Version = "bad"
	err = encoding.WriteFile(keyfile, badKP)
	if err != nil {
		t.Fatal(err)
	}
	err = verifyKeys(uc, testDir, keyname)
	if err != ErrUnknownVersion {
		t.Error("Expected ErrUnknownVersion:", err)
	}

	// Create sets of keys that cover all boundaries from 0 of 1 to 5 of 9.
	// This is to check for errors in the keycheck calculations.
	for i := 1; i < 5; i++ {
		for j := i; j < 9; j++ {
			keyname := "genuine" + strconv.Itoa(i) + strconv.Itoa(j)
			uc, err := generateKeys(i, j, testDir, keyname)
			if err != nil {
				t.Fatal(err)
			}

			// Check that the validate under standard conditions.
			err = verifyKeys(uc, testDir, keyname)
			if err != nil {
				t.Error(err)
			}

			// Provide the wrong keyname to simulate a file does not exist error.
			err = verifyKeys(uc, testDir, "wrongName")
			if err == nil {
				t.Error("Expecting an error")
			}

			// Corrupt the unlock conditions of the files 1 by 1, and see that each
			// file is checked for validity.
			for k := 0; k < j; k++ {
				// Load, corrupt, and then save the keypair. This corruption
				// alters the UnlockConditions.
				var originalKP, badKP KeyPair
				keyfile := filepath.Join(testDir, keyname+"_Key"+strconv.Itoa(k)+FileExtension)
				err := encoding.ReadFile(keyfile, &originalKP)
				if err != nil {
					t.Fatal(err)
				}
				badKP = originalKP
				badKP.UnlockConditions.PublicKeys = nil
				err = encoding.WriteFile(keyfile, badKP)
				if err != nil {
					t.Fatal(err)
				}

				// Run verifyKeys with the corrupted file.
				err = verifyKeys(uc, testDir, keyname)
				if err == nil {
					t.Error("Expecting error after corrupting unlock conditions")
				}

				// Restore the original keyfile.
				err = encoding.WriteFile(keyfile, originalKP)
				if err != nil {
					t.Fatal(err)
				}

				// Verify that things work again.
				err = verifyKeys(uc, testDir, keyname)
				if err != nil {
					t.Fatal(err)
				}
			}

			// Corrupt the secret keys of the files 1 by 1, and see that each secret
			// key is checked for validity.
			for k := 0; k < j; k++ {
				// Load, corrupt, and then save the keypair. This corruption
				// alters the secret key.
				var originalKP, badKP KeyPair
				keyfile := filepath.Join(testDir, keyname+"_Key"+strconv.Itoa(k)+FileExtension)
				err := encoding.ReadFile(keyfile, &originalKP)
				if err != nil {
					t.Fatal(err)
				}
				badKP = originalKP
				badKP.SecretKey[0]++
				err = encoding.WriteFile(keyfile, badKP)
				if err != nil {
					t.Fatal(err)
				}

				// Run verifyKeys with the corrupted file.
				err = verifyKeys(uc, testDir, keyname)
				if err == nil {
					t.Error("Expecting error after corrupting unlock conditions")
				}

				// Restore the original keyfile.
				err = encoding.WriteFile(keyfile, originalKP)
				if err != nil {
					t.Fatal(err)
				}

				// Verify that things work again.
				err = verifyKeys(uc, testDir, keyname)
				if err != nil {
					t.Fatal(err)
				}
			}
		}
	}
}
Ejemplo n.º 5
0
// generateKeys generates a set of keys and saves them to disk.
func generateKeys(requiredKeys int, totalKeys int, folder string, keyname string) (types.UnlockConditions, error) {
	// Check that the inputs have sane values.
	if requiredKeys < 1 {
		return types.UnlockConditions{}, ErrInsecureAddress
	}
	if totalKeys < requiredKeys {
		return types.UnlockConditions{}, ErrUnspendableAddress
	}

	// Generate 'TotalKeys', filling out everything except the unlock
	// conditions.
	keys := make([]KeyPair, totalKeys)
	pubKeys := make([]crypto.PublicKey, totalKeys)
	for i := range keys {
		var err error
		keys[i].Header = FileHeader
		keys[i].Version = FileVersion
		keys[i].Index = i
		keys[i].SecretKey, pubKeys[i], err = crypto.GenerateSignatureKeys()
		if err != nil {
			return types.UnlockConditions{}, err
		}
	}

	// Generate the unlock conditions and add them to each KeyPair object. This
	// must be done second because the keypairs can't be given unlock
	// conditions until the PublicKeys have all been added.
	unlockConditions := types.UnlockConditions{
		Timelock:           0,
		SignaturesRequired: uint64(requiredKeys),
	}
	for i := range keys {
		unlockConditions.PublicKeys = append(unlockConditions.PublicKeys, types.SiaPublicKey{
			Algorithm: types.SignatureEd25519,
			Key:       pubKeys[i][:],
		})
	}
	for i := range keys {
		keys[i].UnlockConditions = unlockConditions
	}

	// Save the KeyPairs to disk.
	if folder != "" {
		err := os.MkdirAll(folder, 0700)
		if err != nil {
			return types.UnlockConditions{}, err
		}
	}
	for i, key := range keys {
		keyFilename := filepath.Join(folder, keyname+"_Key"+strconv.Itoa(i)+FileExtension)
		_, err := os.Stat(keyFilename)
		if !os.IsNotExist(err) {
			if err != nil {
				return types.UnlockConditions{}, err
			}
			return types.UnlockConditions{}, ErrOverwrite
		}
		err = encoding.WriteFile(keyFilename, key)
		if err != nil {
			return types.UnlockConditions{}, err
		}
	}

	return unlockConditions, nil
}