Optimize encrypt attachment

This commit is contained in:
Kay Lukas 2018-10-26 15:08:49 +02:00
parent 0456595f68
commit 9dfb46fe45
24 changed files with 726 additions and 94 deletions

View file

@ -14,11 +14,11 @@ ln -s . vendor/src
# if [ ${CHECK} -eq "1" ]; then
printf "\e[0;32mStart Building iOS framework .. Location: ${IOS_OUT} \033[0m\n\n"
GOPATH="$SCRIPT_LOCATION:$SCRIPT_LOCATION/vendor:$GOPATH" gomobile bind -target ios -o ${IOS_OUT}/pmcrypto.framework gitlab.com/ProtonMail/go-pm-crypto/crypto gitlab.com/ProtonMail/go-pm-crypto/armor gitlab.com/ProtonMail/go-pm-crypto/constants gitlab.com/ProtonMail/go-pm-crypto/key gitlab.com/ProtonMail/go-pm-crypto/models
GOPATH="$SCRIPT_LOCATION:$SCRIPT_LOCATION/vendor:$GOPATH" gomobile bind -target ios -o ${IOS_OUT}/Crypto.framework -ldflags="-s -w" gitlab.com/ProtonMail/go-pm-crypto/crypto gitlab.com/ProtonMail/go-pm-crypto/armor gitlab.com/ProtonMail/go-pm-crypto/constants gitlab.com/ProtonMail/go-pm-crypto/key gitlab.com/ProtonMail/go-pm-crypto/models
printf "\e[0;32mStart Building Android lib .. Location: ${ANDROID_OUT} \033[0m\n\n"
GOPATH="$SCRIPT_LOCATION:$SCRIPT_LOCATION/vendor:$GOPATH" gomobile bind -target android -javapkg com.proton.pmcrypto -o ${ANDROID_OUT}/pmcrypto.aar gitlab.com/ProtonMail/go-pm-crypto/crypto gitlab.com/ProtonMail/go-pm-crypto/armor gitlab.com/ProtonMail/go-pm-crypto/constants gitlab.com/ProtonMail/go-pm-crypto/key gitlab.com/ProtonMail/go-pm-crypto/models
GOPATH="$SCRIPT_LOCATION:$SCRIPT_LOCATION/vendor:$GOPATH" gomobile bind -target android -javapkg com.proton.pmcrypto -o ${ANDROID_OUT}/pmcrypto.aar -ldflags="-s -w" gitlab.com/ProtonMail/go-pm-crypto/crypto gitlab.com/ProtonMail/go-pm-crypto/armor gitlab.com/ProtonMail/go-pm-crypto/constants gitlab.com/ProtonMail/go-pm-crypto/key gitlab.com/ProtonMail/go-pm-crypto/models
printf "\e[0;32mInstalling frameworks. \033[0m\n\n"

32
debug_build.sh Executable file
View file

@ -0,0 +1,32 @@
#!/bin/bash
SCRIPT_LOCATION=$(cd $(dirname $0);echo $PWD)
BUILD_PATH="build"
OUTPUT_PATH="dist"
ANDROID_OUT=${OUTPUT_PATH}/"Android"
IOS_OUT=${OUTPUT_PATH}/"iOS"
rm -rf $BUILD_PATH
mkdir -p $BUILD_PATH
mkdir -p $ANDROID_OUT
mkdir -p $IOS_OUT
ln -s . vendor/src
# CHECK="${1-0}"
# if [ ${CHECK} -eq "1" ]; then
printf "\e[0;32mStart Building iOS framework .. Location: ${IOS_OUT} \033[0m\n\n"
GOPATH="$SCRIPT_LOCATION:$SCRIPT_LOCATION/vendor:$GOPATH" gomobile bind -target ios -o ${IOS_OUT}/pmcrypto.framework gitlab.com/ProtonMail/go-pm-crypto/crypto gitlab.com/ProtonMail/go-pm-crypto/armor gitlab.com/ProtonMail/go-pm-crypto/constants gitlab.com/ProtonMail/go-pm-crypto/key gitlab.com/ProtonMail/go-pm-crypto/models
printf "\e[0;32mStart Building Android lib .. Location: ${ANDROID_OUT} \033[0m\n\n"
GOPATH="$SCRIPT_LOCATION:$SCRIPT_LOCATION/vendor:$GOPATH" gomobile bind -target android -javapkg com.proton.pmcrypto -o ${OUTPUT_PATH}/pmcrypto.aar gitlab.com/ProtonMail/go-pm-crypto/crypto gitlab.com/ProtonMail/go-pm-crypto/armor gitlab.com/ProtonMail/go-pm-crypto/constants gitlab.com/ProtonMail/go-pm-crypto/key gitlab.com/ProtonMail/go-pm-crypto/models
printf "\e[0;32mInstalling frameworks. \033[0m\n\n"
unlink vendor/src
printf "\e[0;32mAll Done. \033[0m\n\n"

Binary file not shown.

1
dist/iOS/Crypto.framework/Crypto vendored Symbolic link
View file

@ -0,0 +1 @@
Versions/Current/Crypto

1
dist/iOS/Crypto.framework/Headers vendored Symbolic link
View file

@ -0,0 +1 @@
Versions/Current/Headers

1
dist/iOS/Crypto.framework/Modules vendored Symbolic link
View file

@ -0,0 +1 @@
Versions/Current/Modules

1
dist/iOS/Crypto.framework/Resources vendored Symbolic link
View file

@ -0,0 +1 @@
Versions/Current/Resources

Binary file not shown.

View file

@ -0,0 +1,42 @@
// Objective-C API for talking to gitlab.com/ProtonMail/go-pm-crypto/armor Go package.
// gobind -lang=objc gitlab.com/ProtonMail/go-pm-crypto/armor
//
// File is generated by gobind. Do not edit.
#ifndef __Armor_H__
#define __Armor_H__
@import Foundation;
#include "Universe.objc.h"
#include "Models.objc.h"
FOUNDATION_EXPORT NSString* const ArmorARMOR_HEADER_COMMENT;
FOUNDATION_EXPORT NSString* const ArmorARMOR_HEADER_VERSION;
FOUNDATION_EXPORT NSString* const ArmorMESSAGE_HEADER;
FOUNDATION_EXPORT NSString* const ArmorPRIVATE_KEY_HEADER;
FOUNDATION_EXPORT NSString* const ArmorPUBLIC_KEY_HEADER;
/**
* ArmorKey make bytes input key to armor format
*/
FOUNDATION_EXPORT NSString* ArmorArmorKey(NSData* input, NSError** error);
/**
* ArmorWithType make bytes input to armor format
*/
FOUNDATION_EXPORT NSString* ArmorArmorWithType(NSData* input, NSString* armorType, NSError** error);
/**
* ReadClearSignedMessage read clear message from a clearsign package
*/
FOUNDATION_EXPORT NSString* ArmorReadClearSignedMessage(NSString* signedMessage, NSError** error);
FOUNDATION_EXPORT ModelsEncryptedSplit* ArmorSplitArmor(NSString* encrypted, NSError** error);
/**
* Unarmor an armored key to bytes key
*/
FOUNDATION_EXPORT NSData* ArmorUnarmor(NSString* input, NSError** error);
#endif

View file

@ -0,0 +1,15 @@
// Objective-C API for talking to gitlab.com/ProtonMail/go-pm-crypto/constants Go package.
// gobind -lang=objc gitlab.com/ProtonMail/go-pm-crypto/constants
//
// File is generated by gobind. Do not edit.
#ifndef __Constants_H__
#define __Constants_H__
@import Foundation;
#include "Universe.objc.h"
FOUNDATION_EXPORT NSString* const ConstantsVERSION;
#endif

View file

@ -0,0 +1,21 @@
// Objective-C API for talking to the following Go packages
//
// gitlab.com/ProtonMail/go-pm-crypto/crypto
// gitlab.com/ProtonMail/go-pm-crypto/armor
// gitlab.com/ProtonMail/go-pm-crypto/constants
// gitlab.com/ProtonMail/go-pm-crypto/key
// gitlab.com/ProtonMail/go-pm-crypto/models
//
// File is generated by gomobile bind. Do not edit.
#ifndef __Crypto_FRAMEWORK_H__
#define __Crypto_FRAMEWORK_H__
#include "Crypto.objc.h"
#include "Armor.objc.h"
#include "Constants.objc.h"
#include "Key.objc.h"
#include "Models.objc.h"
#include "universe.objc.h"
#endif

View file

@ -0,0 +1,166 @@
// Objective-C API for talking to gitlab.com/ProtonMail/go-pm-crypto/crypto Go package.
// gobind -lang=objc gitlab.com/ProtonMail/go-pm-crypto/crypto
//
// File is generated by gobind. Do not edit.
#ifndef __Crypto_H__
#define __Crypto_H__
@import Foundation;
#include "Universe.objc.h"
#include "Armor.objc.h"
#include "Models.objc.h"
@class CryptoPmCrypto;
@class CryptoSignatureCollector;
@protocol CryptoMIMECallbacks;
@class CryptoMIMECallbacks;
@protocol CryptoMIMECallbacks <NSObject>
- (void)onAttachment:(NSString*)headers data:(NSData*)data;
- (void)onBody:(NSString*)body mimetype:(NSString*)mimetype;
- (void)onEncryptedHeaders:(NSString*)headers;
- (void)onError:(NSError*)err;
- (void)onVerified:(long)verified;
@end
/**
* PmCrypto structure to manage multiple address keys and user keys
Called PGP crypto because it cannot have the same name as the package by gomobile's ridiculous rules.
*/
@interface CryptoPmCrypto : NSObject <goSeqRefInterface> {
}
@property(strong, readonly) id _ref;
- (instancetype)initWithRef:(id)ref;
- (instancetype)init;
- (NSString*)checkKey:(NSString*)pubKey error:(NSError**)error;
- (NSData*)decryptAttachment:(NSData*)keyPacket dataPacket:(NSData*)dataPacket privateKey:(NSString*)privateKey passphrase:(NSString*)passphrase error:(NSError**)error;
- (NSData*)decryptAttachmentBinKey:(NSData*)keyPacket dataPacket:(NSData*)dataPacket privateKeys:(NSData*)privateKeys passphrase:(NSString*)passphrase error:(NSError**)error;
- (NSData*)decryptAttachmentWithPassword:(NSData*)keyPacket dataPacket:(NSData*)dataPacket password:(NSString*)password error:(NSError**)error;
- (void)decryptMIMEMessage:(NSString*)encryptedText verifierKey:(NSData*)verifierKey privateKeys:(NSData*)privateKeys passphrase:(NSString*)passphrase callbacks:(id<CryptoMIMECallbacks>)callbacks verifyTime:(int64_t)verifyTime;
- (NSString*)decryptMessage:(NSString*)encryptedText privateKey:(NSString*)privateKey passphrase:(NSString*)passphrase error:(NSError**)error;
- (NSString*)decryptMessageBinKey:(NSString*)encryptedText privateKey:(NSData*)privateKey passphrase:(NSString*)passphrase error:(NSError**)error;
- (ModelsDecryptSignedVerify*)decryptMessageVerify:(NSString*)encryptedText verifierKey:(NSString*)verifierKey privateKey:(NSString*)privateKey passphrase:(NSString*)passphrase verifyTime:(int64_t)verifyTime error:(NSError**)error;
- (ModelsDecryptSignedVerify*)decryptMessageVerifyBinKey:(NSString*)encryptedText verifierKey:(NSData*)verifierKey privateKey:(NSString*)privateKey passphrase:(NSString*)passphrase verifyTime:(int64_t)verifyTime error:(NSError**)error;
- (ModelsDecryptSignedVerify*)decryptMessageVerifyBinKeyPrivBinKeys:(NSString*)encryptedText verifierKey:(NSData*)verifierKey privateKeys:(NSData*)privateKeys passphrase:(NSString*)passphrase verifyTime:(int64_t)verifyTime error:(NSError**)error;
- (ModelsDecryptSignedVerify*)decryptMessageVerifyPrivBinKeys:(NSString*)encryptedText verifierKey:(NSString*)verifierKey privateKeys:(NSData*)privateKeys passphrase:(NSString*)passphrase verifyTime:(int64_t)verifyTime error:(NSError**)error;
- (NSString*)decryptMessageWithPassword:(NSString*)encrypted password:(NSString*)password error:(NSError**)error;
- (ModelsEncryptedSplit*)encryptAttachment:(NSData*)plainData fileName:(NSString*)fileName publicKey:(NSString*)publicKey error:(NSError**)error;
- (ModelsEncryptedSplit*)encryptAttachmentBinKey:(NSData*)plainData fileName:(NSString*)fileName publicKey:(NSData*)publicKey error:(NSError**)error;
- (NSString*)encryptAttachmentWithPassword:(NSData*)plainData password:(NSString*)password error:(NSError**)error;
- (NSString*)encryptMessage:(NSString*)plainText publicKey:(NSString*)publicKey privateKey:(NSString*)privateKey passphrase:(NSString*)passphrase trim:(BOOL)trim error:(NSError**)error;
- (NSString*)encryptMessageBinKey:(NSString*)plainText publicKey:(NSData*)publicKey privateKey:(NSString*)privateKey passphrase:(NSString*)passphrase trim:(BOOL)trim error:(NSError**)error;
- (NSString*)encryptMessageWithPassword:(NSString*)plainText password:(NSString*)password error:(NSError**)error;
- (NSString*)generateKey:(NSString*)userName domain:(NSString*)domain passphrase:(NSString*)passphrase keyType:(NSString*)keyType bits:(long)bits error:(NSError**)error;
- (NSString*)generateRSAKeyWithPrimes:(NSString*)userName domain:(NSString*)domain passphrase:(NSString*)passphrase bits:(long)bits primeone:(NSData*)primeone primetwo:(NSData*)primetwo primethree:(NSData*)primethree primefour:(NSData*)primefour error:(NSError**)error;
/**
* GetSessionFromKeyPacket get session key no encoding in and out
*/
- (ModelsSessionSplit*)getSessionFromKeyPacket:(NSData*)keyPackage privateKey:(NSString*)privateKey passphrase:(NSString*)passphrase error:(NSError**)error;
/**
* GetSessionFromKeyPacketBinkeys get session key no encoding in and out
*/
- (ModelsSessionSplit*)getSessionFromKeyPacketBinkeys:(NSData*)keyPackage privateKey:(NSData*)privateKey passphrase:(NSString*)passphrase error:(NSError**)error;
/**
* GetSessionFromSymmetricPacket ...
*/
- (ModelsSessionSplit*)getSessionFromSymmetricPacket:(NSData*)keyPackage password:(NSString*)password error:(NSError**)error;
/**
* GetTime get latest cached time
*/
- (int64_t)getTime;
- (BOOL)isKeyExpired:(NSString*)publicKey ret0_:(BOOL*)ret0_ error:(NSError**)error;
- (BOOL)isKeyExpiredBin:(NSData*)publicKey ret0_:(BOOL*)ret0_ error:(NSError**)error;
/**
* KeyPacketWithPublicKey ...
*/
- (NSData*)keyPacketWithPublicKey:(ModelsSessionSplit*)sessionSplit publicKey:(NSString*)publicKey error:(NSError**)error;
/**
* KeyPacketWithPublicKeyBin ...
*/
- (NSData*)keyPacketWithPublicKeyBin:(ModelsSessionSplit*)sessionSplit publicKey:(NSData*)publicKey error:(NSError**)error;
/**
* RandomToken ...
*/
- (NSData*)randomToken:(NSError**)error;
/**
* RandomTokenWith ...
*/
- (NSData*)randomTokenWith:(long)size error:(NSError**)error;
/**
* SignBinDetached sign bin data
*/
- (NSString*)signBinDetached:(NSData*)plainData privateKey:(NSString*)privateKey passphrase:(NSString*)passphrase error:(NSError**)error;
/**
* SignBinDetachedBinKey ...
*/
- (NSString*)signBinDetachedBinKey:(NSData*)plainData privateKey:(NSData*)privateKey passphrase:(NSString*)passphrase error:(NSError**)error;
/**
* SignTextDetached sign detached text type
*/
- (NSString*)signTextDetached:(NSString*)plainText privateKey:(NSString*)privateKey passphrase:(NSString*)passphrase trim:(BOOL)trim error:(NSError**)error;
/**
* SignTextDetachedBinKey ...
*/
- (NSString*)signTextDetachedBinKey:(NSString*)plainText privateKey:(NSData*)privateKey passphrase:(NSString*)passphrase trim:(BOOL)trim error:(NSError**)error;
/**
* SymmetricKeyPacketWithPassword ...
*/
- (NSData*)symmetricKeyPacketWithPassword:(ModelsSessionSplit*)sessionSplit password:(NSString*)password error:(NSError**)error;
- (NSString*)updatePrivateKeyPassphrase:(NSString*)privateKey oldPassphrase:(NSString*)oldPassphrase newPassphrase:(NSString*)newPassphrase error:(NSError**)error;
/**
* UpdateTime update cached time
*/
- (void)updateTime:(int64_t)newTime;
/**
* VerifyBinSignDetached ...
*/
- (BOOL)verifyBinSignDetached:(NSString*)signature plainData:(NSData*)plainData publicKey:(NSString*)publicKey verifyTime:(int64_t)verifyTime ret0_:(BOOL*)ret0_ error:(NSError**)error;
/**
* VerifyBinSignDetachedBinKey ...
*/
- (BOOL)verifyBinSignDetachedBinKey:(NSString*)signature plainData:(NSData*)plainData publicKey:(NSData*)publicKey verifyTime:(int64_t)verifyTime ret0_:(BOOL*)ret0_ error:(NSError**)error;
/**
* VerifyTextSignDetached ...
*/
- (BOOL)verifyTextSignDetached:(NSString*)signature plainText:(NSString*)plainText publicKey:(NSString*)publicKey verifyTime:(int64_t)verifyTime ret0_:(BOOL*)ret0_ error:(NSError**)error;
/**
* VerifyTextSignDetachedBinKey ...
*/
- (BOOL)verifyTextSignDetachedBinKey:(NSString*)signature plainText:(NSString*)plainText publicKey:(NSData*)publicKey verifyTime:(int64_t)verifyTime ret0_:(BOOL*)ret0_ error:(NSError**)error;
@end
@interface CryptoSignatureCollector : NSObject <goSeqRefInterface> {
}
@property(strong, readonly) id _ref;
- (instancetype)initWithRef:(id)ref;
- (instancetype)init;
// skipped method SignatureCollector.Accept with unsupported parameter or return types
- (NSString*)getSignature;
@end
@class CryptoMIMECallbacks;
/**
* define call back interface
*/
@interface CryptoMIMECallbacks : NSObject <goSeqRefInterface, CryptoMIMECallbacks> {
}
@property(strong, readonly) id _ref;
- (instancetype)initWithRef:(id)ref;
- (void)onAttachment:(NSString*)headers data:(NSData*)data;
- (void)onBody:(NSString*)body mimetype:(NSString*)mimetype;
/**
* Encrypted headers can be an attachment and thus be placed at the end of the mime structure
*/
- (void)onEncryptedHeaders:(NSString*)headers;
- (void)onError:(NSError*)err;
- (void)onVerified:(long)verified;
@end
#endif

View file

@ -0,0 +1,39 @@
// Objective-C API for talking to gitlab.com/ProtonMail/go-pm-crypto/key Go package.
// gobind -lang=objc gitlab.com/ProtonMail/go-pm-crypto/key
//
// File is generated by gobind. Do not edit.
#ifndef __Key_H__
#define __Key_H__
@import Foundation;
#include "Universe.objc.h"
#include "Armor.objc.h"
/**
* CheckPassphrase check is private key passphrase ok
*/
FOUNDATION_EXPORT BOOL KeyCheckPassphrase(NSString* privateKey, NSString* passphrase);
/**
* GetFingerprint get a armored public key fingerprint
*/
FOUNDATION_EXPORT NSString* KeyGetFingerprint(NSString* publicKey, NSError** error);
/**
* GetFingerprintBinKey get a unarmored public key fingerprint
*/
FOUNDATION_EXPORT NSString* KeyGetFingerprintBinKey(NSData* publicKey, NSError** error);
/**
* PublicKey get a public key from a private key
*/
FOUNDATION_EXPORT NSString* KeyPublicKey(NSString* privateKey, NSError** error);
/**
* PublicKeyBinOut get a public key from a private key
*/
FOUNDATION_EXPORT NSData* KeyPublicKeyBinOut(NSString* privateKey, NSError** error);
#endif

View file

@ -0,0 +1,91 @@
// Objective-C API for talking to gitlab.com/ProtonMail/go-pm-crypto/models Go package.
// gobind -lang=objc gitlab.com/ProtonMail/go-pm-crypto/models
//
// File is generated by gobind. Do not edit.
#ifndef __Models_H__
#define __Models_H__
@import Foundation;
#include "Universe.objc.h"
@class ModelsDecryptSignedVerify;
@class ModelsEncryptedSigned;
@class ModelsEncryptedSplit;
@class ModelsSessionSplit;
/**
* DecryptSignedVerify decrypt_sign_verify
*/
@interface ModelsDecryptSignedVerify : NSObject <goSeqRefInterface> {
}
@property(strong, readonly) id _ref;
- (instancetype)initWithRef:(id)ref;
- (instancetype)init;
/**
* clear text
*/
- (NSString*)plaintext;
- (void)setPlaintext:(NSString*)v;
/**
* bitmask verify status : 0
*/
- (long)verify;
- (void)setVerify:(long)v;
/**
* error message if verify failed
*/
- (NSString*)message;
- (void)setMessage:(NSString*)v;
@end
/**
* EncryptedSigned encrypt_sign_package
*/
@interface ModelsEncryptedSigned : NSObject <goSeqRefInterface> {
}
@property(strong, readonly) id _ref;
- (instancetype)initWithRef:(id)ref;
- (instancetype)init;
- (NSString*)encrypted;
- (void)setEncrypted:(NSString*)v;
- (NSString*)signature;
- (void)setSignature:(NSString*)v;
@end
/**
* EncryptedSplit when encrypt attachemt
*/
@interface ModelsEncryptedSplit : NSObject <goSeqRefInterface> {
}
@property(strong, readonly) id _ref;
- (instancetype)initWithRef:(id)ref;
- (instancetype)init;
- (NSData*)dataPacket;
- (void)setDataPacket:(NSData*)v;
- (NSData*)keyPacket;
- (void)setKeyPacket:(NSData*)v;
- (NSString*)algo;
- (void)setAlgo:(NSString*)v;
@end
/**
* SessionSplit split session
*/
@interface ModelsSessionSplit : NSObject <goSeqRefInterface> {
}
@property(strong, readonly) id _ref;
- (instancetype)initWithRef:(id)ref;
- (instancetype)init;
- (NSData*)session;
- (void)setSession:(NSData*)v;
- (NSString*)algo;
- (void)setAlgo:(NSString*)v;
@end
#endif

View file

@ -0,0 +1,35 @@
// Copyright 2015 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
#ifndef __GO_REF_HDR__
#define __GO_REF_HDR__
#include <Foundation/Foundation.h>
// GoSeqRef is an object tagged with an integer for passing back and
// forth across the language boundary. A GoSeqRef may represent either
// an instance of a Go object, or an Objective-C object passed to Go.
// The explicit allocation of a GoSeqRef is used to pin a Go object
// when it is passed to Objective-C. The Go seq package maintains a
// reference to the Go object in a map keyed by the refnum along with
// a reference count. When the reference count reaches zero, the Go
// seq package will clear the corresponding entry in the map.
@interface GoSeqRef : NSObject {
}
@property(readonly) int32_t refnum;
@property(strong) id obj; // NULL when representing a Go object.
// new GoSeqRef object to proxy a Go object. The refnum must be
// provided from Go side.
- (instancetype)initWithRefnum:(int32_t)refnum obj:(id)obj;
- (int32_t)incNum;
@end
@protocol goSeqRefInterface
-(GoSeqRef*) _ref;
@end
#endif

View file

@ -0,0 +1,28 @@
// Objective-C API for talking to Go package.
// gobind -lang=objc
//
// File is generated by gobind. Do not edit.
#ifndef __Universe_H__
#define __Universe_H__
@import Foundation;
@protocol Universeerror;
@class Universeerror;
@protocol Universeerror <NSObject>
- (NSString*)error;
@end
@class Universeerror;
@interface Universeerror : NSError <goSeqRefInterface, Universeerror> {
}
@property(strong, readonly) id _ref;
- (instancetype)initWithRef:(id)ref;
- (NSString*)error;
@end
#endif

View file

@ -0,0 +1,12 @@
framework module "Crypto" {
header "ref.h"
header "Crypto.objc.h"
header "Armor.objc.h"
header "Constants.objc.h"
header "Key.objc.h"
header "Models.objc.h"
header "universe.objc.h"
header "Crypto.h"
export *
}

View file

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
</dict>
</plist>

View file

@ -0,0 +1 @@
A

30
glide.lock generated
View file

@ -1,8 +1,20 @@
hash: 7169f4883725d9716bbd62ecee1f32d73e8529b4bb0989173826e986395afe6b
updated: 2018-10-24T18:02:15.233807+02:00
updated: 2018-10-25T13:47:24.679131+02:00
imports:
- name: github.com/alecthomas/template
version: a0175ee3bccc567396460bf5acd36800cb10c49c
subpackages:
- parse
- name: github.com/alecthomas/units
version: 2efee857e7cfd4f3d0138cc3cbb1b4966962b93a
- name: github.com/dustin/go-humanize
version: 9f541cc9db5d55bce703bd99987c9d5cb8eea45e
- name: github.com/konsorten/go-windows-terminal-sequences
version: 5c8c8bd35d3832f5d134ae1e1e375b69a4d25242
- name: github.com/mattn/go-zglob
version: 2ea3427bfa539cca900ca2768d8663ecc8a708c1
subpackages:
- fastwalk
- name: github.com/Sirupsen/logrus
version: 4fabf2fffcecfd47f802869b7b92d75e43c5a095
- name: golang.org/x/crypto
@ -33,7 +45,7 @@ imports:
- rsa
- ssh/terminal
- name: golang.org/x/sys
version: 5cd93ef61a7c8f0f858690154eb6de2e69415fa1
version: d989b31c87461dc8ab2f1cac6792814e27fadea9
subpackages:
- unix
- windows
@ -48,4 +60,16 @@ imports:
- name: proton/pmmime
version: 72b7b1bf2d1b491e1d003632a0fda41410b0bb59
repo: git@gitlab.protontech.ch:ProtonMail/go-pm-mime.git
testImports: []
testImports:
- name: github.com/davecgh/go-spew
version: d8f796af33cc11cb798c1aaeb27a4ebc5099927d
subpackages:
- spew
- name: github.com/pmezard/go-difflib
version: 792786c7400a136282c1664665ae0a8db921c6c2
subpackages:
- difflib
- name: github.com/stretchr/testify
version: 04af85275a5c7ac09d16bb3b9b2e751ed45154e5
subpackages:
- assert

View file

@ -4,13 +4,11 @@ import (
"bytes"
"errors"
"gitlab.com/ProtonMail/go-pm-crypto/internal"
"gitlab.com/ProtonMail/go-pm-crypto/models"
"golang.org/x/crypto/openpgp/armor"
"golang.org/x/crypto/openpgp/armor"
"golang.org/x/crypto/openpgp/clearsign"
"golang.org/x/crypto/openpgp/packet"
"io"
"io/ioutil"
)
"gitlab.com/ProtonMail/go-pm-crypto/models"
)
// ArmorKey make bytes input key to armor format
func ArmorKey(input []byte) (string, error) {
@ -50,80 +48,15 @@ func ReadClearSignedMessage(signedMessage string) (string, error) {
return string(modulusBlock.Bytes), nil
}
//SeparateKeyAndData ...
func SplitArmor(encrypted string) (*models.EncryptedSplit, error) {
var err error
encryptedRaw, err := Unarmor(encrypted)
b, err := internal.Unarmor(encrypted)
if err != nil {
return nil, err
}
encryptedReader := bytes.NewReader(encryptedRaw)
//kr *KeyRing, r io.Reader) (key *SymmetricKey, symEncryptedData []byte,
packets := packet.NewReader(encryptedReader)
outSplit := &models.EncryptedSplit{}
// Save encrypted key and signature apart
var ek *packet.EncryptedKey
// var decryptErr error
for {
var p packet.Packet
if p, err = packets.Next(); err == io.EOF {
err = nil
break
}
switch p := p.(type) {
case *packet.EncryptedKey:
// We got an encrypted key. Try to decrypt it with each available key
if ek != nil && ek.Key != nil {
break
}
ek = p
break
case *packet.SymmetricallyEncrypted:
var packetContents []byte
if packetContents, err = ioutil.ReadAll(p.Contents); err != nil {
return nil, err
}
encodedLength := encodedLength(len(packetContents) + 1)
var symEncryptedData []byte
symEncryptedData = append(symEncryptedData, byte(210))
symEncryptedData = append(symEncryptedData, encodedLength...)
symEncryptedData = append(symEncryptedData, byte(1))
symEncryptedData = append(symEncryptedData, packetContents...)
outSplit.DataPacket = symEncryptedData
break
}
split, err := internal.SplitPackets(b.Body, len(encrypted))
if err != nil {
return nil, err
}
var buf bytes.Buffer
ek.Serialize(&buf)
outSplit.KeyPacket = buf.Bytes()
return outSplit, err
}
//encode length based on 4.2.2. in the RFC
func encodedLength(length int) (b []byte) {
if length < 192 {
b = append(b, byte(length))
} else if length < 8384 {
length = length - 192
b = append(b, 192+byte(length>>8))
b = append(b, byte(length))
} else {
b = append(b, byte(255))
b = append(b, byte(length>>24))
b = append(b, byte(length>>16))
b = append(b, byte(length>>8))
b = append(b, byte(length))
}
return
}
return split, nil
}

View file

@ -11,17 +11,15 @@ import (
armorUtils "gitlab.com/ProtonMail/go-pm-crypto/armor"
"gitlab.com/ProtonMail/go-pm-crypto/internal"
"gitlab.com/ProtonMail/go-pm-crypto/models"
)
"sync"
)
//EncryptAttachmentBinKey ...
func (pm *PmCrypto) EncryptAttachmentBinKey(plainData []byte, fileName string, publicKey []byte) (*models.EncryptedSplit, error) {
var outBuf bytes.Buffer
w, err := armor.Encode(&outBuf, armorUtils.MESSAGE_HEADER, internal.ArmorHeaders)
if err != nil {
return nil, err
}
var wg sync.WaitGroup
// you can also add these one at
// a time if you need to
wg.Add(1)
pubKeyReader := bytes.NewReader(publicKey)
pubKeyEntries, err := openpgp.ReadKeyRing(pubKeyReader)
if err != nil {
@ -36,13 +34,26 @@ func (pm *PmCrypto) EncryptAttachmentBinKey(plainData []byte, fileName string, p
Time: pm.getTimeGenerator(),
}
ew, err := openpgp.Encrypt(w, pubKeyEntries, nil, hints, config)
reader, writer := io.Pipe()
var encryptErr error
go func() {
defer wg.Done()
var ew io.WriteCloser
ew, encryptErr = openpgp.Encrypt(writer, pubKeyEntries, nil, hints, config)
_, _ = ew.Write(plainData)
plainData = nil
// clear the buffer
ew.Close()
writer.Close()
}()
_, _ = ew.Write(plainData)
ew.Close()
w.Close()
split, err := internal.SplitPackets(reader, len(plainData))
wg.Wait()
if encryptErr != nil {
return nil, encryptErr
}
split, err := armorUtils.SplitArmor(outBuf.String())
if err != nil {
return nil, err
}

View file

@ -0,0 +1,67 @@
package crypto
import (
"testing"
)
const publicKeya = `-----BEGIN PGP PUBLIC KEY BLOCK-----
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
OQTmvM6R
=DvFv
-----END PGP PUBLIC KEY BLOCK-----`
func TestEncrypt(t *testing.T) {
o := PmCrypto{}
split, err := o.EncryptAttachment([]byte("Hello World!"), "File name", publicKeya)
if err != nil || split == nil {
panic("Encryption failed")
}
}

View file

@ -0,0 +1,105 @@
package internal
import (
"bytes"
"golang.org/x/crypto/openpgp/packet"
"gitlab.com/ProtonMail/go-pm-crypto/models"
"io"
)
func SplitPackets(encryptedReader io.Reader, estimatedLength int) (*models.EncryptedSplit, error){
var err error
//kr *KeyRing, r io.Reader) (key *SymmetricKey, symEncryptedData []byte,
packets := packet.NewReader(encryptedReader)
outSplit := &models.EncryptedSplit{}
// Save encrypted key and signature apart
var ek *packet.EncryptedKey
// var decryptErr error
for {
var p packet.Packet
if p, err = packets.Next(); err == io.EOF {
err = nil
break
}
switch p := p.(type) {
case *packet.EncryptedKey:
// We got an encrypted key. Try to decrypt it with each available key
if ek != nil && ek.Key != nil {
break
}
ek = p
break
case *packet.SymmetricallyEncrypted:
// The code below is optimized to not
var b bytes.Buffer
// 128 is an estimation of the size difference between input and output, the size difference is most probably
// 16 bytes at a maximum though.
b.Grow(128 + estimatedLength)
// empty encoded length + start byte
b.Write(make([]byte, 6))
b.WriteByte(byte(1))
actualLength := 1
block := make([]byte, 128)
for {
n, err := p.Contents.Read(block)
if err == io.EOF {
break
}
b.Write(block[:n])
actualLength += n
}
// quick encoding
symEncryptedData := b.Bytes()
if actualLength < 192 {
symEncryptedData[4] = byte(210)
symEncryptedData[5] = byte(actualLength)
symEncryptedData = symEncryptedData[4:]
} else if actualLength < 8384 {
actualLength = actualLength - 192
symEncryptedData[3] = byte(210)
symEncryptedData[4] = 192+byte(actualLength>>8)
symEncryptedData[5] = byte(actualLength)
symEncryptedData = symEncryptedData[3:]
} else {
symEncryptedData[0] = byte(210)
symEncryptedData[1] = byte(255)
symEncryptedData[2] = byte(actualLength>>24)
symEncryptedData[3] = byte(actualLength>>16)
symEncryptedData[4] = byte(actualLength>>8)
symEncryptedData[5] = byte(actualLength)
}
outSplit.DataPacket = symEncryptedData
break
}
}
var buf bytes.Buffer
ek.Serialize(&buf)
outSplit.KeyPacket = buf.Bytes()
return outSplit, err
}
//encode length based on 4.2.2. in the RFC
func encodedLength(length int) (b []byte) {
if length < 192 {
b = append(b, byte(length))
} else if length < 8384 {
length = length - 192
b = append(b, 192+byte(length>>8))
b = append(b, byte(length))
} else {
b = append(b, byte(255))
b = append(b, byte(length>>24))
b = append(b, byte(length>>16))
b = append(b, byte(length>>8))
b = append(b, byte(length))
}
return
}