Blame lang/js/src/gpgmejs.js

Packit Service 30b792
/* gpgme.js - Javascript integration for gpgme
Packit Service 30b792
 * Copyright (C) 2018 Bundesamt für Sicherheit in der Informationstechnik
Packit Service 30b792
 *
Packit Service 30b792
 * This file is part of GPGME.
Packit Service 30b792
 *
Packit Service 30b792
 * GPGME is free software; you can redistribute it and/or modify it
Packit Service 30b792
 * under the terms of the GNU Lesser General Public License as
Packit Service 30b792
 * published by the Free Software Foundation; either version 2.1 of
Packit Service 30b792
 * the License, or (at your option) any later version.
Packit Service 30b792
 *
Packit Service 30b792
 * GPGME is distributed in the hope that it will be useful, but
Packit Service 30b792
 * WITHOUT ANY WARRANTY; without even the implied warranty of
Packit Service 30b792
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit Service 30b792
 * Lesser General Public License for more details.
Packit Service 30b792
 *
Packit Service 30b792
 * You should have received a copy of the GNU Lesser General Public
Packit Service 30b792
 * License along with this program; if not, see <https://www.gnu.org/licenses/>.
Packit Service 30b792
 * SPDX-License-Identifier: LGPL-2.1+
Packit Service 30b792
 *
Packit Service 30b792
 * Author(s):
Packit Service 30b792
 *     Maximilian Krambach <mkrambach@intevation.de>
Packit Service 30b792
 */
Packit Service 30b792
Packit Service 30b792
Packit Service 30b792
import { GPGME_Message, createMessage } from './Message';
Packit Service 30b792
import { toKeyIdArray } from './Helpers';
Packit Service 30b792
import { gpgme_error } from './Errors';
Packit Service 30b792
import { GPGME_Keyring } from './Keyring';
Packit Service 30b792
import { createSignature } from './Signature';
Packit Service 30b792
Packit Service 30b792
/**
Packit Service 30b792
 * @typedef {Object} decrypt_result
Packit Service 30b792
 * @property {String|Uint8Array} data The decrypted data.
Packit Service 30b792
 * @property {String} format Indicating how the data was converted after being
Packit Service 30b792
 * received from gpgme:
Packit Service 30b792
 * 
Packit Service 30b792
 *      'ascii': Data was ascii-encoded and no further processed
Packit Service 30b792
 *      'string': Data was decoded into an utf-8 string,
Packit Service 30b792
 *      'base64': Data was not processed and is a base64 string
Packit Service 30b792
 *      'uint8': data was turned into a Uint8Array
Packit Service 30b792
 * 
Packit Service 30b792
 * @property {Boolean} is_mime (optional) the data claims to be a MIME object.
Packit Service 30b792
 * @property {String} file_name (optional) the original file name
Packit Service 30b792
 * @property {signatureDetails} signatures Verification details for
Packit Service 30b792
 * signatures
Packit Service 30b792
 */
Packit Service 30b792
Packit Service 30b792
/**
Packit Service 30b792
 * @typedef {Object} signatureDetails
Packit Service 30b792
 * @property {Boolean} all_valid Quick summary. True if all signatures are
Packit Service 30b792
 * fully valid according to gnupg.
Packit Service 30b792
 * @property {Number} count Number of signatures parsed.
Packit Service 30b792
 * @property {Number} failures Number of signatures not passing as valid. This
Packit Service 30b792
 * may imply bad signatures, or signatures with e.g. the public Key not being
Packit Service 30b792
 * available.
Packit Service 30b792
 * @property {GPGME_Signature[]} signatures.good Array of all signatures
Packit Service 30b792
 * considered valid.
Packit Service 30b792
 * @property {GPGME_Signature[]} signatures.bad All invalid signatures.
Packit Service 30b792
 */
Packit Service 30b792
Packit Service 30b792
/**
Packit Service 30b792
 * @typedef {Object} encrypt_result The result of an encrypt operation,
Packit Service 30b792
 * containing the encrypted data and some additional information.
Packit Service 30b792
 * @property {String} data The encrypted message.
Packit Service 30b792
 * @property {String} format Indicating how the data was converted after being
Packit Service 30b792
 *  received from gpgme.
Packit Service 30b792
 * 
Packit Service 30b792
 *      'ascii': Data was ascii-encoded and no further processed
Packit Service 30b792
 *      'string': Data was decoded into an utf-8 string,
Packit Service 30b792
 *      'base64': Data was not processed and is a base64 string
Packit Service 30b792
 *      'uint8': Data was turned into a Uint8Array
Packit Service 30b792
 * 
Packit Service 30b792
 */
Packit Service 30b792
Packit Service 30b792
/**
Packit Service 30b792
 * @typedef { GPGME_Key | String | Object } inputKeys
Packit Service 30b792
 * Accepts different identifiers of a gnupg Key that can be parsed by
Packit Service 30b792
 * {@link toKeyIdArray}. Expected inputs are: One or an array of
Packit Service 30b792
 * GPGME_Keys; one or an array of fingerprint strings; one or an array of
Packit Service 30b792
 * openpgpjs Key objects.
Packit Service 30b792
 */
Packit Service 30b792
Packit Service 30b792
/**
Packit Service 30b792
 * @typedef {Object} signResult The result of a signing operation
Packit Service 30b792
 * @property {String} data The resulting data. Includes the signature in
Packit Service 30b792
 *  clearsign mode
Packit Service 30b792
 * @property {String} signature The detached signature (only present in in
Packit Service 30b792
 * detached mode)
Packit Service 30b792
 */
Packit Service 30b792
Packit Service 30b792
/** @typedef {Object} verifyResult The result of a verification
Packit Service 30b792
 * @property {Boolean} data: The verified data
Packit Service 30b792
 * @property {Boolean} is_mime (optional) the data claims to be a MIME
Packit Service 30b792
 * object.
Packit Service 30b792
 * @property {signatureDetails} signatures Verification details for
Packit Service 30b792
 * signatures
Packit Service 30b792
 */
Packit Service 30b792
Packit Service 30b792
/**
Packit Service 30b792
 * The main entry point for gpgme.js.
Packit Service 30b792
 * @class
Packit Service 30b792
 */
Packit Service 30b792
export class GpgME {
Packit Service 30b792
Packit Service 30b792
    constructor (){
Packit Service 30b792
        this._Keyring = null;
Packit Service 30b792
    }
Packit Service 30b792
Packit Service 30b792
    set Keyring (keyring){
Packit Service 30b792
        if (keyring && keyring instanceof GPGME_Keyring){
Packit Service 30b792
            this._Keyring = keyring;
Packit Service 30b792
        }
Packit Service 30b792
    }
Packit Service 30b792
Packit Service 30b792
    /**
Packit Service 30b792
     * Accesses the {@link GPGME_Keyring}. From the Keyring, all Keys can be
Packit Service 30b792
     * accessed.
Packit Service 30b792
     */
Packit Service 30b792
    get Keyring (){
Packit Service 30b792
        if (!this._Keyring){
Packit Service 30b792
            this._Keyring = new GPGME_Keyring;
Packit Service 30b792
        }
Packit Service 30b792
        return this._Keyring;
Packit Service 30b792
    }
Packit Service 30b792
Packit Service 30b792
    /**
Packit Service 30b792
     * Encrypt data for the recipients specified in publicKeys. If privateKeys
Packit Service 30b792
     * are submitted, the data will be signed by those Keys.
Packit Service 30b792
     * @param {Object} options
Packit Service 30b792
     * @param {String|Object} options.data text/data to be encrypted as String.
Packit Service 30b792
     * Also accepts Objects with a getText method.
Packit Service 30b792
     * @param {inputKeys} options.publicKeys
Packit Service 30b792
     * Keys used to encrypt the message
Packit Service 30b792
     * @param {inputKeys} options.secretKeys (optional) Keys used to sign the
Packit Service 30b792
     * message. If Keys are present, the  operation requested is assumed
Packit Service 30b792
     * to be 'encrypt and sign'
Packit Service 30b792
     * @param {Boolean} options.base64 (optional, default: false) The data will
Packit Service 30b792
     * be interpreted as base64 encoded data.
Packit Service 30b792
     * @param {Boolean} options.armor (optional, default: true) Request the
Packit Service 30b792
     * output as armored block.
Packit Service 30b792
     * @param {Boolean} options.wildcard (optional, default: false) If true,
Packit Service 30b792
     * recipient information will not be added to the message.
Packit Service 30b792
     * @param {Boolean} options.always_trust (optional, default true) This
Packit Service 30b792
     * assumes that used keys are fully trusted. If set to false, encryption to
Packit Service 30b792
     * a key not fully trusted in gnupg will fail.
Packit Service 30b792
     * @param {String} options.expect (default: 'base64') In case of
Packit Service 30b792
     * armored:false, request how to return the binary result.
Packit Service 30b792
     * Accepts 'base64' or 'uint8'
Packit Service 30b792
     * @param {Object} options.additional use additional valid gpg options as
Packit Service 30b792
     * defined in {@link permittedOperations}
Packit Service 30b792
     * @returns {Promise<encrypt_result>} Object containing the encrypted
Packit Service 30b792
     * message and additional info.
Packit Service 30b792
     * @async
Packit Service 30b792
     */
Packit Service 30b792
    encrypt ({ data, publicKeys, secretKeys, base64 = false, armor = true,
Packit Service 30b792
        wildcard, always_trust = true, expect = 'base64',
Packit Service 30b792
        additional = {} } = {}){
Packit Service 30b792
        if (typeof arguments[0] !== 'object') {
Packit Service 30b792
            return Promise.reject(gpgme_error('PARAM_WRONG'));
Packit Service 30b792
        }
Packit Service 30b792
        if (!data || !publicKeys){
Packit Service 30b792
            return Promise.reject(gpgme_error('MSG_INCOMPLETE'));
Packit Service 30b792
        }
Packit Service 30b792
        let msg = createMessage('encrypt');
Packit Service 30b792
        if (msg instanceof Error){
Packit Service 30b792
            return Promise.reject(msg);
Packit Service 30b792
        }
Packit Service 30b792
        if (armor === false){
Packit Service 30b792
            msg.setParameter('armor', false);
Packit Service 30b792
            if (expect === 'uint8' || expect === 'base64') {
Packit Service 30b792
                msg.expected = expect;
Packit Service 30b792
            } else {
Packit Service 30b792
                return Promise.reject(gpgme_error('PARAM_WRONG'));
Packit Service 30b792
            }
Packit Service 30b792
        } else if (armor === true) {
Packit Service 30b792
            msg.setParameter('armor', true);
Packit Service 30b792
        }
Packit Service 30b792
        if (base64 === true) {
Packit Service 30b792
            msg.setParameter('base64', true);
Packit Service 30b792
        }
Packit Service 30b792
        if (always_trust === true) {
Packit Service 30b792
            msg.setParameter('always-trust', true);
Packit Service 30b792
        }
Packit Service 30b792
        let pubkeys = toKeyIdArray(publicKeys);
Packit Service 30b792
        if (!pubkeys.length) {
Packit Service 30b792
            return Promise.reject(gpgme_error('MSG_NO_KEYS'));
Packit Service 30b792
        }
Packit Service 30b792
        msg.setParameter('keys', pubkeys);
Packit Service 30b792
        let sigkeys = toKeyIdArray(secretKeys);
Packit Service 30b792
        if (sigkeys.length > 0) {
Packit Service 30b792
            msg.setParameter('signing_keys', sigkeys);
Packit Service 30b792
        }
Packit Service 30b792
        putData(msg, data);
Packit Service 30b792
        if (wildcard === true){
Packit Service 30b792
            msg.setParameter('throw-keyids', true);
Packit Service 30b792
        }
Packit Service 30b792
        if (additional){
Packit Service 30b792
            let additional_Keys = Object.keys(additional);
Packit Service 30b792
            for (let k = 0; k < additional_Keys.length; k++) {
Packit Service 30b792
                try {
Packit Service 30b792
                    msg.setParameter(additional_Keys[k],
Packit Service 30b792
                        additional[additional_Keys[k]]);
Packit Service 30b792
                }
Packit Service 30b792
                catch (error){
Packit Service 30b792
                    return Promise.reject(error);
Packit Service 30b792
                }
Packit Service 30b792
            }
Packit Service 30b792
        }
Packit Service 30b792
        if (msg.isComplete() === true){
Packit Service 30b792
            return msg.post();
Packit Service 30b792
        } else {
Packit Service 30b792
            return Promise.reject(gpgme_error('MSG_INCOMPLETE'));
Packit Service 30b792
        }
Packit Service 30b792
    }
Packit Service 30b792
Packit Service 30b792
    /**
Packit Service 30b792
    * Decrypts (and verifies, if applicable) a message.
Packit Service 30b792
    * @param {Object} options
Packit Service 30b792
    * @param {String|Object} options.data text/data to be decrypted. Accepts
Packit Service 30b792
    * Strings and Objects with a getText method.
Packit Service 30b792
    * @param {Boolean} options.base64 (optional, default: false). Indicate that
Packit Service 30b792
    * the input given is base64-encoded binary instead of an armored block in
Packit Service 30b792
    * gpg armored form.
Packit Service 30b792
    * @param {String} options.expect (optional). By default, the output is
Packit Service 30b792
    * expected to be a string compatible with javascript. In cases of binary
Packit Service 30b792
    * data the decryption may fail due to encoding problems. For data expected
Packit Service 30b792
    * to return as binary data, the decroding after decryption can be bypassed:
Packit Service 30b792
    * 
Packit Service 30b792
    *   'uint8': Return as Uint8Array
Packit Service 30b792
    *   'base64': Return as unprocessed (base64 encoded) string.
Packit Service 30b792
    * 
Packit Service 30b792
    * @returns {Promise<decrypt_result>} Decrypted Message and information
Packit Service 30b792
    * @async
Packit Service 30b792
    */
Packit Service 30b792
    decrypt ({ data, base64, expect } = {}){
Packit Service 30b792
        if (typeof arguments[0] !== 'object') {
Packit Service 30b792
            return Promise.reject(gpgme_error('PARAM_WRONG'));
Packit Service 30b792
        }
Packit Service 30b792
        if (!data){
Packit Service 30b792
            return Promise.reject(gpgme_error('MSG_EMPTY'));
Packit Service 30b792
        }
Packit Service 30b792
        let msg = createMessage('decrypt');
Packit Service 30b792
Packit Service 30b792
        if (msg instanceof Error){
Packit Service 30b792
            return Promise.reject(msg);
Packit Service 30b792
        }
Packit Service 30b792
        if (base64 === true){
Packit Service 30b792
            msg.setParameter('base64', true);
Packit Service 30b792
        }
Packit Service 30b792
        if (expect === 'base64' || expect === 'uint8'){
Packit Service 30b792
            msg.expected = expect;
Packit Service 30b792
        }
Packit Service 30b792
        putData(msg, data);
Packit Service 30b792
        return new Promise(function (resolve, reject){
Packit Service 30b792
            msg.post().then(function (result){
Packit Service 30b792
                let returnValue = { data: result.data };
Packit Service 30b792
                returnValue.format = result.format ? result.format : null;
Packit Service 30b792
                if (result.hasOwnProperty('dec_info')){
Packit Service 30b792
                    returnValue.is_mime = result.dec_info.is_mime ? true: false;
Packit Service 30b792
                    if (result.dec_info.file_name) {
Packit Service 30b792
                        returnValue.file_name = result.dec_info.file_name;
Packit Service 30b792
                    }
Packit Service 30b792
                }
Packit Service 30b792
                if (!returnValue.file_name) {
Packit Service 30b792
                    returnValue.file_name = null;
Packit Service 30b792
                }
Packit Service 30b792
                if (result.hasOwnProperty('info')
Packit Service 30b792
                    && result.info.hasOwnProperty('signatures')
Packit Service 30b792
                    && Array.isArray(result.info.signatures)
Packit Service 30b792
                ) {
Packit Service 30b792
                    returnValue.signatures = collectSignatures(
Packit Service 30b792
                        result.info.signatures);
Packit Service 30b792
                }
Packit Service 30b792
                if (returnValue.signatures instanceof Error){
Packit Service 30b792
                    reject(returnValue.signatures);
Packit Service 30b792
                } else {
Packit Service 30b792
                    resolve(returnValue);
Packit Service 30b792
                }
Packit Service 30b792
            }, function (error){
Packit Service 30b792
                reject(error);
Packit Service 30b792
            });
Packit Service 30b792
        });
Packit Service 30b792
    }
Packit Service 30b792
Packit Service 30b792
    /**
Packit Service 30b792
     * Sign a Message.
Packit Service 30b792
     * @param {Object} options Signing options
Packit Service 30b792
     * @param {String|Object} options.data text/data to be signed. Accepts
Packit Service 30b792
     * Strings and Objects with a getText method.
Packit Service 30b792
     * @param {inputKeys} options.keys The key/keys to use for signing
Packit Service 30b792
     * @param {String} options.mode The signing mode. Currently supported:
Packit Service 30b792
     * 
Packit Service 30b792
     *      'clearsign':The Message is embedded into the signature;
Packit Service 30b792
     *      'detached': The signature is stored separately
Packit Service 30b792
     * 
Packit Service 30b792
     * @param {Boolean} options.base64 input is considered base64
Packit Service 30b792
     * @returns {Promise<signResult>}
Packit Service 30b792
     * @async
Packit Service 30b792
     */
Packit Service 30b792
    sign ({ data, keys, mode = 'clearsign', base64 } = {}){
Packit Service 30b792
        if (typeof arguments[0] !== 'object') {
Packit Service 30b792
            return Promise.reject(gpgme_error('PARAM_WRONG'));
Packit Service 30b792
        }
Packit Service 30b792
        if (!data){
Packit Service 30b792
            return Promise.reject(gpgme_error('MSG_EMPTY'));
Packit Service 30b792
        }
Packit Service 30b792
        let key_arr = toKeyIdArray(keys);
Packit Service 30b792
        if (key_arr.length === 0){
Packit Service 30b792
            return Promise.reject(gpgme_error('MSG_NO_KEYS'));
Packit Service 30b792
        }
Packit Service 30b792
Packit Service 30b792
        let msg = createMessage('sign');
Packit Service 30b792
        msg.setParameter('keys', key_arr);
Packit Service 30b792
        if (base64 === true){
Packit Service 30b792
            msg.setParameter('base64', true);
Packit Service 30b792
        }
Packit Service 30b792
        msg.setParameter('mode', mode);
Packit Service 30b792
        putData(msg, data);
Packit Service 30b792
Packit Service 30b792
        return new Promise(function (resolve,reject) {
Packit Service 30b792
            msg.post().then( function (message) {
Packit Service 30b792
                if (mode === 'clearsign'){
Packit Service 30b792
                    resolve({
Packit Service 30b792
                        data: message.data }
Packit Service 30b792
                    );
Packit Service 30b792
                } else if (mode === 'detached') {
Packit Service 30b792
                    resolve({
Packit Service 30b792
                        data: data,
Packit Service 30b792
                        signature: message.data
Packit Service 30b792
                    });
Packit Service 30b792
                }
Packit Service 30b792
            }, function (error){
Packit Service 30b792
                reject(error);
Packit Service 30b792
            });
Packit Service 30b792
        });
Packit Service 30b792
    }
Packit Service 30b792
Packit Service 30b792
    /**
Packit Service 30b792
     * Verifies data.
Packit Service 30b792
     * @param {Object} options
Packit Service 30b792
     * @param {String|Object} options.data text/data to be verified. Accepts
Packit Service 30b792
     * Strings and Objects with a getText method
Packit Service 30b792
     * @param {String} options.signature A detached signature. If not present,
Packit Service 30b792
     * opaque mode is assumed
Packit Service 30b792
     * @param {Boolean} options.base64 Indicating that data and signature are
Packit Service 30b792
     * base64 encoded
Packit Service 30b792
     * @returns {Promise<verifyResult>}
Packit Service 30b792
     *@async
Packit Service 30b792
    */
Packit Service 30b792
    verify ({ data, signature, base64 } = {}){
Packit Service 30b792
        if (typeof arguments[0] !== 'object') {
Packit Service 30b792
            return Promise.reject(gpgme_error('PARAM_WRONG'));
Packit Service 30b792
        }
Packit Service 30b792
        if (!data){
Packit Service 30b792
            return Promise.reject(gpgme_error('PARAM_WRONG'));
Packit Service 30b792
        }
Packit Service 30b792
        let msg = createMessage('verify');
Packit Service 30b792
        let dt = putData(msg, data);
Packit Service 30b792
        if (dt instanceof Error){
Packit Service 30b792
            return Promise.reject(dt);
Packit Service 30b792
        }
Packit Service 30b792
        if (signature){
Packit Service 30b792
            if (typeof signature !== 'string'){
Packit Service 30b792
                return Promise.reject(gpgme_error('PARAM_WRONG'));
Packit Service 30b792
            } else {
Packit Service 30b792
                msg.setParameter('signature', signature);
Packit Service 30b792
            }
Packit Service 30b792
        }
Packit Service 30b792
        if (base64 === true){
Packit Service 30b792
            msg.setParameter('base64', true);
Packit Service 30b792
        }
Packit Service 30b792
        return new Promise(function (resolve, reject){
Packit Service 30b792
            msg.post().then(function (message){
Packit Service 30b792
                if (!message.info || !message.info.signatures){
Packit Service 30b792
                    reject(gpgme_error('SIG_NO_SIGS'));
Packit Service 30b792
                } else {
Packit Service 30b792
                    let returnValue = {
Packit Service 30b792
                        signatures: collectSignatures(message.info.signatures)
Packit Service 30b792
                    };
Packit Service 30b792
                    if (returnValue.signatures instanceof Error){
Packit Service 30b792
                        reject(returnValue.signatures);
Packit Service 30b792
                    } else {
Packit Service 30b792
                        returnValue.is_mime = message.info.is_mime? true: false;
Packit Service 30b792
                        if (message.info.filename){
Packit Service 30b792
                            returnValue.file_name = message.info.filename;
Packit Service 30b792
                        }
Packit Service 30b792
                        returnValue.data = message.data;
Packit Service 30b792
                        resolve(returnValue);
Packit Service 30b792
                    }
Packit Service 30b792
                }
Packit Service 30b792
            }, function (error){
Packit Service 30b792
                reject(error);
Packit Service 30b792
            });
Packit Service 30b792
        });
Packit Service 30b792
    }
Packit Service 30b792
}
Packit Service 30b792
Packit Service 30b792
/**
Packit Service 30b792
 * Sets the data of the message, setting flags according on the data type
Packit Service 30b792
 * @param {GPGME_Message} message The message where this data will be set
Packit Service 30b792
 * @param { String| Object } data The data to enter. Expects either a string of
Packit Service 30b792
 * data, or an object with a getText method
Packit Service 30b792
 * @returns {undefined| GPGME_Error} Error if not successful, nothing otherwise
Packit Service 30b792
 * @private
Packit Service 30b792
 */
Packit Service 30b792
function putData (message, data){
Packit Service 30b792
    if (!message || !(message instanceof GPGME_Message)) {
Packit Service 30b792
        return gpgme_error('PARAM_WRONG');
Packit Service 30b792
    }
Packit Service 30b792
    if (!data){
Packit Service 30b792
        return gpgme_error('PARAM_WRONG');
Packit Service 30b792
    } else if (typeof data === 'string') {
Packit Service 30b792
        message.setParameter('data', data);
Packit Service 30b792
    } else if (
Packit Service 30b792
        (typeof data === 'object') &&
Packit Service 30b792
        (typeof data.getText === 'function')
Packit Service 30b792
    ){
Packit Service 30b792
        let txt = data.getText();
Packit Service 30b792
        if (typeof txt === 'string'){
Packit Service 30b792
            message.setParameter('data', txt);
Packit Service 30b792
        } else {
Packit Service 30b792
            return gpgme_error('PARAM_WRONG');
Packit Service 30b792
        }
Packit Service 30b792
Packit Service 30b792
    } else {
Packit Service 30b792
        return gpgme_error('PARAM_WRONG');
Packit Service 30b792
    }
Packit Service 30b792
}
Packit Service 30b792
Packit Service 30b792
/**
Packit Service 30b792
 * Parses, validates and converts incoming objects into signatures.
Packit Service 30b792
 * @param {Array<Object>} sigs
Packit Service 30b792
 * @returns {signatureDetails} Details about the signatures
Packit Service 30b792
 * @private
Packit Service 30b792
 */
Packit Service 30b792
function collectSignatures (sigs){
Packit Service 30b792
    if (!Array.isArray(sigs)){
Packit Service 30b792
        return gpgme_error('SIG_NO_SIGS');
Packit Service 30b792
    }
Packit Service 30b792
    let summary = {
Packit Service 30b792
        all_valid: false,
Packit Service 30b792
        count: sigs.length,
Packit Service 30b792
        failures: 0,
Packit Service 30b792
        signatures: {
Packit Service 30b792
            good: [],
Packit Service 30b792
            bad: [],
Packit Service 30b792
        }
Packit Service 30b792
    };
Packit Service 30b792
    for (let i=0; i< sigs.length; i++){
Packit Service 30b792
        let sigObj = createSignature(sigs[i]);
Packit Service 30b792
        if (sigObj instanceof Error) {
Packit Service 30b792
            return gpgme_error('SIG_WRONG');
Packit Service 30b792
        }
Packit Service 30b792
        if (sigObj.valid !== true){
Packit Service 30b792
            summary.failures += 1;
Packit Service 30b792
            summary.signatures.bad.push(sigObj);
Packit Service 30b792
        } else {
Packit Service 30b792
            summary.signatures.good.push(sigObj);
Packit Service 30b792
        }
Packit Service 30b792
    }
Packit Service 30b792
    if (summary.failures === 0){
Packit Service 30b792
        summary.all_valid = true;
Packit Service 30b792
    }
Packit Service 30b792
    return summary;
Packit Service 30b792
}