// OpenPGP.js - An OpenPGP implementation in javascript // Copyright (C) 2015 Tankred Hase // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation; either // version 3.0 of the License, or (at your option) any later version. // // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public // License along with this library; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA /** * @fileoverview This module implements packet list cloning required to * pass certain object types between the web worker and main thread using * the structured cloning algorithm. * @module packet/clone */ import { Key } from '../key'; import { Message } from '../message'; import { CleartextMessage } from '../cleartext'; import { Signature } from '../signature'; import List from './packetlist'; import type_keyid from '../type/keyid'; import stream from '../stream'; import util from '../util'; ////////////////////////////// // // // List --> Clone // // // ////////////////////////////// /** * Create a packetlist from the correspoding object types. * @param {Object} options the object passed to and from the web worker * @returns {Object} a mutated version of the options optject */ export function clonePackets(options) { if (options.publicKeys) { options.publicKeys = options.publicKeys.map(key => key.toPacketlist()); } if (options.privateKeys) { options.privateKeys = options.privateKeys.map(key => key.toPacketlist()); } if (options.privateKey) { options.privateKey = options.privateKey.toPacketlist(); } if (options.key) { options.key = options.key.toPacketlist(); } if (options.message) { //could be either a Message or CleartextMessage object if (options.message instanceof Message) { options.message = options.message.packets; } else if (options.message instanceof CleartextMessage) { options.message = { text: options.message.text, signature: options.message.signature.packets }; } } if (options.signature && (options.signature instanceof Signature)) { options.signature = options.signature.packets; } if (options.signatures) { if (util.isStream(options.signatures)) { options.signatures = stream.transform(options.signatures, verificationObjectToClone); } else { options.signatures.forEach(verificationObjectToClone); } } return options; } function verificationObjectToClone(verObject) { verObject.signature = verObject.signature.packets; return verObject; } ////////////////////////////// // // // Clone --> List // // // ////////////////////////////// /** * Creates an object with the correct prototype from a corresponding packetlist. * @param {Object} options the object passed to and from the web worker * @param {String} method the public api function name to be delegated to the worker * @returns {Object} a mutated version of the options optject */ export function parseClonedPackets(options) { if (options.publicKeys) { options.publicKeys = options.publicKeys.map(packetlistCloneToKey); } if (options.privateKeys) { options.privateKeys = options.privateKeys.map(packetlistCloneToKey); } if (options.privateKey) { options.privateKey = packetlistCloneToKey(options.privateKey); } if (options.key) { options.key = packetlistCloneToKey(options.key); } if (options.message && options.message.signature) { options.message = packetlistCloneToCleartextMessage(options.message); } else if (options.message) { options.message = packetlistCloneToMessage(options.message); } if (options.signatures) { if (util.isStream(options.signatures)) { options.signatures = stream.transform(options.signatures, packetlistCloneToSignatures); } else { options.signatures = options.signatures.map(packetlistCloneToSignatures); } } if (options.signature) { options.signature = packetlistCloneToSignature(options.signature); } return options; } function packetlistCloneToKey(clone) { const packetlist = List.fromStructuredClone(clone); return new Key(packetlist); } function packetlistCloneToMessage(clone) { const packetlist = List.fromStructuredClone(clone); return new Message(packetlist); } function packetlistCloneToCleartextMessage(clone) { const packetlist = List.fromStructuredClone(clone.signature); return new CleartextMessage(clone.text, new Signature(packetlist)); } //verification objects function packetlistCloneToSignatures(clone) { clone.keyid = type_keyid.fromClone(clone.keyid); const packetlist = List.fromStructuredClone(clone.signature); clone.signature = new Signature(packetlist); return clone; } function packetlistCloneToSignature(clone) { if (util.isString(clone) || util.isStream(clone)) { //signature is armored return clone; } const packetlist = List.fromStructuredClone(clone); return new Signature(packetlist); }