// createPasswordRec creates a new record from a username and password
func createPasswordRec(password string, admin bool) (newRec PasswordRecord, err error) {
	newRec.Type = DefaultRecordType

	if newRec.PasswordSalt, err = symcrypt.MakeRandom(16); err != nil {
		return
	}

	if newRec.HashedPassword, err = hashPassword(password, newRec.PasswordSalt); err != nil {
		return
	}

	if newRec.KeySalt, err = symcrypt.MakeRandom(16); err != nil {
		return
	}

	passKey, err := derivePasswordKey(password, newRec.KeySalt)
	if err != nil {
		return
	}

	// generate a key pair
	switch DefaultRecordType {
	case RSARecord:
		var rsaPriv *rsa.PrivateKey
		rsaPriv, err = rsa.GenerateKey(rand.Reader, 2048)
		if err != nil {
			return
		}
		// encrypt RSA key with password key
		if err = encryptRSARecord(&newRec, rsaPriv, passKey); err != nil {
			return
		}
		newRec.RSAKey.RSAPublic = rsaPriv.PublicKey
	case ECCRecord:
		var ecPriv *ecdsa.PrivateKey
		ecPriv, err = ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
		if err != nil {
			return
		}
		// encrypt ECDSA key with password key
		if err = encryptECCRecord(&newRec, ecPriv, passKey); err != nil {
			return
		}
		newRec.ECKey.ECPublic = ecPriv.PublicKey
	}

	// encrypt AES key with password key
	aesKey, err := symcrypt.MakeRandom(16)
	if err != nil {
		return
	}

	if newRec.AESKey, err = encryptECB(aesKey, passKey); err != nil {
		return
	}

	newRec.Admin = admin

	return
}
// encryptRSARecord takes an RSA private key and encrypts it with
// a password key
func encryptRSARecord(newRec *PasswordRecord, rsaPriv *rsa.PrivateKey, passKey []byte) (err error) {
	if newRec.RSAKey.RSAExpIV, err = symcrypt.MakeRandom(16); err != nil {
		return
	}

	paddedExponent := padding.AddPadding(rsaPriv.D.Bytes())
	if newRec.RSAKey.RSAExp, err = symcrypt.EncryptCBC(paddedExponent, newRec.RSAKey.RSAExpIV, passKey); err != nil {
		return
	}

	if newRec.RSAKey.RSAPrimePIV, err = symcrypt.MakeRandom(16); err != nil {
		return
	}

	paddedPrimeP := padding.AddPadding(rsaPriv.Primes[0].Bytes())
	if newRec.RSAKey.RSAPrimeP, err = symcrypt.EncryptCBC(paddedPrimeP, newRec.RSAKey.RSAPrimePIV, passKey); err != nil {
		return
	}

	if newRec.RSAKey.RSAPrimeQIV, err = symcrypt.MakeRandom(16); err != nil {
		return
	}

	paddedPrimeQ := padding.AddPadding(rsaPriv.Primes[1].Bytes())
	newRec.RSAKey.RSAPrimeQ, err = symcrypt.EncryptCBC(paddedPrimeQ, newRec.RSAKey.RSAPrimeQIV, passKey)
	return
}
Example #3
0
// ChangePassword changes the password for a given user.
func (records *Records) ChangePassword(name, password, newPassword string) (err error) {
	pr, ok := records.GetRecord(name)
	if !ok {
		err = errors.New("Record not present")
		return
	}

	var keySalt []byte
	if keySalt, err = symcrypt.MakeRandom(16); err != nil {
		return
	}
	newPassKey, err := derivePasswordKey(newPassword, keySalt)
	if err != nil {
		return
	}

	// decrypt with old password and re-encrypt original key with new password
	if pr.Type == RSARecord {
		var rsaKey rsa.PrivateKey
		rsaKey, err = pr.GetKeyRSA(password)
		if err != nil {
			return
		}

		// encrypt RSA key with password key
		err = encryptRSARecord(&pr, &rsaKey, newPassKey)
		if err != nil {
			return
		}
	} else if pr.Type == ECCRecord {
		var ecKey *ecdsa.PrivateKey
		ecKey, err = pr.GetKeyECC(password)
		if err != nil {
			return
		}

		// encrypt ECDSA key with password key
		err = encryptECCRecord(&pr, ecKey, newPassKey)
		if err != nil {
			return
		}
	} else {
		err = errors.New("Unkown record type")
		return
	}

	// add the password salt and hash
	if pr.PasswordSalt, err = symcrypt.MakeRandom(16); err != nil {
		return
	}
	if pr.HashedPassword, err = hashPassword(newPassword, pr.PasswordSalt); err != nil {
		return
	}

	pr.KeySalt = keySalt

	records.SetRecord(pr, name)

	return records.WriteRecordsToDisk()
}
// createPasswordRec creates a new record from a username and password
func createPasswordRec(password string, admin bool, userType string) (newRec PasswordRecord, err error) {
	newRec.Type = userType

	if newRec.PasswordSalt, err = symcrypt.MakeRandom(16); err != nil {
		return
	}

	if newRec.HashedPassword, err = hashPassword(password, newRec.PasswordSalt); err != nil {
		return
	}

	if newRec.KeySalt, err = symcrypt.MakeRandom(16); err != nil {
		return
	}

	passKey, err := derivePasswordKey(password, newRec.KeySalt)
	if err != nil {
		return
	}

	newRec.AltNames = make(map[string]string)

	// generate a key pair
	switch userType {
	case RSARecord:
		var rsaPriv *rsa.PrivateKey
		rsaPriv, err = rsa.GenerateKey(rand.Reader, 2048)
		if err != nil {
			return
		}
		// encrypt RSA key with password key
		if err = encryptRSARecord(&newRec, rsaPriv, passKey); err != nil {
			return
		}
		newRec.RSAKey.RSAPublic = rsaPriv.PublicKey
	case ECCRecord:
		var ecPriv *ecdsa.PrivateKey
		ecPriv, err = ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
		if err != nil {
			return
		}
		// encrypt ECDSA key with password key
		if err = encryptECCRecord(&newRec, ecPriv, passKey); err != nil {
			return
		}
		newRec.ECKey.ECPublic.Curve = ecPriv.PublicKey.Curve.Params()
		newRec.ECKey.ECPublic.X = ecPriv.PublicKey.X
		newRec.ECKey.ECPublic.Y = ecPriv.PublicKey.Y
	default:
		err = errors.New("Unknown record type")
	}

	newRec.Admin = admin

	return
}
func init() {
	// seed math.random from crypto.random
	seedBytes, _ := symcrypt.MakeRandom(8)
	seedBuf := bytes.NewBuffer(seedBytes)
	n64, _ := binary.ReadVarint(seedBuf)
	mrand.Seed(n64)
}
Example #6
0
// Encrypt secures and authenticates its input using the public key
// using ECDHE with AES-128-CBC-HMAC-SHA1.
func Encrypt(pub *ecdsa.PublicKey, in []byte) (out []byte, err error) {
	ephemeral, err := ecdsa.GenerateKey(Curve(), rand.Reader)
	if err != nil {
		return
	}
	x, _ := pub.Curve.ScalarMult(pub.X, pub.Y, ephemeral.D.Bytes())
	if x == nil {
		return nil, errors.New("Failed to generate encryption key")
	}
	shared := sha256.Sum256(x.Bytes())
	iv, err := symcrypt.MakeRandom(16)
	if err != nil {
		return
	}

	paddedIn := padding.AddPadding(in)
	ct, err := symcrypt.EncryptCBC(paddedIn, iv, shared[:16])
	if err != nil {
		return
	}

	ephPub := elliptic.Marshal(pub.Curve, ephemeral.PublicKey.X, ephemeral.PublicKey.Y)
	out = make([]byte, 1+len(ephPub)+16)
	out[0] = byte(len(ephPub))
	copy(out[1:], ephPub)
	copy(out[1+len(ephPub):], iv)
	out = append(out, ct...)

	h := hmac.New(sha1.New, shared[16:])
	h.Write(iv)
	h.Write(ct)
	out = h.Sum(out)
	return
}
Example #7
0
// Encrypt encrypts data with the keys associated with names. This
// requires a minimum of min keys to decrypt.  NOTE: as currently
// implemented, the maximum value for min is 2.
func (c *Cryptor) Encrypt(in []byte, labels []string, access AccessStructure) (resp []byte, err error) {
	var encrypted EncryptedData
	encrypted.Version = DEFAULT_VERSION
	if encrypted.VaultId, err = c.records.GetVaultID(); err != nil {
		return
	}

	// Generate random IV and encryption key
	encrypted.IV, err = symcrypt.MakeRandom(16)
	if err != nil {
		return
	}

	clearKey, err := symcrypt.MakeRandom(16)
	if err != nil {
		return
	}

	err = encrypted.wrapKey(c.records, clearKey, access)
	if err != nil {
		return
	}

	// encrypt file with clear key
	aesCrypt, err := aes.NewCipher(clearKey)
	if err != nil {
		return
	}

	clearFile := padding.AddPadding(in)

	encryptedFile := make([]byte, len(clearFile))
	aesCBC := cipher.NewCBCEncrypter(aesCrypt, encrypted.IV)
	aesCBC.CryptBlocks(encryptedFile, clearFile)

	encrypted.Data = encryptedFile
	encrypted.Labels = labels

	hmacKey, err := c.records.GetHMACKey()
	if err != nil {
		return
	}
	encrypted.Signature = encrypted.computeHmac(hmacKey)
	encrypted.lock(hmacKey)

	return json.Marshal(encrypted)
}
// encryptECCRecord takes an ECDSA private key and encrypts it with
// a password key.
func encryptECCRecord(newRec *PasswordRecord, ecPriv *ecdsa.PrivateKey, passKey []byte) (err error) {
	ecX509, err := x509.MarshalECPrivateKey(ecPriv)
	if err != nil {
		return
	}

	if newRec.ECKey.ECPrivIV, err = symcrypt.MakeRandom(16); err != nil {
		return
	}

	paddedX509 := padding.AddPadding(ecX509)
	newRec.ECKey.ECPriv, err = symcrypt.EncryptCBC(paddedX509, newRec.ECKey.ECPrivIV, passKey)
	return
}
// ChangePassword changes the password for a given user.
func ChangePassword(name, password, newPassword string) (err error) {
	pr, ok := GetRecord(name)
	if !ok {
		err = errors.New("Record not present")
		return
	}
	if err = pr.ValidatePassword(password); err != nil {
		return
	}

	// decrypt key
	var key []byte
	var rsaKey rsa.PrivateKey
	var ecKey *ecdsa.PrivateKey
	if pr.Type == AESRecord {
		key, err = pr.GetKeyAES(password)
		if err != nil {
			return
		}
	} else if pr.Type == RSARecord {
		rsaKey, err = pr.GetKeyRSA(password)
		if err != nil {
			return
		}
	} else if pr.Type == ECCRecord {
		ecKey, err = pr.GetKeyECC(password)
		if err != nil {
			return
		}
	} else {
		err = errors.New("Unkown record type")
		return
	}

	// add the password salt and hash
	if pr.PasswordSalt, err = symcrypt.MakeRandom(16); err != nil {
		return
	}
	if pr.HashedPassword, err = hashPassword(newPassword, pr.PasswordSalt); err != nil {
		return
	}

	if pr.KeySalt, err = symcrypt.MakeRandom(16); err != nil {
		return
	}
	newPassKey, err := derivePasswordKey(newPassword, pr.KeySalt)
	if err != nil {
		return
	}

	// encrypt original key with new password
	if pr.Type == AESRecord {
		pr.AESKey, err = encryptECB(key, newPassKey)
		if err != nil {
			return
		}
	} else if pr.Type == RSARecord {
		// encrypt RSA key with password key
		err = encryptRSARecord(&pr, &rsaKey, newPassKey)
		if err != nil {
			return
		}
	} else if pr.Type == ECCRecord {
		// encrypt ECDSA key with password key
		err = encryptECCRecord(&pr, ecKey, newPassKey)
		if err != nil {
			return
		}
	} else {
		err = errors.New("Unkown record type")
		return
	}

	SetRecord(pr, name)

	return WriteRecordsToDisk()
}
// InitFromDisk reads the record from disk and initialize global context.
func InitFromDisk(path string) error {
	jsonDiskRecord, err := ioutil.ReadFile(path)

	// It's OK for the file to be missing, we'll create it later if
	// anything is added.

	if err != nil && !os.IsNotExist(err) {
		return err
	}

	// Initialized so that we can determine later if anything was read
	// from the file.

	records.Version = 0

	if len(jsonDiskRecord) != 0 {
		if err = json.Unmarshal(jsonDiskRecord, &records); err != nil {
			return err
		}
	}

	formatErr := errors.New("Format error")
	for _, rec := range records.Passwords {
		if len(rec.PasswordSalt) != 16 {
			return formatErr
		}
		if len(rec.HashedPassword) != 16 {
			return formatErr
		}
		if len(rec.KeySalt) != 16 {
			return formatErr
		}
		if rec.Type == AESRecord {
			if len(rec.AESKey) != 16 {
				return formatErr
			}
		}
		if rec.Type == RSARecord {
			if len(rec.RSAKey.RSAExp) == 0 || len(rec.RSAKey.RSAExp)%16 != 0 {
				return formatErr
			}
			if len(rec.RSAKey.RSAPrimeP) == 0 || len(rec.RSAKey.RSAPrimeP)%16 != 0 {
				return formatErr
			}
			if len(rec.RSAKey.RSAPrimeQ) == 0 || len(rec.RSAKey.RSAPrimeQ)%16 != 0 {
				return formatErr
			}
			if len(rec.RSAKey.RSAExpIV) != 16 {
				return formatErr
			}
			if len(rec.RSAKey.RSAPrimePIV) != 16 {
				return formatErr
			}
			if len(rec.RSAKey.RSAPrimeQIV) != 16 {
				return formatErr
			}
		}
		if rec.Type == ECCRecord {
			if len(rec.ECKey.ECPriv) == 0 {
				return formatErr
			}
		}
	}

	// If the Version field is 0 then it indicates that nothing was
	// read from the file and so it needs to be initialized.

	if records.Version == 0 {
		records.Version = DEFAULT_VERSION
		records.VaultId = int(mrand.Int31())
		records.HmacKey, err = symcrypt.MakeRandom(16)
		if err != nil {
			return err
		}
		records.Passwords = make(map[string]PasswordRecord)
	}

	localPath = path

	return nil
}
Example #11
0
func TestUsesFlush(t *testing.T) {
	// Initialize passvault with one dummy user.
	records, err := passvault.InitFrom("memory")
	if err != nil {
		t.Fatalf("%v", err)
	}

	pr, err := records.AddNewRecord("user", "weakpassword", true, passvault.DefaultRecordType)
	if err != nil {
		t.Fatalf("%v", err)
	}

	// Initialize keycache and delegate the user's key to it.
	cache := NewCache()

	err = cache.AddKeyFromRecord(pr, "user", "weakpassword", nil, nil, 2, "", "1h")
	if err != nil {
		t.Fatalf("%v", err)
	}

	cache.Refresh()
	if len(cache.UserKeys) != 1 {
		t.Fatalf("Error in number of live keys")
	}

	// Generate a random symmetric key, encrypt a blank block with it, and encrypt
	// the key itself with the user's public key.
	dummy := make([]byte, 16)
	key, err := symcrypt.MakeRandom(16)
	if err != nil {
		t.Fatalf("%v", err)
	}

	encKey, err := symcrypt.EncryptCBC(dummy, dummy, key)
	if err != nil {
		t.Fatalf("%v", err)
	}

	pubEncryptedKey, err := pr.EncryptKey(key)
	if err != nil {
		t.Fatalf("%v", err)
	}

	key2, err := cache.DecryptKey(encKey, "user", "anybody", []string{}, pubEncryptedKey)
	if err != nil {
		t.Fatalf("%v", err)
	}

	if bytes.Equal(key, key2) {
		t.Fatalf("cache.DecryptKey didnt decrypt the right key!")
	}

	// Second decryption allowed.
	_, err = cache.DecryptKey(encKey, "user", "anybody else", []string{}, pubEncryptedKey)
	if err != nil {
		t.Fatalf("%v", err)
	}

	if len(cache.UserKeys) != 0 {
		t.Fatalf("Error in number of live keys %v", cache.UserKeys)
	}
}
Example #12
0
// wrapKey encrypts the clear key according to an access structure.
func (encrypted *EncryptedData) wrapKey(records *passvault.Records, clearKey []byte, access AccessStructure) (err error) {
	generateRandomKey := func(name string) (singleWrappedKey SingleWrappedKey, err error) {
		rec, ok := records.GetRecord(name)
		if !ok {
			err = errors.New("Missing user on disk")
			return
		}

		if singleWrappedKey.aesKey, err = symcrypt.MakeRandom(16); err != nil {
			return
		}

		if singleWrappedKey.Key, err = rec.EncryptKey(singleWrappedKey.aesKey); err != nil {
			return
		}

		return
	}

	encryptKey := func(outer, inner string, clearKey []byte) (keyBytes []byte, err error) {
		var outerCrypt, innerCrypt cipher.Block
		keyBytes = make([]byte, 16)

		outerCrypt, err = aes.NewCipher(encrypted.KeySetRSA[outer].aesKey)
		if err != nil {
			return
		}

		innerCrypt, err = aes.NewCipher(encrypted.KeySetRSA[inner].aesKey)
		if err != nil {
			return
		}

		innerCrypt.Encrypt(keyBytes, clearKey)
		outerCrypt.Encrypt(keyBytes, keyBytes)

		return
	}

	if len(access.Names) > 0 {
		// Generate a random AES key for each user and RSA/ECIES encrypt it
		encrypted.KeySetRSA = make(map[string]SingleWrappedKey)

		for _, name := range access.Names {
			encrypted.KeySetRSA[name], err = generateRandomKey(name)
			if err != nil {
				return err
			}
		}

		// encrypt file key with every combination of two keys
		encrypted.KeySet = make([]MultiWrappedKey, 0)

		for i := 0; i < len(access.Names); i++ {
			for j := i + 1; j < len(access.Names); j++ {
				keyBytes, err := encryptKey(access.Names[i], access.Names[j], clearKey)
				if err != nil {
					return err
				}

				out := MultiWrappedKey{
					Name: []string{access.Names[i], access.Names[j]},
					Key:  keyBytes,
				}

				encrypted.KeySet = append(encrypted.KeySet, out)
			}
		}
	} else if len(access.LeftNames) > 0 && len(access.RightNames) > 0 {
		// Generate a random AES key for each user and RSA/ECIES encrypt it
		encrypted.KeySetRSA = make(map[string]SingleWrappedKey)

		for _, name := range access.LeftNames {
			encrypted.KeySetRSA[name], err = generateRandomKey(name)
			if err != nil {
				return err
			}
		}

		for _, name := range access.RightNames {
			encrypted.KeySetRSA[name], err = generateRandomKey(name)
			if err != nil {
				return err
			}
		}

		// encrypt file key with every combination of one left key and one right key
		encrypted.KeySet = make([]MultiWrappedKey, 0)

		for _, leftName := range access.LeftNames {
			for _, rightName := range access.RightNames {
				if leftName == rightName {
					continue
				}

				keyBytes, err := encryptKey(leftName, rightName, clearKey)
				if err != nil {
					return err
				}

				out := MultiWrappedKey{
					Name: []string{leftName, rightName},
					Key:  keyBytes,
				}

				encrypted.KeySet = append(encrypted.KeySet, out)
			}
		}
	} else if len(access.Predicate) > 0 {
		encrypted.KeySetRSA = make(map[string]SingleWrappedKey)

		sss, err := msp.StringToMSP(access.Predicate)
		if err != nil {
			return err
		}

		db := msp.UserDatabase(UserDatabase{records: records})
		shareSet, err := sss.DistributeShares(clearKey, &db)
		if err != nil {
			return err
		}

		for name, _ := range shareSet {
			encrypted.KeySetRSA[name], err = generateRandomKey(name)
			if err != nil {
				return err
			}
			crypt, err := aes.NewCipher(encrypted.KeySetRSA[name].aesKey)
			if err != nil {
				return err
			}

			for i, _ := range shareSet[name] {
				tmp := make([]byte, 16)
				crypt.Encrypt(tmp, shareSet[name][i])
				shareSet[name][i] = tmp
			}
		}

		encrypted.ShareSet = shareSet
		encrypted.Predicate = access.Predicate
	} else {
		return errors.New("Invalid access structure.")
	}

	return nil
}
Example #13
0
// Encrypt encrypts data with the keys associated with names. This
// requires a minimum of min keys to decrypt.  NOTE: as currently
// implemented, the maximum value for min is 2.
func Encrypt(in []byte, names []string, min int) (resp []byte, err error) {
	if min > 2 {
		return nil, errors.New("Minimum restricted to 2")
	}

	var encrypted EncryptedData
	encrypted.Version = DEFAULT_VERSION
	if encrypted.VaultId, err = passvault.GetVaultId(); err != nil {
		return
	}

	// Generate random IV and encryption key
	ivBytes, err := symcrypt.MakeRandom(16)
	if err != nil {
		return
	}

	// append used here to make a new slice from ivBytes and assign to
	// encrypted.IV

	encrypted.IV = append([]byte{}, ivBytes...)
	clearKey, err := symcrypt.MakeRandom(16)
	if err != nil {
		return
	}

	// Allocate set of keys to be able to cover all ordered subsets of
	// length 2 of names

	encrypted.KeySet = make([]MultiWrappedKey, len(names)*(len(names)-1))
	encrypted.KeySetRSA = make(map[string]SingleWrappedKey)

	var singleWrappedKey SingleWrappedKey
	for _, name := range names {
		rec, ok := passvault.GetRecord(name)
		if !ok {
			err = errors.New("Missing user on disk")
			return
		}

		if rec.GetType() == passvault.RSARecord || rec.GetType() == passvault.ECCRecord {
			// only wrap key with RSA key if found
			if singleWrappedKey.aesKey, err = symcrypt.MakeRandom(16); err != nil {
				return nil, err
			}

			if singleWrappedKey.Key, err = rec.EncryptKey(singleWrappedKey.aesKey); err != nil {
				return nil, err
			}
			encrypted.KeySetRSA[name] = singleWrappedKey
		} else {
			err = nil
		}
	}

	// encrypt file key with every combination of two keys
	var n int
	for _, nameOuter := range names {
		for _, nameInner := range names {
			if nameInner != nameOuter {
				encrypted.KeySet[n], err = encryptKey(nameInner, nameOuter, clearKey, encrypted.KeySetRSA)
				n += 1
			}
			if err != nil {
				return
			}
		}
	}

	// encrypt file with clear key
	aesCrypt, err := aes.NewCipher(clearKey)
	if err != nil {
		return
	}

	clearFile := padding.AddPadding(in)

	encryptedFile := make([]byte, len(clearFile))
	aesCBC := cipher.NewCBCEncrypter(aesCrypt, ivBytes)
	aesCBC.CryptBlocks(encryptedFile, clearFile)

	encrypted.Data = encryptedFile

	hmacKey, err := passvault.GetHmacKey()
	if err != nil {
		return
	}
	encrypted.Signature = computeHmac(hmacKey, encrypted)

	return json.Marshal(encrypted)
}