Additional helpers for iOS drive (#78)
* add tests Co-authored-by: wussler <aron@wussler.it> Co-authored-by: marin thiercelin <marin.thiercelin@pm.me>
This commit is contained in:
parent
64b3b45404
commit
55c4bd994d
5 changed files with 174 additions and 48 deletions
|
|
@ -85,6 +85,6 @@ func VerifyCleartextMessage(keyRing *crypto.KeyRing, armored string, verifyTime
|
||||||
// canonicalizeAndTrim alters a string canonicalizing and trimming the newlines.
|
// canonicalizeAndTrim alters a string canonicalizing and trimming the newlines.
|
||||||
func canonicalizeAndTrim(text string) string {
|
func canonicalizeAndTrim(text string) string {
|
||||||
text = internal.TrimNewlines(text)
|
text = internal.TrimNewlines(text)
|
||||||
text = strings.Replace(strings.Replace(text, "\r\n", "\n", -1), "\n", "\r\n", -1)
|
text = strings.ReplaceAll(strings.ReplaceAll(text, "\r\n", "\n"), "\n", "\r\n")
|
||||||
return text
|
return text
|
||||||
}
|
}
|
||||||
|
|
|
||||||
145
helper/helper.go
145
helper/helper.go
|
|
@ -52,23 +52,13 @@ func EncryptMessageArmored(key, plaintext string) (string, error) {
|
||||||
func EncryptSignMessageArmored(
|
func EncryptSignMessageArmored(
|
||||||
publicKey, privateKey string, passphrase []byte, plaintext string,
|
publicKey, privateKey string, passphrase []byte, plaintext string,
|
||||||
) (ciphertext string, err error) {
|
) (ciphertext string, err error) {
|
||||||
var publicKeyObj, privateKeyObj, unlockedKeyObj *crypto.Key
|
var privateKeyObj, unlockedKeyObj *crypto.Key
|
||||||
var publicKeyRing, privateKeyRing *crypto.KeyRing
|
var publicKeyRing, privateKeyRing *crypto.KeyRing
|
||||||
var pgpMessage *crypto.PGPMessage
|
var pgpMessage *crypto.PGPMessage
|
||||||
|
|
||||||
var message = crypto.NewPlainMessageFromString(plaintext)
|
var message = crypto.NewPlainMessageFromString(plaintext)
|
||||||
|
|
||||||
if publicKeyObj, err = crypto.NewKeyFromArmored(publicKey); err != nil {
|
if publicKeyRing, err = createPublicKeyRing(publicKey); err != nil {
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
if publicKeyObj.IsPrivate() {
|
|
||||||
publicKeyObj, err = publicKeyObj.ToPublic()
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if publicKeyRing, err = crypto.NewKeyRing(publicKeyObj); err != nil {
|
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -116,22 +106,12 @@ func DecryptMessageArmored(
|
||||||
func DecryptVerifyMessageArmored(
|
func DecryptVerifyMessageArmored(
|
||||||
publicKey, privateKey string, passphrase []byte, ciphertext string,
|
publicKey, privateKey string, passphrase []byte, ciphertext string,
|
||||||
) (plaintext string, err error) {
|
) (plaintext string, err error) {
|
||||||
var publicKeyObj, privateKeyObj, unlockedKeyObj *crypto.Key
|
var privateKeyObj, unlockedKeyObj *crypto.Key
|
||||||
var publicKeyRing, privateKeyRing *crypto.KeyRing
|
var publicKeyRing, privateKeyRing *crypto.KeyRing
|
||||||
var pgpMessage *crypto.PGPMessage
|
var pgpMessage *crypto.PGPMessage
|
||||||
var message *crypto.PlainMessage
|
var message *crypto.PlainMessage
|
||||||
|
|
||||||
if publicKeyObj, err = crypto.NewKeyFromArmored(publicKey); err != nil {
|
if publicKeyRing, err = createPublicKeyRing(publicKey); err != nil {
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
if publicKeyObj.IsPrivate() {
|
|
||||||
publicKeyObj, err = publicKeyObj.ToPublic()
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if publicKeyRing, err = crypto.NewKeyRing(publicKeyObj); err != nil {
|
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -256,20 +236,79 @@ func DecryptVerifyArmoredDetached(
|
||||||
return message.GetBinary(), nil
|
return message.GetBinary(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// EncryptAttachmentWithKey encrypts a binary file
|
||||||
|
// Using a given armored public key.
|
||||||
|
func EncryptAttachmentWithKey(
|
||||||
|
publicKey string,
|
||||||
|
filename string,
|
||||||
|
plainData []byte,
|
||||||
|
) (message *crypto.PGPSplitMessage, err error) {
|
||||||
|
publicKeyRing, err := createPublicKeyRing(publicKey)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return EncryptAttachment(plainData, filename, publicKeyRing)
|
||||||
|
}
|
||||||
|
|
||||||
|
// DecryptAttachmentWithKey decrypts a binary file
|
||||||
|
// Using a given armored private key and its passphrase.
|
||||||
|
func DecryptAttachmentWithKey(
|
||||||
|
privateKey string,
|
||||||
|
passphrase, keyPacket, dataPacket []byte,
|
||||||
|
) (attachment []byte, err error) {
|
||||||
|
message, err := decryptAttachment(privateKey, passphrase, keyPacket, dataPacket)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return message.GetBinary(), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// EncryptSessionKey encrypts a session key
|
||||||
|
// using a given armored public key.
|
||||||
|
func EncryptSessionKey(
|
||||||
|
publicKey string,
|
||||||
|
sessionKey *crypto.SessionKey,
|
||||||
|
) (encryptedSessionKey []byte, err error) {
|
||||||
|
publicKeyRing, err := createPublicKeyRing(publicKey)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
encryptedSessionKey, err = publicKeyRing.EncryptSessionKey(sessionKey)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// DecryptSessionKey decrypts a session key
|
||||||
|
// using a given armored private key
|
||||||
|
// and its passphrase.
|
||||||
|
func DecryptSessionKey(
|
||||||
|
privateKey string,
|
||||||
|
passphrase, encryptedSessionKey []byte,
|
||||||
|
) (sessionKey *crypto.SessionKey, err error) {
|
||||||
|
privateKeyObj, err := crypto.NewKeyFromArmored(privateKey)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
privateKeyUnlocked, err := privateKeyObj.Unlock(passphrase)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
defer privateKeyUnlocked.ClearPrivateParams()
|
||||||
|
|
||||||
|
privateKeyRing, err := crypto.NewKeyRing(privateKeyUnlocked)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
sessionKey, err = privateKeyRing.DecryptSessionKey(encryptedSessionKey)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
func encryptMessageArmored(key string, message *crypto.PlainMessage) (string, error) {
|
func encryptMessageArmored(key string, message *crypto.PlainMessage) (string, error) {
|
||||||
publicKey, err := crypto.NewKeyFromArmored(key)
|
publicKeyRing, err := createPublicKeyRing(key)
|
||||||
if publicKey.IsPrivate() {
|
|
||||||
publicKey, err = publicKey.ToPublic()
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
|
|
||||||
publicKeyRing, err := crypto.NewKeyRing(publicKey)
|
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
|
|
@ -363,22 +402,14 @@ func signDetachedArmored(privateKey string, passphrase []byte, message *crypto.P
|
||||||
}
|
}
|
||||||
|
|
||||||
func verifyDetachedArmored(publicKey string, message *crypto.PlainMessage, armoredSignature string) (check bool, err error) {
|
func verifyDetachedArmored(publicKey string, message *crypto.PlainMessage, armoredSignature string) (check bool, err error) {
|
||||||
var publicKeyObj *crypto.Key
|
|
||||||
var publicKeyRing *crypto.KeyRing
|
var publicKeyRing *crypto.KeyRing
|
||||||
var detachedSignature *crypto.PGPSignature
|
var detachedSignature *crypto.PGPSignature
|
||||||
|
|
||||||
// We prepare the public key for signature verification
|
// We prepare the public key for signature verification
|
||||||
if publicKeyObj, err = crypto.NewKeyFromArmored(publicKey); err != nil {
|
publicKeyRing, err = createPublicKeyRing(publicKey)
|
||||||
return false, err
|
|
||||||
}
|
|
||||||
if publicKeyObj.IsPrivate() {
|
|
||||||
publicKeyObj, err = publicKeyObj.ToPublic()
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if publicKeyRing, err = crypto.NewKeyRing(publicKeyObj); err != nil {
|
|
||||||
return false, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// We verify the signature
|
// We verify the signature
|
||||||
if detachedSignature, err = crypto.NewPGPSignatureFromArmored(armoredSignature); err != nil {
|
if detachedSignature, err = crypto.NewPGPSignatureFromArmored(armoredSignature); err != nil {
|
||||||
|
|
@ -418,3 +449,23 @@ func decryptAttachment(
|
||||||
|
|
||||||
return message, nil
|
return message, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func createPublicKeyRing(
|
||||||
|
publicKey string,
|
||||||
|
) (publicKeyRing *crypto.KeyRing, err error) {
|
||||||
|
publicKeyObj, err := crypto.NewKeyFromArmored(publicKey)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if publicKeyObj.IsPrivate() {
|
||||||
|
publicKeyObj, err = publicKeyObj.ToPublic()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
publicKeyRing, err = crypto.NewKeyRing(publicKeyObj)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -216,3 +216,78 @@ func TestEncryptSignArmoredDetached(t *testing.T) {
|
||||||
t.Fatal("Expected an error while decrypting and verifying with a wrong signature")
|
t.Fatal("Expected an error while decrypting and verifying with a wrong signature")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestEncryptDecryptAttachmenWithKey(t *testing.T) {
|
||||||
|
plainData := []byte("Secret message")
|
||||||
|
privateKeyString := readTestFile("keyring_privateKey", false)
|
||||||
|
privateKey, err := crypto.NewKeyFromArmored(privateKeyString)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal("Error reading the test private key: ", err)
|
||||||
|
}
|
||||||
|
publicKeyString, err := privateKey.GetArmoredPublicKey()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal("Error reading the test public key: ", err)
|
||||||
|
}
|
||||||
|
pgpSplitMessage, err := EncryptAttachmentWithKey(
|
||||||
|
publicKeyString,
|
||||||
|
"test_filename",
|
||||||
|
plainData,
|
||||||
|
)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal("Expected no error while encrypting, got:", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
decrypted, err := DecryptAttachmentWithKey(
|
||||||
|
privateKeyString,
|
||||||
|
testMailboxPassword,
|
||||||
|
pgpSplitMessage.KeyPacket,
|
||||||
|
pgpSplitMessage.DataPacket,
|
||||||
|
)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal("Expected no error while decrypting, got:", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !bytes.Equal(decrypted, plainData) {
|
||||||
|
t.Error("Decrypted attachment is not equal to the original attachment")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestEncryptDecryptSessionKey(t *testing.T) {
|
||||||
|
privateKeyString := readTestFile("keyring_privateKey", false)
|
||||||
|
privateKey, err := crypto.NewKeyFromArmored(privateKeyString)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal("Error reading the test private key: ", err)
|
||||||
|
}
|
||||||
|
publicKeyString, err := privateKey.GetArmoredPublicKey()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal("Error reading the test public key: ", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
sessionKey, err := crypto.GenerateSessionKeyAlgo("aes256")
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal("Expected no error while generating the session key, got:", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
encrypted, err := EncryptSessionKey(publicKeyString, sessionKey)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal("Expected no error while encrypting session key, got:", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
decryptedSessionKey, err := DecryptSessionKey(
|
||||||
|
privateKeyString,
|
||||||
|
testMailboxPassword,
|
||||||
|
encrypted,
|
||||||
|
)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal("Expected no error while decrypting session key, got:", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if decryptedSessionKey.GetBase64Key() != sessionKey.GetBase64Key() {
|
||||||
|
t.Error("Decrypted session key is not equal to the original session key")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue