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.
|
||||
func canonicalizeAndTrim(text string) string {
|
||||
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
|
||||
}
|
||||
|
|
|
|||
145
helper/helper.go
145
helper/helper.go
|
|
@ -52,23 +52,13 @@ func EncryptMessageArmored(key, plaintext string) (string, error) {
|
|||
func EncryptSignMessageArmored(
|
||||
publicKey, privateKey string, passphrase []byte, plaintext string,
|
||||
) (ciphertext string, err error) {
|
||||
var publicKeyObj, privateKeyObj, unlockedKeyObj *crypto.Key
|
||||
var privateKeyObj, unlockedKeyObj *crypto.Key
|
||||
var publicKeyRing, privateKeyRing *crypto.KeyRing
|
||||
var pgpMessage *crypto.PGPMessage
|
||||
|
||||
var message = crypto.NewPlainMessageFromString(plaintext)
|
||||
|
||||
if publicKeyObj, err = crypto.NewKeyFromArmored(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 {
|
||||
if publicKeyRing, err = createPublicKeyRing(publicKey); err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
|
|
@ -116,22 +106,12 @@ func DecryptMessageArmored(
|
|||
func DecryptVerifyMessageArmored(
|
||||
publicKey, privateKey string, passphrase []byte, ciphertext string,
|
||||
) (plaintext string, err error) {
|
||||
var publicKeyObj, privateKeyObj, unlockedKeyObj *crypto.Key
|
||||
var privateKeyObj, unlockedKeyObj *crypto.Key
|
||||
var publicKeyRing, privateKeyRing *crypto.KeyRing
|
||||
var pgpMessage *crypto.PGPMessage
|
||||
var message *crypto.PlainMessage
|
||||
|
||||
if publicKeyObj, err = crypto.NewKeyFromArmored(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 {
|
||||
if publicKeyRing, err = createPublicKeyRing(publicKey); err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
|
|
@ -256,20 +236,79 @@ func DecryptVerifyArmoredDetached(
|
|||
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) {
|
||||
publicKey, err := crypto.NewKeyFromArmored(key)
|
||||
if publicKey.IsPrivate() {
|
||||
publicKey, err = publicKey.ToPublic()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
publicKeyRing, err := crypto.NewKeyRing(publicKey)
|
||||
publicKeyRing, err := createPublicKeyRing(key)
|
||||
|
||||
if err != nil {
|
||||
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) {
|
||||
var publicKeyObj *crypto.Key
|
||||
var publicKeyRing *crypto.KeyRing
|
||||
var detachedSignature *crypto.PGPSignature
|
||||
|
||||
// We prepare the public key for signature verification
|
||||
if publicKeyObj, err = crypto.NewKeyFromArmored(publicKey); err != nil {
|
||||
return false, err
|
||||
}
|
||||
if publicKeyObj.IsPrivate() {
|
||||
publicKeyObj, err = publicKeyObj.ToPublic()
|
||||
publicKeyRing, err = createPublicKeyRing(publicKey)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
}
|
||||
if publicKeyRing, err = crypto.NewKeyRing(publicKeyObj); err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
// We verify the signature
|
||||
if detachedSignature, err = crypto.NewPGPSignatureFromArmored(armoredSignature); err != nil {
|
||||
|
|
@ -418,3 +449,23 @@ func decryptAttachment(
|
|||
|
||||
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")
|
||||
}
|
||||
}
|
||||
|
||||
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