diff --git a/build.sh b/build.sh index 4467f5f..1b4c8b5 100755 --- a/build.sh +++ b/build.sh @@ -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" diff --git a/debug_build.sh b/debug_build.sh new file mode 100755 index 0000000..0d4eead --- /dev/null +++ b/debug_build.sh @@ -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" + + diff --git a/dist/Android/pmcrypto.aar b/dist/Android/pmcrypto.aar index 28877dd..64faefa 100644 Binary files a/dist/Android/pmcrypto.aar and b/dist/Android/pmcrypto.aar differ diff --git a/dist/iOS/Crypto.framework/Crypto b/dist/iOS/Crypto.framework/Crypto new file mode 120000 index 0000000..2e04b9d --- /dev/null +++ b/dist/iOS/Crypto.framework/Crypto @@ -0,0 +1 @@ +Versions/Current/Crypto \ No newline at end of file diff --git a/dist/iOS/Crypto.framework/Headers b/dist/iOS/Crypto.framework/Headers new file mode 120000 index 0000000..a177d2a --- /dev/null +++ b/dist/iOS/Crypto.framework/Headers @@ -0,0 +1 @@ +Versions/Current/Headers \ No newline at end of file diff --git a/dist/iOS/Crypto.framework/Modules b/dist/iOS/Crypto.framework/Modules new file mode 120000 index 0000000..5736f31 --- /dev/null +++ b/dist/iOS/Crypto.framework/Modules @@ -0,0 +1 @@ +Versions/Current/Modules \ No newline at end of file diff --git a/dist/iOS/Crypto.framework/Resources b/dist/iOS/Crypto.framework/Resources new file mode 120000 index 0000000..953ee36 --- /dev/null +++ b/dist/iOS/Crypto.framework/Resources @@ -0,0 +1 @@ +Versions/Current/Resources \ No newline at end of file diff --git a/dist/iOS/Crypto.framework/Versions/A/Crypto b/dist/iOS/Crypto.framework/Versions/A/Crypto new file mode 100644 index 0000000..dea9e19 Binary files /dev/null and b/dist/iOS/Crypto.framework/Versions/A/Crypto differ diff --git a/dist/iOS/Crypto.framework/Versions/A/Headers/Armor.objc.h b/dist/iOS/Crypto.framework/Versions/A/Headers/Armor.objc.h new file mode 100644 index 0000000..1b37df1 --- /dev/null +++ b/dist/iOS/Crypto.framework/Versions/A/Headers/Armor.objc.h @@ -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 diff --git a/dist/iOS/Crypto.framework/Versions/A/Headers/Constants.objc.h b/dist/iOS/Crypto.framework/Versions/A/Headers/Constants.objc.h new file mode 100644 index 0000000..b32fbf4 --- /dev/null +++ b/dist/iOS/Crypto.framework/Versions/A/Headers/Constants.objc.h @@ -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 diff --git a/dist/iOS/Crypto.framework/Versions/A/Headers/Crypto.h b/dist/iOS/Crypto.framework/Versions/A/Headers/Crypto.h new file mode 100644 index 0000000..ee54a51 --- /dev/null +++ b/dist/iOS/Crypto.framework/Versions/A/Headers/Crypto.h @@ -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 diff --git a/dist/iOS/Crypto.framework/Versions/A/Headers/Crypto.objc.h b/dist/iOS/Crypto.framework/Versions/A/Headers/Crypto.objc.h new file mode 100644 index 0000000..e231d90 --- /dev/null +++ b/dist/iOS/Crypto.framework/Versions/A/Headers/Crypto.objc.h @@ -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 +- (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 { +} +@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)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 { +} +@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 { +} +@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 diff --git a/dist/iOS/Crypto.framework/Versions/A/Headers/Key.objc.h b/dist/iOS/Crypto.framework/Versions/A/Headers/Key.objc.h new file mode 100644 index 0000000..0556c1e --- /dev/null +++ b/dist/iOS/Crypto.framework/Versions/A/Headers/Key.objc.h @@ -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 diff --git a/dist/iOS/Crypto.framework/Versions/A/Headers/Models.objc.h b/dist/iOS/Crypto.framework/Versions/A/Headers/Models.objc.h new file mode 100644 index 0000000..74fd077 --- /dev/null +++ b/dist/iOS/Crypto.framework/Versions/A/Headers/Models.objc.h @@ -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 { +} +@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 { +} +@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 { +} +@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 { +} +@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 diff --git a/dist/iOS/Crypto.framework/Versions/A/Headers/ref.h b/dist/iOS/Crypto.framework/Versions/A/Headers/ref.h new file mode 100644 index 0000000..b8036a4 --- /dev/null +++ b/dist/iOS/Crypto.framework/Versions/A/Headers/ref.h @@ -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 + +// 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 diff --git a/dist/iOS/Crypto.framework/Versions/A/Headers/universe.objc.h b/dist/iOS/Crypto.framework/Versions/A/Headers/universe.objc.h new file mode 100644 index 0000000..e47f716 --- /dev/null +++ b/dist/iOS/Crypto.framework/Versions/A/Headers/universe.objc.h @@ -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 +- (NSString*)error; +@end + +@class Universeerror; + +@interface Universeerror : NSError { +} +@property(strong, readonly) id _ref; + +- (instancetype)initWithRef:(id)ref; +- (NSString*)error; +@end + +#endif diff --git a/dist/iOS/Crypto.framework/Versions/A/Modules/module.modulemap b/dist/iOS/Crypto.framework/Versions/A/Modules/module.modulemap new file mode 100644 index 0000000..097b6c4 --- /dev/null +++ b/dist/iOS/Crypto.framework/Versions/A/Modules/module.modulemap @@ -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 * +} \ No newline at end of file diff --git a/dist/iOS/Crypto.framework/Versions/A/Resources/Info.plist b/dist/iOS/Crypto.framework/Versions/A/Resources/Info.plist new file mode 100644 index 0000000..0d1a4b8 --- /dev/null +++ b/dist/iOS/Crypto.framework/Versions/A/Resources/Info.plist @@ -0,0 +1,6 @@ + + + + + + diff --git a/dist/iOS/Crypto.framework/Versions/Current b/dist/iOS/Crypto.framework/Versions/Current new file mode 120000 index 0000000..8c7e5a6 --- /dev/null +++ b/dist/iOS/Crypto.framework/Versions/Current @@ -0,0 +1 @@ +A \ No newline at end of file diff --git a/glide.lock b/glide.lock index 365c9df..97d07fb 100644 --- a/glide.lock +++ b/glide.lock @@ -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 diff --git a/src/gitlab.com/ProtonMail/go-pm-crypto/armor/armor.go b/src/gitlab.com/ProtonMail/go-pm-crypto/armor/armor.go index 678f0dd..7da9ec9 100644 --- a/src/gitlab.com/ProtonMail/go-pm-crypto/armor/armor.go +++ b/src/gitlab.com/ProtonMail/go-pm-crypto/armor/armor.go @@ -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 +} \ No newline at end of file diff --git a/src/gitlab.com/ProtonMail/go-pm-crypto/crypto/attachment.go b/src/gitlab.com/ProtonMail/go-pm-crypto/crypto/attachment.go index 35f089a..979bcca 100644 --- a/src/gitlab.com/ProtonMail/go-pm-crypto/crypto/attachment.go +++ b/src/gitlab.com/ProtonMail/go-pm-crypto/crypto/attachment.go @@ -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 } diff --git a/src/gitlab.com/ProtonMail/go-pm-crypto/crypto/attachment_test.go b/src/gitlab.com/ProtonMail/go-pm-crypto/crypto/attachment_test.go new file mode 100644 index 0000000..106095f --- /dev/null +++ b/src/gitlab.com/ProtonMail/go-pm-crypto/crypto/attachment_test.go @@ -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") + } +} \ No newline at end of file diff --git a/src/gitlab.com/ProtonMail/go-pm-crypto/internal/packets.go b/src/gitlab.com/ProtonMail/go-pm-crypto/internal/packets.go new file mode 100644 index 0000000..1f8160f --- /dev/null +++ b/src/gitlab.com/ProtonMail/go-pm-crypto/internal/packets.go @@ -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 +}