func encryptRSARecord(newRec *PasswordRecord, rsaPriv *rsa.PrivateKey, passKey []byte) (err error) { if newRec.RSAKey.RSAExpIV, err = makeRandom(16); err != nil { return } paddedExponent := padding.AddPadding(rsaPriv.D.Bytes()) if newRec.RSAKey.RSAExp, err = encryptCBC(paddedExponent, newRec.RSAKey.RSAExpIV, passKey); err != nil { return } if newRec.RSAKey.RSAPrimePIV, err = makeRandom(16); err != nil { return } paddedPrimeP := padding.AddPadding(rsaPriv.Primes[0].Bytes()) if newRec.RSAKey.RSAPrimeP, err = encryptCBC(paddedPrimeP, newRec.RSAKey.RSAPrimePIV, passKey); err != nil { return } if newRec.RSAKey.RSAPrimeQIV, err = makeRandom(16); err != nil { return } paddedPrimeQ := padding.AddPadding(rsaPriv.Primes[1].Bytes()) newRec.RSAKey.RSAPrimeQ, err = encryptCBC(paddedPrimeQ, newRec.RSAKey.RSAPrimeQIV, passKey) return }
// 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 EncryptedFile encrypted.Version = DEFAULT_VERSION if encrypted.VaultId, err = passvault.GetVaultId(); err != nil { return } // Generate random IV and encryption key ivBytes, err := 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 := 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 { // only wrap key with RSA key if found if singleWrappedKey.aesKey, err = 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 } mac := hmac.New(sha1.New, hmacKey) mac.Write(encrypted.Data) encrypted.Signature = mac.Sum(nil) return json.Marshal(encrypted) }