Merge branch 'rfr' into 'master'

Refactor setup

See merge request ProtonMail/go-pm-crypto!2
This commit is contained in:
Kay Lukas 2018-10-30 09:57:15 +00:00
commit 00ac3e0e2d
46 changed files with 864 additions and 182 deletions

3
.gitignore vendored
View file

@ -1,4 +1,5 @@
.DS_Store
bin
pkg
vendor
.vscode
.vscode

View file

@ -1,129 +0,0 @@
package armor
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/clearsign"
"golang.org/x/crypto/openpgp/packet"
"io"
"io/ioutil"
)
// ArmorKey make bytes input key to armor format
func ArmorKey(input []byte) (string, error) {
return ArmorWithType(input, PUBLIC_KEY_HEADER)
}
// ArmorWithType make bytes input to armor format
func ArmorWithType(input []byte, armorType string) (string, error) {
var b bytes.Buffer
w, err := armor.Encode(&b, armorType, internal.ArmorHeaders)
if err != nil {
return "", err
}
_, err = w.Write(input)
if err != nil {
return "", err
}
w.Close()
return b.String(), nil
}
// Unarmor an armored key to bytes key
func Unarmor(input string) ([]byte, error) {
b, err := internal.Unarmor(input)
if err != nil {
return nil, err
}
return ioutil.ReadAll(b.Body)
}
//ReadClearSignedMessage read clear message from a clearsign package
func ReadClearSignedMessage(signedMessage string) (string, error) {
modulusBlock, rest := clearsign.Decode([]byte(signedMessage))
if len(rest) != 0 {
return "", errors.New("pmapi: extra data after modulus")
}
return string(modulusBlock.Bytes), nil
}
//SeparateKeyAndData ...
func SplitArmor(encrypted string) (*models.EncryptedSplit, error) {
var err error
encryptedRaw, err := 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
}
}
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
}

View file

@ -7,18 +7,23 @@ ANDROID_OUT=${OUTPUT_PATH}/"Android"
IOS_OUT=${OUTPUT_PATH}/"iOS"
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"
gomobile bind -target ios -o ${IOS_OUT}/pmcrypto.framework proton/pmcrypto/crypto proton/pmcrypto/armor proton/pmcrypto/constants proton/pmcrypto/key proton/pmcrypto/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"
gomobile bind -target android -javapkg com.proton.pmcrypto -o ${ANDROID_OUT}/pmcrypto.aar proton/pmcrypto/crypto proton/pmcrypto/armor proton/pmcrypto/constants proton/pmcrypto/key proton/pmcrypto/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"
unlink vendor/src
printf "\e[0;32mAll Done. \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.

Binary file not shown.

BIN
dist/iOS/Crypto.framework.zip vendored Normal file

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,180 @@
// 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 CryptoAttachmentProcessor;
@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
/**
* EncryptedSplit when encrypt attachment
*/
@interface CryptoAttachmentProcessor : NSObject <goSeqRefInterface> {
}
@property(strong, readonly) id _ref;
- (instancetype)initWithRef:(id)ref;
- (instancetype)init;
- (ModelsEncryptedSplit*)finish:(NSError**)error;
- (void)process:(NSData*)plainData;
@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;
- (CryptoAttachmentProcessor*)encryptAttachmentLowMemory:(long)estimatedSize fileName:(NSString*)fileName publicKey:(NSString*)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

14
glide.lock generated
View file

@ -1,8 +1,10 @@
hash: 0e0069ce69a4e3bde6233726f21a880347400808a97c2e6f7a173e4d7daea51c
updated: 2018-09-07T10:20:50.211694+02:00
hash: 7497775ba9a895661860516e3bbf9f367dc7102b014b84d7af225035c0cbfc02
updated: 2018-10-29T15:51:04.090506+01:00
imports:
- name: github.com/konsorten/go-windows-terminal-sequences
version: 5c8c8bd35d3832f5d134ae1e1e375b69a4d25242
- name: github.com/Sirupsen/logrus
version: 3791101e143bf0f32515ac23e831475684f61229
version: 566a5f690849162ff53cf98f3c42135389d63f95
- name: golang.org/x/crypto
version: 9e4251120d8c43f10024d798bc6dde21d40704a0
repo: https://github.com/ProtonMail/crypto.git
@ -31,12 +33,12 @@ imports:
- rsa
- ssh/terminal
- name: golang.org/x/sys
version: 8cf3aee429924738c56c34bb819c4ea8273fc434
version: 95b1ffbd15a57cc5abb3f04402b9e8ec0016a52c
subpackages:
- unix
- windows
- name: golang.org/x/text
version: 4ae1256249243a4eb350a9a372e126557f2aa346
version: 6f8607282f41687a5ce9b5a0378084237f2f7576
subpackages:
- encoding
- encoding/charmap
@ -44,6 +46,6 @@ imports:
- encoding/internal/identifier
- transform
- name: proton/pmmime
version: 347d69204aa62d6958bcb3b9bbacccb24a36372b
version: 72b7b1bf2d1b491e1d003632a0fda41410b0bb59
repo: git@gitlab.protontech.ch:ProtonMail/go-pm-mime.git
testImports: []

View file

@ -1,7 +1,9 @@
package: proton/pmcrypto
package: gitlab.com/ProtonMail/go-pm-crypto
import:
- package: golang.org/x/crypto
version: v1.0.0
repo: https://github.com/ProtonMail/crypto.git
- package: proton/pmmime
repo: git@gitlab.protontech.ch:ProtonMail/go-pm-mime.git
version: feat/mimevisitor

3
init.sh Executable file
View file

@ -0,0 +1,3 @@
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )"
GOPATH="$DIR" glide up
GOPATH="$DIR:$DIR/vendor:$GOPATH" gomobile init -ndk $ANDROID_NDK

View file

@ -0,0 +1,62 @@
package armor
import (
"bytes"
"errors"
"gitlab.com/ProtonMail/go-pm-crypto/internal"
"golang.org/x/crypto/openpgp/armor"
"golang.org/x/crypto/openpgp/clearsign"
"io/ioutil"
"gitlab.com/ProtonMail/go-pm-crypto/models"
)
// ArmorKey make bytes input key to armor format
func ArmorKey(input []byte) (string, error) {
return ArmorWithType(input, PUBLIC_KEY_HEADER)
}
// ArmorWithType make bytes input to armor format
func ArmorWithType(input []byte, armorType string) (string, error) {
var b bytes.Buffer
w, err := armor.Encode(&b, armorType, internal.ArmorHeaders)
if err != nil {
return "", err
}
_, err = w.Write(input)
if err != nil {
return "", err
}
w.Close()
return b.String(), nil
}
// Unarmor an armored key to bytes key
func Unarmor(input string) ([]byte, error) {
b, err := internal.Unarmor(input)
if err != nil {
return nil, err
}
return ioutil.ReadAll(b.Body)
}
//ReadClearSignedMessage read clear message from a clearsign package
func ReadClearSignedMessage(signedMessage string) (string, error) {
modulusBlock, rest := clearsign.Decode([]byte(signedMessage))
if len(rest) != 0 {
return "", errors.New("pmapi: extra data after modulus")
}
return string(modulusBlock.Bytes), nil
}
func SplitArmor(encrypted string) (*models.EncryptedSplit, error) {
var err error
b, err := internal.Unarmor(encrypted)
if err != nil {
return nil, err
}
split, err := internal.SplitPackets(b.Body, len(encrypted), -1)
if err != nil {
return nil, err
}
return split, nil
}

View file

@ -4,24 +4,50 @@ import (
"bytes"
"io"
"io/ioutil"
"golang.org/x/crypto/openpgp"
"golang.org/x/crypto/openpgp/armor"
"golang.org/x/crypto/openpgp/packet"
armorUtils "proton/pmcrypto/armor"
"proton/pmcrypto/internal"
"proton/pmcrypto/models"
)
armorUtils "gitlab.com/ProtonMail/go-pm-crypto/armor"
"gitlab.com/ProtonMail/go-pm-crypto/internal"
"gitlab.com/ProtonMail/go-pm-crypto/models"
"sync"
"runtime"
)
//EncryptedSplit when encrypt attachment
type AttachmentProcessor struct {
w *io.WriteCloser
pipe *io.PipeWriter
done sync.WaitGroup
split *models.EncryptedSplit
garbageCollector int
err error
}
func (ap *AttachmentProcessor) Process(plainData []byte) {
(*ap.w).Write(plainData)
}
func (ap *AttachmentProcessor) Finish() (*models.EncryptedSplit, error) {
if ap.err != nil {
return nil, ap.err
}
(*ap.w).Close()
(*ap.pipe).Close()
ap.done.Wait()
if ap.garbageCollector > 0 {
runtime.GC()
}
return ap.split, nil
}
//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
}
func (pm *PmCrypto) encryptAttachment(estimatedSize int, fileName string, publicKey []byte, garbageCollector int) (*AttachmentProcessor, error) {
attachmentProc := &AttachmentProcessor{}
// you can also add these one at
// a time if you need to
attachmentProc.done.Add(1)
attachmentProc.garbageCollector = garbageCollector
pubKeyReader := bytes.NewReader(publicKey)
pubKeyEntries, err := openpgp.ReadKeyRing(pubKeyReader)
if err != nil {
@ -36,18 +62,28 @@ 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()
_, _ = ew.Write(plainData)
ew.Close()
w.Close()
go func () {
defer attachmentProc.done.Done()
split, splitError := internal.SplitPackets(reader, estimatedSize, garbageCollector)
if attachmentProc.err != nil {
attachmentProc.err = splitError
}
split.Algo = "aes256"
attachmentProc.split = split
}()
split, err := armorUtils.SplitArmor(outBuf.String())
if err != nil {
return nil, err
var ew io.WriteCloser
var encryptErr error
ew, encryptErr = openpgp.Encrypt(writer, pubKeyEntries, nil, hints, config)
attachmentProc.w = &ew
attachmentProc.pipe = writer
if attachmentProc.err != nil {
attachmentProc.err = encryptErr
}
split.Algo = "aes256"
return split, nil
return attachmentProc, nil
}
//EncryptAttachment ...
@ -56,7 +92,26 @@ func (pm *PmCrypto) EncryptAttachment(plainData []byte, fileName string, publicK
if err != nil {
return nil, err
}
return pm.EncryptAttachmentBinKey(plainData, fileName, rawPubKey)
ap, err := pm.encryptAttachment(len(plainData), fileName, rawPubKey, -1)
if err != nil {
return nil, err
}
ap.Process(plainData)
split, err := ap.Finish()
if err != nil {
return nil, err
}
return split, nil
}
//EncryptAttachment ...
func (pm *PmCrypto) EncryptAttachmentLowMemory(estimatedSize int, fileName string, publicKey string) (*AttachmentProcessor, error) {
rawPubKey, err := armorUtils.Unarmor(publicKey)
if err != nil {
return nil, err
}
// Garbage collect every megabyte
return pm.encryptAttachment(estimatedSize, fileName, rawPubKey, 1 << 20)
}
//DecryptAttachmentBinKey ...

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

@ -11,7 +11,7 @@ import (
"golang.org/x/crypto/openpgp"
"golang.org/x/crypto/openpgp/packet"
"math/big"
"proton/pmcrypto/armor"
"gitlab.com/ProtonMail/go-pm-crypto/armor"
)
const (

View file

@ -13,9 +13,9 @@ import (
errors2 "golang.org/x/crypto/openpgp/errors"
"golang.org/x/crypto/openpgp/packet"
"math"
armorUtils "proton/pmcrypto/armor"
"proton/pmcrypto/internal"
"proton/pmcrypto/models"
armorUtils "gitlab.com/ProtonMail/go-pm-crypto/armor"
"gitlab.com/ProtonMail/go-pm-crypto/internal"
"gitlab.com/ProtonMail/go-pm-crypto/models"
)
// DecryptMessage decrypt encrypted message use private key (string )

View file

@ -9,8 +9,7 @@ import (
"io/ioutil"
"bytes"
"golang.org/x/crypto/openpgp"
"proton/pmcrypto/armor"
)
)
// ======================== Attachments Collector ==============
// Collect contents of all attachment parts and return
@ -34,7 +33,6 @@ func (pm PmCrypto) parseMIME(mimeBody string, verifierKey []byte) (*pmmime.BodyC
bodyCollector := pmmime.NewBodyCollector(printAccepter)
attachmentsCollector := pmmime.NewAttachmentsCollector(bodyCollector)
mimeVisitor := pmmime.NewMimeVisitor(attachmentsCollector)
str, err := armor.ArmorKey(verifierKey)
signatureCollector := newSignatureCollector(mimeVisitor, pubKeyEntries, config)
err = pmmime.VisitAll(bytes.NewReader(mmBodyData), h, signatureCollector)

View file

@ -3,7 +3,7 @@ package crypto
import (
"fmt"
"io/ioutil"
"proton/pmcrypto/internal"
"gitlab.com/ProtonMail/go-pm-crypto/internal"
"testing"
)

View file

@ -9,8 +9,8 @@ import (
"golang.org/x/crypto/openpgp"
"golang.org/x/crypto/openpgp/packet"
"proton/pmcrypto/armor"
"proton/pmcrypto/models"
"gitlab.com/ProtonMail/go-pm-crypto/armor"
"gitlab.com/ProtonMail/go-pm-crypto/models"
)
//RandomToken ...

View file

@ -10,7 +10,7 @@ import (
"golang.org/x/crypto/openpgp/packet"
errors2 "golang.org/x/crypto/openpgp/errors"
"io"
"proton/pmcrypto/internal"
"gitlab.com/ProtonMail/go-pm-crypto/internal"
)
// SignTextDetached sign detached text type

View file

@ -1,14 +1,12 @@
package crypto
import (
"bufio"
"bytes"
"golang.org/x/crypto/openpgp"
"golang.org/x/crypto/openpgp/packet"
"io"
"io/ioutil"
"mime"
"mime/multipart"
"net/textproto"
"proton/pmmime"
)

View file

@ -7,7 +7,6 @@ import (
// UpdateTime update cached time
func (pm *PmCrypto) UpdateTime(newTime int64) {
pm.latestServerTime = newTime
pm.latestClientTime = time.Now()
}
//GetTime get latest cached time
@ -16,10 +15,8 @@ func (pm *PmCrypto) GetTime() int64 {
}
func (pm *PmCrypto) getNow() time.Time {
if pm.latestServerTime > 0 && !pm.latestClientTime.IsZero() {
// Sub is monotome, it uses a monotime time clock in this case instead of the wall clock
extrapolate := int64(pm.latestClientTime.Sub(time.Now()).Seconds())
return time.Unix(pm.latestServerTime + extrapolate, 0)
if pm.latestServerTime > 0 {
return time.Unix(pm.latestServerTime, 0)
}
return time.Now()

View file

@ -0,0 +1,115 @@
package internal
import (
"bytes"
"golang.org/x/crypto/openpgp/packet"
"gitlab.com/ProtonMail/go-pm-crypto/models"
"io"
"runtime"
)
func SplitPackets(encryptedReader io.Reader, estimatedLength int, garbageCollector int) (*models.EncryptedSplit, error){
var err error
// For info on each, see: https://golang.org/pkg/runtime/#MemStats
//kr *KeyRing, r io.Reader) (key *SymmetricKey, symEncryptedData []byte,
packets := packet.NewReader(encryptedReader)
outSplit := &models.EncryptedSplit{}
gcCounter := 0
// 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
// 2^16 is an estimation of the size difference between input and output, the size difference is most probably
// 16 bytes at a maximum though.
// We need to avoid triggering a grow from the system as this will allocate too much memory causing problems
// in low-memory environments
b.Grow(1 << 16 + 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
gcCounter += n
if gcCounter > garbageCollector && garbageCollector > 0 {
runtime.GC()
gcCounter = 0
}
}
// 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
}

View file

@ -6,7 +6,7 @@ import (
"errors"
"golang.org/x/crypto/openpgp"
"proton/pmcrypto/armor"
"gitlab.com/ProtonMail/go-pm-crypto/armor"
)
// GetFingerprint get a armored public key fingerprint

View file

@ -6,7 +6,7 @@ import (
"fmt"
"golang.org/x/crypto/openpgp/packet"
"bytes"
"proton/pmcrypto/armor"
"gitlab.com/ProtonMail/go-pm-crypto/armor"
)
//CheckPassphrase check is private key passphrase ok