Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 3 additions & 5 deletions Core/source/core/pgp-msg.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import { Catch } from '../platform/catch';
import { FcAttLinkData } from './att';
import { MsgBlockParser } from './msg-block-parser';
import { PgpArmor } from './pgp-armor';
import { PgpHash } from './pgp-hash';
import { Store } from '../platform/store';
import { openpgp } from './pgp';

Expand Down Expand Up @@ -222,8 +221,8 @@ export class PgpMsg {

public static encrypt: PgpMsgMethod.Encrypt = async ({ pubkeys, signingPrv, pwd, data, filename, armor, date }) => {
const message = openpgp.message.fromBinary(data, filename, date);

const options: OpenPGP.EncryptOptions = { armor, message, date };
let usedChallenge = false;
if (pubkeys) {
options.publicKeys = [];
for (const armoredPubkey of pubkeys) {
Expand All @@ -232,10 +231,9 @@ export class PgpMsg {
}
}
if (pwd) {
options.passwords = [await PgpHash.challengeAnswer(pwd)];
usedChallenge = true;
options.passwords = [pwd];
}
if (!pubkeys && !usedChallenge) {
if (!pubkeys && !pwd) {
throw new Error('no-pubkeys-no-challenge');
}
if (signingPrv && typeof signingPrv.isPrivate !== 'undefined' && signingPrv.isPrivate()) { // tslint:disable-line:no-unbound-method - only testing if exists
Expand Down
16 changes: 8 additions & 8 deletions Core/source/mobile-interface/endpoints.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,6 @@ export class Endpoints {
return fmtRes({ app_version: VERSION });
}

public encryptMsg = async (uncheckedReq: any, data: Buffers): Promise<EndpointRes> => {
const req = ValidateInput.encryptMsg(uncheckedReq);
const encrypted = await PgpMsg.encrypt({ pubkeys: req.pubKeys, data: Buf.concat(data), armor: true }) as OpenPGP.EncryptArmorResult;
return fmtRes({}, Buf.fromUtfStr(encrypted.data));
}

public generateKey = async (uncheckedReq: any): Promise<EndpointRes> => {
Store.keyCacheWipe(); // generateKey may be used when changing major settings, wipe cache to prevent dated results
const { passphrase, userIds, variant } = ValidateInput.generateKey(uncheckedReq);
Expand All @@ -57,13 +51,14 @@ export class Endpoints {
}
if (req.format === 'plain') {
const atts = (req.atts || []).map(({ name, type, base64 }) => new Att({ name, type, data: Buf.fromBase64Str(base64) }));
return fmtRes({}, Buf.fromUtfStr(await Mime.encode({ 'text/plain': req.text }, mimeHeaders, atts)));
return fmtRes({}, Buf.fromUtfStr(await Mime.encode({ 'text/plain': req.text, 'text/html': req.html }, mimeHeaders, atts)));
} else if (req.format === 'encrypt-inline') {
const encryptedAtts: Att[] = [];
for (const att of req.atts || []) {
const encryptedAtt = await PgpMsg.encrypt({ pubkeys: req.pubKeys, data: Buf.fromBase64Str(att.base64), filename: att.name, armor: false }) as OpenPGP.EncryptBinaryResult;
encryptedAtts.push(new Att({ name: `${att.name}.pgp`, type: 'application/pgp-encrypted', data: encryptedAtt.message.packets.write() }))
}

const signingPrv = await getSigningPrv(req);
const encrypted = await PgpMsg.encrypt({ pubkeys: req.pubKeys, signingPrv, data: Buf.fromUtfStr(req.text), armor: true }) as OpenPGP.EncryptArmorResult;
return fmtRes({}, Buf.fromUtfStr(await Mime.encode({ 'text/plain': encrypted.data }, mimeHeaders, encryptedAtts)));
Expand All @@ -72,6 +67,12 @@ export class Endpoints {
}
}

public encryptMsg = async (uncheckedReq: any, data: Buffers): Promise<EndpointRes> => {
const req = ValidateInput.encryptMsg(uncheckedReq);
const encrypted = await PgpMsg.encrypt({ pubkeys: req.pubKeys, pwd: req.msgPwd, data: Buf.concat(data), armor: true }) as OpenPGP.EncryptArmorResult;
return fmtRes({}, Buf.fromUtfStr(encrypted.data));
}

public encryptFile = async (uncheckedReq: any, data: Buffers): Promise<EndpointRes> => {
const req = ValidateInput.encryptFile(uncheckedReq);
const encrypted = await PgpMsg.encrypt({ pubkeys: req.pubKeys, data: Buf.concat(data), filename: req.name, armor: false }) as OpenPGP.EncryptBinaryResult;
Expand Down Expand Up @@ -304,4 +305,3 @@ export const getSigningPrv = async (req: NodeRequest.composeEmailEncrypted): Pro
throw new Error(`Fail to decrypt signing key`);
}
}

8 changes: 4 additions & 4 deletions Core/source/mobile-interface/validate-input.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,13 @@ type Obj = { [k: string]: any };
export namespace NodeRequest {
type PrvKeyInfo = { private: string; longid: string, passphrase: string | undefined };
type Attachment = { name: string; type: string; base64: string };
interface composeEmailBase { text: string, to: string[], cc: string[], bcc: string[], from: string, subject: string, replyToMimeMsg: string, atts?: Attachment[] };
interface composeEmailBase { text: string, html?: string, to: string[], cc: string[], bcc: string[], from: string, subject: string, replyToMimeMsg: string, atts?: Attachment[] };
export interface composeEmailPlain extends composeEmailBase { format: 'plain' };
export interface composeEmailEncrypted extends composeEmailBase { format: 'encrypt-inline' | 'encrypt-pgpmime', pubKeys: string[], signingPrv: PrvKeyInfo | undefined };

export type generateKey = { passphrase: string, variant: 'rsa2048' | 'rsa4096' | 'curve25519', userIds: { name: string, email: string }[] };
export type composeEmail = composeEmailPlain | composeEmailEncrypted;
export type encryptMsg = { pubKeys: string[] };
export type encryptMsg = { pubKeys: string[], msgPwd?: string };
export type encryptFile = { pubKeys: string[], name: string };
export type parseDecryptMsg = { keys: PrvKeyInfo[], msgPwd?: string, isEmail?: boolean, verificationPubkeys?: string[] };
export type decryptFile = { keys: PrvKeyInfo[], msgPwd?: string };
Expand All @@ -37,14 +37,14 @@ export class ValidateInput {
}

public static encryptMsg = (v: any): NodeRequest.encryptMsg => {
if (isObj(v) && hasProp(v, 'pubKeys', 'string[]')) {
if (isObj(v) && hasProp(v, 'pubKeys', 'string[]') && hasProp(v, 'msgPwd', 'string?')) {
return v as NodeRequest.encryptMsg;
}
throw new Error('Wrong request structure for NodeRequest.encryptMsg');
}

public static composeEmail = (v: any): NodeRequest.composeEmail => {
if (!(isObj(v) && hasProp(v, 'text', 'string') && hasProp(v, 'from', 'string') && hasProp(v, 'subject', 'string') && hasProp(v, 'to', 'string[]') && hasProp(v, 'cc', 'string[]') && hasProp(v, 'bcc', 'string[]'))) {
if (!(isObj(v) && hasProp(v, 'text', 'string') && hasProp(v, 'html', 'string?') && hasProp(v, 'from', 'string') && hasProp(v, 'subject', 'string') && hasProp(v, 'to', 'string[]') && hasProp(v, 'cc', 'string[]') && hasProp(v, 'bcc', 'string[]'))) {
throw new Error('Wrong request structure for NodeRequest.composeEmail, need: text,from,subject,to,cc,bcc,atts (can use empty arr for cc/bcc, and can skip atts)');
}
if (!hasProp(v, 'atts', 'Attachment[]?')) {
Expand Down
12 changes: 12 additions & 0 deletions Core/source/test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,18 @@ for (const keypairName of allKeypairNames.filter(name => name != 'expired' && na
});
}

ava.default(`encryptMsg -> parseDecryptMsg (with password)`, async t => {
const content = 'hello\nwrld';
const msgPwd = '123';
const { data: encryptedMsg, json: encryptJson } = parseResponse(await endpoints.encryptMsg({ pubKeys: [], msgPwd: msgPwd }, [Buffer.from(content, 'utf8')]));
expectEmptyJson(encryptJson);
expectData(encryptedMsg, 'armoredMsg');
const { data: blocks, json: decryptJson } = parseResponse(await endpoints.parseDecryptMsg({ keys: [], msgPwd: msgPwd }, [encryptedMsg]));
expect(decryptJson).to.deep.equal({ text: content, replyType: 'encrypted' });
expectData(blocks, 'msgBlocks', [{ rendered: true, frameColor: 'green', htmlContent: content.replace(/\n/g, '<br />') }]);
t.pass();
});

ava.default('composeEmail format:plain -> parseDecryptMsg', async t => {
const content = 'hello\nwrld';
const { keys } = getKeypairs('rsa1');
Expand Down
18 changes: 9 additions & 9 deletions FlowCrypt.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
21C7DF09266C0D8F00C44800 /* EnterpriseServerApi.swift in Sources */ = {isa = PBXBuildFile; fileRef = 21C7DF08266C0D8F00C44800 /* EnterpriseServerApi.swift */; };
21CE25E62650070300ADFF4B /* WkdUrlConstructor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 21CE25E52650070300ADFF4B /* WkdUrlConstructor.swift */; };
21EA3B592656611D00691848 /* ClientConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 21EA3B15265647C400691848 /* ClientConfiguration.swift */; };
21F836B62652A26B00B2448C /* DataExntensions+ZBase32Encoding.swift in Sources */ = {isa = PBXBuildFile; fileRef = 21F836B52652A26B00B2448C /* DataExntensions+ZBase32Encoding.swift */; };
21F836B62652A26B00B2448C /* DataExtensions+ZBase32Encoding.swift in Sources */ = {isa = PBXBuildFile; fileRef = 21F836B52652A26B00B2448C /* DataExtensions+ZBase32Encoding.swift */; };
2C03CC16275BB53400887EEB /* EnterpriseServerApiTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2C03CC15275BB53400887EEB /* EnterpriseServerApiTests.swift */; };
2C08F6BE273FA7B900EE1610 /* Version5SchemaMigration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2C08F6BD273FA7B900EE1610 /* Version5SchemaMigration.swift */; };
2C124DB42728809100A2EFA6 /* ApiCall.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2C124DB32728809100A2EFA6 /* ApiCall.swift */; };
Expand Down Expand Up @@ -345,7 +345,7 @@
D2CDC3CD2402CCD7002B045F /* UIImageExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F8277952373732000E19C07 /* UIImageExtensions.swift */; };
D2CDC3CE2402CDB4002B045F /* DispatchTimeExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 32DCABF1508B0C08DEDE2059 /* DispatchTimeExtensions.swift */; };
D2CDC3D32402D4FE002B045F /* DataExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 32DCAEFF16F5D91A35791730 /* DataExtensions.swift */; };
D2CDC3D42402D50A002B045F /* CodableExntensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 32DCA38E87F2B7196E0E1F1F /* CodableExntensions.swift */; };
D2CDC3D42402D50A002B045F /* CodableExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 32DCA38E87F2B7196E0E1F1F /* CodableExtensions.swift */; };
D2CDC3D72404704D002B045F /* RecipientEmailsCellNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = D24ABA6223FDB4FF002EE9DD /* RecipientEmailsCellNode.swift */; };
D2CDC3D824047066002B045F /* RecipientEmailNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2531F3523FFEDA2007E5198 /* RecipientEmailNode.swift */; };
D2CDC3DD24052D50002B045F /* FlowCryptUI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D204DB9E23FB35700083B9D6 /* FlowCryptUI.framework */; };
Expand Down Expand Up @@ -448,7 +448,7 @@
21EA3B2E26565B7400691848 /* client_configuraion.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = client_configuraion.json; sourceTree = "<group>"; };
21EA3B3526565B8100691848 /* client_configuraion_empty.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = client_configuraion_empty.json; sourceTree = "<group>"; };
21EA3B3C26565B9800691848 /* client_configuraion_partly_empty.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = client_configuraion_partly_empty.json; sourceTree = "<group>"; };
21F836B52652A26B00B2448C /* DataExntensions+ZBase32Encoding.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "DataExntensions+ZBase32Encoding.swift"; sourceTree = "<group>"; };
21F836B52652A26B00B2448C /* DataExtensions+ZBase32Encoding.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "DataExtensions+ZBase32Encoding.swift"; sourceTree = "<group>"; };
21F836CB2652A38700B2448C /* ZBase32EncodingTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ZBase32EncodingTests.swift; sourceTree = "<group>"; };
21F836D22652A46E00B2448C /* WKDURLsConstructorTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WKDURLsConstructorTests.swift; sourceTree = "<group>"; };
2C03CC15275BB53400887EEB /* EnterpriseServerApiTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EnterpriseServerApiTests.swift; sourceTree = "<group>"; };
Expand All @@ -470,7 +470,7 @@
32DCA0C3D34A69851A238E87 /* Core.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Core.swift; sourceTree = "<group>"; };
32DCA0E63F2F0473D0A8EDB0 /* StringExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StringExtensions.swift; sourceTree = "<group>"; };
32DCA377D22F4D67A8FA05EB /* Imap.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Imap.swift; sourceTree = "<group>"; };
32DCA38E87F2B7196E0E1F1F /* CodableExntensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CodableExntensions.swift; sourceTree = "<group>"; };
32DCA38E87F2B7196E0E1F1F /* CodableExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CodableExtensions.swift; sourceTree = "<group>"; };
32DCA4B11D4531B3B04D01D1 /* AppErr.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppErr.swift; sourceTree = "<group>"; };
32DCA55C094E9745AA1FD210 /* Imap+msg.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Imap+msg.swift"; sourceTree = "<group>"; };
32DCA63656CB3323C26BC084 /* UIVIewExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UIVIewExtensions.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -956,7 +956,7 @@
isa = PBXGroup;
children = (
32DCAEFF16F5D91A35791730 /* DataExtensions.swift */,
21F836B52652A26B00B2448C /* DataExntensions+ZBase32Encoding.swift */,
21F836B52652A26B00B2448C /* DataExtensions+ZBase32Encoding.swift */,
);
path = Data;
sourceTree = "<group>";
Expand Down Expand Up @@ -1879,7 +1879,7 @@
D2D27B78248A8694007346FA /* BigIntExtensions.swift */,
E26D5E20275AA417007B8802 /* BundleExtensions.swift */,
21C7DEFB26669A3700C44800 /* CalendarExtensions.swift */,
32DCA38E87F2B7196E0E1F1F /* CodableExntensions.swift */,
32DCA38E87F2B7196E0E1F1F /* CodableExtensions.swift */,
D2531F452402C62D007E5198 /* CollectionExtensions.swift */,
9F0C3C2723194E8500299985 /* CommonExtensions.swift */,
9F56BD3723438C7000A7371A /* DateFormattingExtensions.swift */,
Expand Down Expand Up @@ -2262,7 +2262,7 @@
isa = PBXProject;
attributes = {
LastSwiftUpdateCheck = 1240;
LastUpgradeCheck = 1310;
LastUpgradeCheck = 1320;
ORGANIZATIONNAME = "FlowCrypt Limited";
TargetAttributes = {
9F2AC5C5267BE99E00F6149B = {
Expand Down Expand Up @@ -2845,7 +2845,7 @@
9F67998C277B3E4000AFE5BE /* BundleExtensions.swift in Sources */,
9FD5052B278B2C8600FAA82F /* UIPopoverPresentationControllerExtensions.swift in Sources */,
D2CDC3CD2402CCD7002B045F /* UIImageExtensions.swift in Sources */,
21F836B62652A26B00B2448C /* DataExntensions+ZBase32Encoding.swift in Sources */,
21F836B62652A26B00B2448C /* DataExtensions+ZBase32Encoding.swift in Sources */,
D29AFFF6240939AE00C1387D /* Then.swift in Sources */,
9FBD69EE27775086002FC602 /* ErrorExtensions.swift in Sources */,
9F6F5F6C26A2F66B00C625C7 /* Logger.swift in Sources */,
Expand All @@ -2862,7 +2862,7 @@
9FD5052927889D8200FAA82F /* UIAlertControllerExtensions.swift in Sources */,
9F8076D927762515008E5874 /* BigIntExtensions.swift in Sources */,
9FBD69EC27775086002FC602 /* UIApplicationExtensions.swift in Sources */,
D2CDC3D42402D50A002B045F /* CodableExntensions.swift in Sources */,
D2CDC3D42402D50A002B045F /* CodableExtensions.swift in Sources */,
9FD505272785C2CD00FAA82F /* UIDeviceExtensions.swift in Sources */,
D2531F3D24000E37007E5198 /* UIVIewExtensions.swift in Sources */,
D2531F3723FFF043007E5198 /* CommonExtensions.swift in Sources */,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1310"
LastUpgradeVersion = "1320"
version = "1.7">
<BuildAction
parallelizeBuildables = "YES"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1310"
LastUpgradeVersion = "1320"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1310"
LastUpgradeVersion = "1320"
version = "1.7">
<BuildAction
parallelizeBuildables = "YES"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1310"
LastUpgradeVersion = "1320"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1310"
LastUpgradeVersion = "1320"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1310"
LastUpgradeVersion = "1320"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1310"
LastUpgradeVersion = "1320"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
Expand Down
8 changes: 4 additions & 4 deletions FlowCrypt.xcworkspace/xcshareddata/swiftpm/Package.resolved

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -497,6 +497,7 @@ extension ComposeViewController {
// TODO: - fix for spinner
// https://github.com/FlowCrypt/flowcrypt-ios/issues/291
try await Task.sleep(nanoseconds: 100 * 1_000_000) // 100ms

let sendableMsg = try await self.composeMessageService.validateAndProduceSendableMsg(
input: self.input,
contextToSend: self.contextToSend,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@

import UIKit


struct BackupViewDecorator {
let sceneTitle: String = "backup_screen_title"
.localized
Expand Down
Loading