Skip to content

sign outgoing messages #274

Description

@tomholub

part of #275

When outgoing message is encrypted, it should also be signed with the private key.

The implementation is to add a private key into the Core.composeEmail function which will cause the message to also get signed.

Currently it doesn't have any way to add private key, so we should add signingPrv: PrvKeyInfo? to it and pass that in.

    func composeEmail(msg: SendableMsg, fmt: MsgFmt, pubKeys: [String]?) throws -> CoreRes.ComposeEmail {
        let r = try call("composeEmail", jsonDict: [
            "text": msg.text,
            "to": msg.to,
            "cc": msg.cc,
            "bcc": msg.bcc,
            "from": msg.from,
            "subject": msg.subject,
            "replyToMimeMsg": msg.replyToMimeMsg,
            "atts": msg.atts.map { att in ["name": att.name, "type": att.type, "base64": att.base64] },
            "format": fmt.rawValue,
            "pubKeys": pubKeys,
        ], data: nil)
        // this call returned no useful json data, only bytes
        return CoreRes.ComposeEmail(mimeEncoded: r.data)
    }

On the receiving side, this has to be put into the PgpMsg.encrypt function which has a way to accept a private key.

  public composeEmail = async (uncheckedReq: any): Promise<Buffers> => {
    const req = ValidateInput.composeEmail(uncheckedReq);
    const mimeHeaders: RichHeaders = { to: req.to, from: req.from, subject: req.subject, cc: req.cc, bcc: req.bcc };
    if (req.replyToMimeMsg) {
      const previousMsg = await Mime.decode(Buf.fromUtfStr((req.replyToMimeMsg.substr(0, 10000).split('\n\n')[0] || '') + `\n\nno content`));
      const replyHeaders = Mime.replyHeaders(previousMsg);
      mimeHeaders['in-reply-to'] = replyHeaders['in-reply-to'];
      mimeHeaders['references'] = replyHeaders['references'];
    }
    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)));
    } 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, type: 'application/pgp-encrypted', data: encryptedAtt.message.packets.write() }))
      }
      const encrypted = await PgpMsg.encrypt({ pubkeys: req.pubKeys, data: Buf.fromUtfStr(req.text), armor: true }) as OpenPGP.EncryptArmorResult;
      return fmtRes({}, Buf.fromUtfStr(await Mime.encode({ 'text/plain': encrypted.data }, mimeHeaders, encryptedAtts)));
    } else {
      throw new Error(`Unknown format: ${req.format}`);
    }
  }

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions