Blame lang/js/src/Key.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 { isFingerprint, isLongId } from './Helpers';
Packit Service 30b792
import { gpgme_error } from './Errors';
Packit Service 30b792
import { createMessage } from './Message';
Packit Service 30b792
Packit Service 30b792
/**
Packit Service 30b792
 * Validates the given fingerprint and creates a new {@link GPGME_Key}
Packit Service 30b792
 * @param {String} fingerprint
Packit Service 30b792
 * @param {Boolean} async If True, Key properties (except fingerprint) will be
Packit Service 30b792
 * queried from gnupg on each call, making the operation up-to-date, the
Packit Service 30b792
 * answers will be Promises, and the performance will likely suffer
Packit Service 30b792
 * @param {Object} data additional initial properties this Key will have. Needs
Packit Service 30b792
 * a full object as delivered by gpgme-json
Packit Service 30b792
 * @returns {Object} The verified and updated data
Packit Service 30b792
 */
Packit Service 30b792
export function createKey (fingerprint, async = false, data){
Packit Service 30b792
    if (!isFingerprint(fingerprint) || typeof (async) !== 'boolean'){
Packit Service 30b792
        throw gpgme_error('PARAM_WRONG');
Packit Service 30b792
    }
Packit Service 30b792
    if (data !== undefined){
Packit Service 30b792
        data = validateKeyData(fingerprint, data);
Packit Service 30b792
    }
Packit Service 30b792
    if (data instanceof Error){
Packit Service 30b792
        throw gpgme_error('KEY_INVALID');
Packit Service 30b792
    } else {
Packit Service 30b792
        return new GPGME_Key(fingerprint, async, data);
Packit Service 30b792
    }
Packit Service 30b792
}
Packit Service 30b792
Packit Service 30b792
/**
Packit Service 30b792
 * Represents the Keys as stored in the gnupg backend. A key is defined by a
Packit Service 30b792
 * fingerprint.
Packit Service 30b792
 * A key cannot be directly created via the new operator, please use
Packit Service 30b792
 * {@link createKey} instead.
Packit Service 30b792
 * A GPGME_Key object allows to query almost all information defined in gpgme
Packit Service 30b792
 * Keys. It offers two modes, async: true/false. In async mode, Key properties
Packit Service 30b792
 * with the exception of the fingerprint will be queried from gnupg on each
Packit Service 30b792
 * call, making the operation up-to-date, the answers will be Promises, and
Packit Service 30b792
 * the performance will likely suffer. In Sync modes, all information except
Packit Service 30b792
 * for the armored Key export will be cached and can be refreshed by
Packit Service 30b792
 * [refreshKey]{@link GPGME_Key#refreshKey}.
Packit Service 30b792
 *
Packit Service 30b792
 * 
Packit Service 30b792
 * see also:
Packit Service 30b792
 *      {@link GPGME_UserId} user Id objects
Packit Service 30b792
 *      {@link GPGME_Subkey} subKey objects
Packit Service 30b792
 * 
Packit Service 30b792
 * For other Key properteis, refer to {@link validKeyProperties},
Packit Service 30b792
 * and to the [gpgme documentation]{@link https://www.gnupg.org/documentation/manuals/gpgme/Key-objects.html}
Packit Service 30b792
 * for meanings and further details.
Packit Service 30b792
 *
Packit Service 30b792
 * @class
Packit Service 30b792
 */
Packit Service 30b792
class GPGME_Key {
Packit Service 30b792
Packit Service 30b792
    constructor (fingerprint, async, data){
Packit Service 30b792
Packit Service 30b792
        /**
Packit Service 30b792
         * @property {Boolean} _async If true, the Key was initialized without
Packit Service 30b792
         * cached data
Packit Service 30b792
         */
Packit Service 30b792
        this._async = async;
Packit Service 30b792
Packit Service 30b792
        this._data = { fingerprint: fingerprint.toUpperCase() };
Packit Service 30b792
        if (data !== undefined
Packit Service 30b792
            && data.fingerprint.toUpperCase() === this._data.fingerprint
Packit Service 30b792
        ) {
Packit Service 30b792
            this._data = data;
Packit Service 30b792
        }
Packit Service 30b792
    }
Packit Service 30b792
Packit Service 30b792
    /**
Packit Service 30b792
     * Query any property of the Key listed in {@link validKeyProperties}
Packit Service 30b792
     * @param {String} property property to be retrieved
Packit Service 30b792
     * @returns {Boolean| String | Date | Array | Object}
Packit Service 30b792
     * @returns {Promise<Boolean| String | Date | Array | Object>} (if in async
Packit Service 30b792
     * mode)
Packit Service 30b792
     * 
Packit Service 30b792
     * Returns the value of the property requested. If the Key is set to async,
Packit Service 30b792
     * the value will be fetched from gnupg and resolved as a Promise. If Key
Packit Service 30b792
     * is not  async, the armored property is not available (it can still be
Packit Service 30b792
     * retrieved asynchronously by [getArmor]{@link GPGME_Key#getArmor})
Packit Service 30b792
     */
Packit Service 30b792
    get (property) {
Packit Service 30b792
        if (this._async === true) {
Packit Service 30b792
            switch (property){
Packit Service 30b792
            case 'armored':
Packit Service 30b792
                return this.getArmor();
Packit Service 30b792
            case 'hasSecret':
Packit Service 30b792
                return this.getGnupgSecretState();
Packit Service 30b792
            default:
Packit Service 30b792
                return getGnupgState(this.fingerprint, property);
Packit Service 30b792
            }
Packit Service 30b792
        } else {
Packit Service 30b792
            if (property === 'armored') {
Packit Service 30b792
                throw gpgme_error('KEY_ASYNC_ONLY');
Packit Service 30b792
            }
Packit Service 30b792
            // eslint-disable-next-line no-use-before-define
Packit Service 30b792
            if (!validKeyProperties.hasOwnProperty(property)){
Packit Service 30b792
                throw gpgme_error('PARAM_WRONG');
Packit Service 30b792
            } else {
Packit Service 30b792
                return (this._data[property]);
Packit Service 30b792
            }
Packit Service 30b792
        }
Packit Service 30b792
    }
Packit Service 30b792
Packit Service 30b792
    /**
Packit Service 30b792
     * Reloads the Key information from gnupg. This is only useful if the Key
Packit Service 30b792
     * use the GPGME_Keys cached. Note that this is a performance hungry
Packit Service 30b792
     * operation. If you desire more than a few refreshs, it may be
Packit Service 30b792
     * advisable to run [Keyring.getKeys]{@link Keyring#getKeys} instead.
Packit Service 30b792
     * @returns {Promise<GPGME_Key>}
Packit Service 30b792
     * @async
Packit Service 30b792
     */
Packit Service 30b792
    refreshKey () {
Packit Service 30b792
        let me = this;
Packit Service 30b792
        return new Promise(function (resolve, reject) {
Packit Service 30b792
            if (!me._data.fingerprint){
Packit Service 30b792
                reject(gpgme_error('KEY_INVALID'));
Packit Service 30b792
            }
Packit Service 30b792
            let msg = createMessage('keylist');
Packit Service 30b792
            msg.setParameter('sigs', true);
Packit Service 30b792
            msg.setParameter('keys', me._data.fingerprint);
Packit Service 30b792
            msg.post().then(function (result){
Packit Service 30b792
                if (result.keys.length === 1){
Packit Service 30b792
                    const newdata = validateKeyData(
Packit Service 30b792
                        me._data.fingerprint, result.keys[0]);
Packit Service 30b792
                    if (newdata instanceof Error){
Packit Service 30b792
                        reject(gpgme_error('KEY_INVALID'));
Packit Service 30b792
                    } else {
Packit Service 30b792
                        me._data = newdata;
Packit Service 30b792
                        me.getGnupgSecretState().then(function (){
Packit Service 30b792
                            me.getArmor().then(function (){
Packit Service 30b792
                                resolve(me);
Packit Service 30b792
                            }, function (error){
Packit Service 30b792
                                reject(error);
Packit Service 30b792
                            });
Packit Service 30b792
                        }, function (error){
Packit Service 30b792
                            reject(error);
Packit Service 30b792
                        });
Packit Service 30b792
                    }
Packit Service 30b792
                } else {
Packit Service 30b792
                    reject(gpgme_error('KEY_NOKEY'));
Packit Service 30b792
                }
Packit Service 30b792
            }, function (error) {
Packit Service 30b792
                reject(gpgme_error('GNUPG_ERROR'), error);
Packit Service 30b792
            });
Packit Service 30b792
        });
Packit Service 30b792
    }
Packit Service 30b792
Packit Service 30b792
    /**
Packit Service 30b792
     * Query the armored block of the Key directly from gnupg. Please note
Packit Service 30b792
     * that this will not get you any export of the secret/private parts of
Packit Service 30b792
     * a Key
Packit Service 30b792
     * @returns {Promise<String>}
Packit Service 30b792
     * @async
Packit Service 30b792
     */
Packit Service 30b792
    getArmor () {
Packit Service 30b792
        const me = this;
Packit Service 30b792
        return new Promise(function (resolve, reject) {
Packit Service 30b792
            if (!me._data.fingerprint){
Packit Service 30b792
                reject(gpgme_error('KEY_INVALID'));
Packit Service 30b792
            }
Packit Service 30b792
            let msg = createMessage('export');
Packit Service 30b792
            msg.setParameter('armor', true);
Packit Service 30b792
            msg.setParameter('keys', me._data.fingerprint);
Packit Service 30b792
            msg.post().then(function (result){
Packit Service 30b792
                resolve(result.data);
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
     * Find out if the Key is part of a Key pair including public and
Packit Service 30b792
     * private key(s). If you want this information about more than a few
Packit Service 30b792
     * Keys in synchronous mode, it may be advisable to run
Packit Service 30b792
     * [Keyring.getKeys]{@link Keyring#getKeys} instead, as it performs faster
Packit Service 30b792
     * in bulk querying.
Packit Service 30b792
     * @returns {Promise<Boolean>} True if a private Key is available in the
Packit Service 30b792
     * gnupg Keyring.
Packit Service 30b792
     * @async
Packit Service 30b792
     */
Packit Service 30b792
    getGnupgSecretState (){
Packit Service 30b792
        const me = this;
Packit Service 30b792
        return new Promise(function (resolve, reject) {
Packit Service 30b792
            if (!me._data.fingerprint){
Packit Service 30b792
                reject(gpgme_error('KEY_INVALID'));
Packit Service 30b792
            } else {
Packit Service 30b792
                let msg = createMessage('keylist');
Packit Service 30b792
                msg.setParameter('keys', me._data.fingerprint);
Packit Service 30b792
                msg.setParameter('secret', true);
Packit Service 30b792
                msg.post().then(function (result){
Packit Service 30b792
                    me._data.hasSecret = null;
Packit Service 30b792
                    if (
Packit Service 30b792
                        result.keys &&
Packit Service 30b792
                        result.keys.length === 1 &&
Packit Service 30b792
                        result.keys[0].secret === true
Packit Service 30b792
                    ) {
Packit Service 30b792
                        me._data.hasSecret = true;
Packit Service 30b792
                        resolve(true);
Packit Service 30b792
                    } else {
Packit Service 30b792
                        me._data.hasSecret = false;
Packit Service 30b792
                        resolve(false);
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
     * Deletes the (public) Key from the GPG Keyring. Note that a deletion
Packit Service 30b792
     * of a secret key is not supported by the native backend, and gnupg will
Packit Service 30b792
     * refuse to delete a Key if there is still a secret/private Key present
Packit Service 30b792
     * to that public Key
Packit Service 30b792
     * @returns {Promise<Boolean>} Success if key was deleted.
Packit Service 30b792
     */
Packit Service 30b792
    delete (){
Packit Service 30b792
        const me = this;
Packit Service 30b792
        return new Promise(function (resolve, reject){
Packit Service 30b792
            if (!me._data.fingerprint){
Packit Service 30b792
                reject(gpgme_error('KEY_INVALID'));
Packit Service 30b792
            }
Packit Service 30b792
            let msg = createMessage('delete');
Packit Service 30b792
            msg.setParameter('key', me._data.fingerprint);
Packit Service 30b792
            msg.post().then(function (result){
Packit Service 30b792
                resolve(result.success);
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
     * @returns {String} The fingerprint defining this Key. Convenience getter
Packit Service 30b792
     */
Packit Service 30b792
    get fingerprint (){
Packit Service 30b792
        return this._data.fingerprint;
Packit Service 30b792
    }
Packit Service 30b792
}
Packit Service 30b792
Packit Service 30b792
/**
Packit Service 30b792
 * Representing a subkey of a Key. See {@link validSubKeyProperties} for
Packit Service 30b792
 * possible properties.
Packit Service 30b792
 * @class
Packit Service 30b792
 * @protected
Packit Service 30b792
 */
Packit Service 30b792
class GPGME_Subkey {
Packit Service 30b792
Packit Service 30b792
    /**
Packit Service 30b792
     * Initializes with the json data sent by gpgme-json
Packit Service 30b792
     * @param {Object} data
Packit Service 30b792
     * @private
Packit Service 30b792
     */
Packit Service 30b792
    constructor (data){
Packit Service 30b792
        this._data = {};
Packit Service 30b792
        let keys = Object.keys(data);
Packit Service 30b792
        const me = this;
Packit Service 30b792
Packit Service 30b792
        /**
Packit Service 30b792
         * Validates a subkey property against {@link validSubKeyProperties} and
Packit Service 30b792
         * sets it if validation is successful
Packit Service 30b792
         * @param {String} property
Packit Service 30b792
         * @param {*} value
Packit Service 30b792
         * @param private
Packit Service 30b792
         */
Packit Service 30b792
        const setProperty = function (property, value){
Packit Service 30b792
            // eslint-disable-next-line no-use-before-define
Packit Service 30b792
            if (validSubKeyProperties.hasOwnProperty(property)){
Packit Service 30b792
                // eslint-disable-next-line no-use-before-define
Packit Service 30b792
                if (validSubKeyProperties[property](value) === true) {
Packit Service 30b792
                    if (property === 'timestamp' || property === 'expires'){
Packit Service 30b792
                        me._data[property] = new Date(value * 1000);
Packit Service 30b792
                    } else {
Packit Service 30b792
                        me._data[property] = value;
Packit Service 30b792
                    }
Packit Service 30b792
                }
Packit Service 30b792
            }
Packit Service 30b792
        };
Packit Service 30b792
        for (let i=0; i< keys.length; i++) {
Packit Service 30b792
            setProperty(keys[i], data[keys[i]]);
Packit Service 30b792
        }
Packit Service 30b792
    }
Packit Service 30b792
Packit Service 30b792
    /**
Packit Service 30b792
     * Fetches any information about this subkey
Packit Service 30b792
     * @param {String} property Information to request
Packit Service 30b792
     * @returns {String | Number | Date}
Packit Service 30b792
     */
Packit Service 30b792
    get (property) {
Packit Service 30b792
        if (this._data.hasOwnProperty(property)){
Packit Service 30b792
            return (this._data[property]);
Packit Service 30b792
        }
Packit Service 30b792
    }
Packit Service 30b792
Packit Service 30b792
}
Packit Service 30b792
Packit Service 30b792
/**
Packit Service 30b792
 * Representing user attributes associated with a Key or subkey. See
Packit Service 30b792
 * {@link validUserIdProperties} for possible properties.
Packit Service 30b792
 * @class
Packit Service 30b792
 * @protected
Packit Service 30b792
 */
Packit Service 30b792
class GPGME_UserId {
Packit Service 30b792
Packit Service 30b792
    /**
Packit Service 30b792
     * Initializes with the json data sent by gpgme-json
Packit Service 30b792
     * @param {Object} data
Packit Service 30b792
     * @private
Packit Service 30b792
     */
Packit Service 30b792
    constructor (data){
Packit Service 30b792
        this._data = {};
Packit Service 30b792
        const me = this;
Packit Service 30b792
        let keys = Object.keys(data);
Packit Service 30b792
        const setProperty = function (property, value){
Packit Service 30b792
            // eslint-disable-next-line no-use-before-define
Packit Service 30b792
            if (validUserIdProperties.hasOwnProperty(property)){
Packit Service 30b792
                // eslint-disable-next-line no-use-before-define
Packit Service 30b792
                if (validUserIdProperties[property](value) === true) {
Packit Service 30b792
                    if (property === 'last_update'){
Packit Service 30b792
                        me._data[property] = new Date(value*1000);
Packit Service 30b792
                    } else {
Packit Service 30b792
                        me._data[property] = value;
Packit Service 30b792
                    }
Packit Service 30b792
                }
Packit Service 30b792
            }
Packit Service 30b792
        };
Packit Service 30b792
        for (let i=0; i< keys.length; i++) {
Packit Service 30b792
            setProperty(keys[i], data[keys[i]]);
Packit Service 30b792
        }
Packit Service 30b792
    }
Packit Service 30b792
Packit Service 30b792
    /**
Packit Service 30b792
     * Fetches information about the user
Packit Service 30b792
     * @param {String} property Information to request
Packit Service 30b792
     * @returns {String | Number}
Packit Service 30b792
     */
Packit Service 30b792
    get (property) {
Packit Service 30b792
        if (this._data.hasOwnProperty(property)){
Packit Service 30b792
            return (this._data[property]);
Packit Service 30b792
        }
Packit Service 30b792
    }
Packit Service 30b792
Packit Service 30b792
}
Packit Service 30b792
Packit Service 30b792
/**
Packit Service 30b792
 * Validation definition for userIds. Each valid userId property is represented
Packit Service 30b792
 * as a key- Value pair, with their value being a validation function to check
Packit Service 30b792
 * against
Packit Service 30b792
 * @protected
Packit Service 30b792
 * @const
Packit Service 30b792
 */
Packit Service 30b792
const validUserIdProperties = {
Packit Service 30b792
    'revoked': function (value){
Packit Service 30b792
        return typeof (value) === 'boolean';
Packit Service 30b792
    },
Packit Service 30b792
    'invalid':  function (value){
Packit Service 30b792
        return typeof (value) === 'boolean';
Packit Service 30b792
    },
Packit Service 30b792
    'uid': function (value){
Packit Service 30b792
        if (typeof (value) === 'string' || value === ''){
Packit Service 30b792
            return true;
Packit Service 30b792
        }
Packit Service 30b792
        return false;
Packit Service 30b792
    },
Packit Service 30b792
    'validity': function (value){
Packit Service 30b792
        if (typeof (value) === 'string'){
Packit Service 30b792
            return true;
Packit Service 30b792
        }
Packit Service 30b792
        return false;
Packit Service 30b792
    },
Packit Service 30b792
    'name': function (value){
Packit Service 30b792
        if (typeof (value) === 'string' || value === ''){
Packit Service 30b792
            return true;
Packit Service 30b792
        }
Packit Service 30b792
        return false;
Packit Service 30b792
    },
Packit Service 30b792
    'email': function (value){
Packit Service 30b792
        if (typeof (value) === 'string' || value === ''){
Packit Service 30b792
            return true;
Packit Service 30b792
        }
Packit Service 30b792
        return false;
Packit Service 30b792
    },
Packit Service 30b792
    'address': function (value){
Packit Service 30b792
        if (typeof (value) === 'string' || value === ''){
Packit Service 30b792
            return true;
Packit Service 30b792
        }
Packit Service 30b792
        return false;
Packit Service 30b792
    },
Packit Service 30b792
    'comment': function (value){
Packit Service 30b792
        if (typeof (value) === 'string' || value === ''){
Packit Service 30b792
            return true;
Packit Service 30b792
        }
Packit Service 30b792
        return false;
Packit Service 30b792
    },
Packit Service 30b792
    'origin':  function (value){
Packit Service 30b792
        return Number.isInteger(value);
Packit Service 30b792
    },
Packit Service 30b792
    'last_update':  function (value){
Packit Service 30b792
        return Number.isInteger(value);
Packit Service 30b792
    }
Packit Service 30b792
};
Packit Service 30b792
Packit Service 30b792
/**
Packit Service 30b792
 * Validation definition for subKeys. Each valid userId property is represented
Packit Service 30b792
 * as a key-value pair, with the value being a validation function
Packit Service 30b792
 * @protected
Packit Service 30b792
 * @const
Packit Service 30b792
 */
Packit Service 30b792
const validSubKeyProperties = {
Packit Service 30b792
    'invalid': function (value){
Packit Service 30b792
        return typeof (value) === 'boolean';
Packit Service 30b792
    },
Packit Service 30b792
    'can_encrypt': function (value){
Packit Service 30b792
        return typeof (value) === 'boolean';
Packit Service 30b792
    },
Packit Service 30b792
    'can_sign': function (value){
Packit Service 30b792
        return typeof (value) === 'boolean';
Packit Service 30b792
    },
Packit Service 30b792
    'can_certify':  function (value){
Packit Service 30b792
        return typeof (value) === 'boolean';
Packit Service 30b792
    },
Packit Service 30b792
    'can_authenticate':  function (value){
Packit Service 30b792
        return typeof (value) === 'boolean';
Packit Service 30b792
    },
Packit Service 30b792
    'secret': function (value){
Packit Service 30b792
        return typeof (value) === 'boolean';
Packit Service 30b792
    },
Packit Service 30b792
    'is_qualified': function (value){
Packit Service 30b792
        return typeof (value) === 'boolean';
Packit Service 30b792
    },
Packit Service 30b792
    'is_cardkey':  function (value){
Packit Service 30b792
        return typeof (value) === 'boolean';
Packit Service 30b792
    },
Packit Service 30b792
    'is_de_vs':  function (value){
Packit Service 30b792
        return typeof (value) === 'boolean';
Packit Service 30b792
    },
Packit Service 30b792
    'pubkey_algo_name': function (value){
Packit Service 30b792
        return typeof (value) === 'string';
Packit Service 30b792
        // TODO: check against list of known?['']
Packit Service 30b792
    },
Packit Service 30b792
    'pubkey_algo_string': function (value){
Packit Service 30b792
        return typeof (value) === 'string';
Packit Service 30b792
        // TODO: check against list of known?['']
Packit Service 30b792
    },
Packit Service 30b792
    'keyid': function (value){
Packit Service 30b792
        return isLongId(value);
Packit Service 30b792
    },
Packit Service 30b792
    'pubkey_algo': function (value) {
Packit Service 30b792
        return (Number.isInteger(value) && value >= 0);
Packit Service 30b792
    },
Packit Service 30b792
    'length': function (value){
Packit Service 30b792
        return (Number.isInteger(value) && value > 0);
Packit Service 30b792
    },
Packit Service 30b792
    'timestamp': function (value){
Packit Service 30b792
        return (Number.isInteger(value) && value > 0);
Packit Service 30b792
    },
Packit Service 30b792
    'expires': function (value){
Packit Service 30b792
        return (Number.isInteger(value) && value > 0);
Packit Service 30b792
    }
Packit Service 30b792
};
Packit Service 30b792
Packit Service 30b792
/**
Packit Service 30b792
 * Validation definition for Keys. Each valid Key property is represented
Packit Service 30b792
 * as a key-value pair, with their value being a validation function. For
Packit Service 30b792
 * details on the meanings, please refer to the gpgme documentation
Packit Service 30b792
 * https://www.gnupg.org/documentation/manuals/gpgme/Key-objects.html#Key-objects
Packit Service 30b792
 * @param {String} fingerprint
Packit Service 30b792
 * @param {Boolean} revoked
Packit Service 30b792
 * @param {Boolean} expired
Packit Service 30b792
 * @param {Boolean} disabled
Packit Service 30b792
 * @param {Boolean} invalid
Packit Service 30b792
 * @param {Boolean} can_encrypt
Packit Service 30b792
 * @param {Boolean} can_sign
Packit Service 30b792
 * @param {Boolean} can_certify
Packit Service 30b792
 * @param {Boolean} can_authenticate
Packit Service 30b792
 * @param {Boolean} secret
Packit Service 30b792
 * @param {Boolean}is_qualified
Packit Service 30b792
 * @param {String} protocol
Packit Service 30b792
 * @param {String} issuer_serial
Packit Service 30b792
 * @param {String} issuer_name
Packit Service 30b792
 * @param {Boolean} chain_id
Packit Service 30b792
 * @param {String} owner_trust
Packit Service 30b792
 * @param {Date} last_update
Packit Service 30b792
 * @param {String} origin
Packit Service 30b792
 * @param {Array<GPGME_Subkey>} subkeys
Packit Service 30b792
 * @param {Array<GPGME_UserId>} userids
Packit Service 30b792
 * @param {Array<String>} tofu
Packit Service 30b792
 * @param {Boolean} hasSecret
Packit Service 30b792
 * @protected
Packit Service 30b792
 * @const
Packit Service 30b792
 */
Packit Service 30b792
const validKeyProperties = {
Packit Service 30b792
    'fingerprint': function (value){
Packit Service 30b792
        return isFingerprint(value);
Packit Service 30b792
    },
Packit Service 30b792
    'revoked': function (value){
Packit Service 30b792
        return typeof (value) === 'boolean';
Packit Service 30b792
    },
Packit Service 30b792
    'expired': function (value){
Packit Service 30b792
        return typeof (value) === 'boolean';
Packit Service 30b792
    },
Packit Service 30b792
    'disabled': function (value){
Packit Service 30b792
        return typeof (value) === 'boolean';
Packit Service 30b792
    },
Packit Service 30b792
    'invalid': function (value){
Packit Service 30b792
        return typeof (value) === 'boolean';
Packit Service 30b792
    },
Packit Service 30b792
    'can_encrypt': function (value){
Packit Service 30b792
        return typeof (value) === 'boolean';
Packit Service 30b792
    },
Packit Service 30b792
    'can_sign': function (value){
Packit Service 30b792
        return typeof (value) === 'boolean';
Packit Service 30b792
    },
Packit Service 30b792
    'can_certify': function (value){
Packit Service 30b792
        return typeof (value) === 'boolean';
Packit Service 30b792
    },
Packit Service 30b792
    'can_authenticate': function (value){
Packit Service 30b792
        return typeof (value) === 'boolean';
Packit Service 30b792
    },
Packit Service 30b792
    'secret': function (value){
Packit Service 30b792
        return typeof (value) === 'boolean';
Packit Service 30b792
    },
Packit Service 30b792
    'is_qualified': function (value){
Packit Service 30b792
        return typeof (value) === 'boolean';
Packit Service 30b792
    },
Packit Service 30b792
    'protocol': function (value){
Packit Service 30b792
        return typeof (value) === 'string';
Packit Service 30b792
        // TODO check for implemented ones
Packit Service 30b792
    },
Packit Service 30b792
    'issuer_serial': function (value){
Packit Service 30b792
        return typeof (value) === 'string';
Packit Service 30b792
    },
Packit Service 30b792
    'issuer_name': function (value){
Packit Service 30b792
        return typeof (value) === 'string';
Packit Service 30b792
    },
Packit Service 30b792
    'chain_id': function (value){
Packit Service 30b792
        return typeof (value) === 'string';
Packit Service 30b792
    },
Packit Service 30b792
    'owner_trust': function (value){
Packit Service 30b792
        return typeof (value) === 'string';
Packit Service 30b792
    },
Packit Service 30b792
    'last_update': function (value){
Packit Service 30b792
        return (Number.isInteger(value));
Packit Service 30b792
        // TODO undefined/null possible?
Packit Service 30b792
    },
Packit Service 30b792
    'origin': function (value){
Packit Service 30b792
        return (Number.isInteger(value));
Packit Service 30b792
    },
Packit Service 30b792
    'subkeys': function (value){
Packit Service 30b792
        return (Array.isArray(value));
Packit Service 30b792
    },
Packit Service 30b792
    'userids': function (value){
Packit Service 30b792
        return (Array.isArray(value));
Packit Service 30b792
    },
Packit Service 30b792
    'tofu': function (value){
Packit Service 30b792
        return (Array.isArray(value));
Packit Service 30b792
    },
Packit Service 30b792
    'hasSecret': function (value){
Packit Service 30b792
        return typeof (value) === 'boolean';
Packit Service 30b792
    }
Packit Service 30b792
Packit Service 30b792
};
Packit Service 30b792
Packit Service 30b792
/**
Packit Service 30b792
* sets the Key data in bulk. It can only be used from inside a Key, either
Packit Service 30b792
* during construction or on a refresh callback.
Packit Service 30b792
* @param {Object} key the original internal key data.
Packit Service 30b792
* @param {Object} data Bulk set the data for this key, with an Object structure
Packit Service 30b792
* as sent by gpgme-json.
Packit Service 30b792
* @returns {Object|GPGME_Error} the changed data after values have been set,
Packit Service 30b792
* an error if something went wrong.
Packit Service 30b792
* @private
Packit Service 30b792
*/
Packit Service 30b792
function validateKeyData (fingerprint, data){
Packit Service 30b792
    const key = {};
Packit Service 30b792
    if (!fingerprint || typeof (data) !== 'object' || !data.fingerprint
Packit Service 30b792
     || fingerprint !== data.fingerprint.toUpperCase()
Packit Service 30b792
    ){
Packit Service 30b792
        return gpgme_error('KEY_INVALID');
Packit Service 30b792
    }
Packit Service 30b792
    let props = Object.keys(data);
Packit Service 30b792
    for (let i=0; i< props.length; i++){
Packit Service 30b792
        if (!validKeyProperties.hasOwnProperty(props[i])){
Packit Service 30b792
            return gpgme_error('KEY_INVALID');
Packit Service 30b792
        }
Packit Service 30b792
        // running the defined validation function
Packit Service 30b792
        if (validKeyProperties[props[i]](data[props[i]]) !== true ){
Packit Service 30b792
            return gpgme_error('KEY_INVALID');
Packit Service 30b792
        }
Packit Service 30b792
        switch (props[i]){
Packit Service 30b792
        case 'subkeys':
Packit Service 30b792
            key.subkeys = [];
Packit Service 30b792
            for (let i=0; i< data.subkeys.length; i++) {
Packit Service 30b792
                key.subkeys.push(
Packit Service 30b792
                    new GPGME_Subkey(data.subkeys[i]));
Packit Service 30b792
            }
Packit Service 30b792
            break;
Packit Service 30b792
        case 'userids':
Packit Service 30b792
            key.userids = [];
Packit Service 30b792
            for (let i=0; i< data.userids.length; i++) {
Packit Service 30b792
                key.userids.push(
Packit Service 30b792
                    new GPGME_UserId(data.userids[i]));
Packit Service 30b792
            }
Packit Service 30b792
            break;
Packit Service 30b792
        case 'last_update':
Packit Service 30b792
            key[props[i]] = new Date( data[props[i]] * 1000 );
Packit Service 30b792
            break;
Packit Service 30b792
        default:
Packit Service 30b792
            key[props[i]] = data[props[i]];
Packit Service 30b792
        }
Packit Service 30b792
    }
Packit Service 30b792
    return key;
Packit Service 30b792
}
Packit Service 30b792
Packit Service 30b792
/**
Packit Service 30b792
 * Fetches and sets properties from gnupg
Packit Service 30b792
 * @param {String} fingerprint
Packit Service 30b792
 * @param {String} property to search for.
Packit Service 30b792
 * @private
Packit Service 30b792
 * @async
Packit Service 30b792
 */
Packit Service 30b792
function getGnupgState (fingerprint, property){
Packit Service 30b792
    return new Promise(function (resolve, reject) {
Packit Service 30b792
        if (!isFingerprint(fingerprint)) {
Packit Service 30b792
            reject(gpgme_error('KEY_INVALID'));
Packit Service 30b792
        } else {
Packit Service 30b792
            let msg = createMessage('keylist');
Packit Service 30b792
            msg.setParameter('keys', fingerprint);
Packit Service 30b792
            msg.post().then(function (res){
Packit Service 30b792
                if (!res.keys || res.keys.length !== 1){
Packit Service 30b792
                    reject(gpgme_error('KEY_INVALID'));
Packit Service 30b792
                } else {
Packit Service 30b792
                    const key = res.keys[0];
Packit Service 30b792
                    let result;
Packit Service 30b792
                    switch (property){
Packit Service 30b792
                    case 'subkeys':
Packit Service 30b792
                        result = [];
Packit Service 30b792
                        if (key.subkeys.length){
Packit Service 30b792
                            for (let i=0; i < key.subkeys.length; i++) {
Packit Service 30b792
                                result.push(
Packit Service 30b792
                                    new GPGME_Subkey(key.subkeys[i]));
Packit Service 30b792
                            }
Packit Service 30b792
                        }
Packit Service 30b792
                        resolve(result);
Packit Service 30b792
                        break;
Packit Service 30b792
                    case 'userids':
Packit Service 30b792
                        result = [];
Packit Service 30b792
                        if (key.userids.length){
Packit Service 30b792
                            for (let i=0; i< key.userids.length; i++) {
Packit Service 30b792
                                result.push(
Packit Service 30b792
                                    new GPGME_UserId(key.userids[i]));
Packit Service 30b792
                            }
Packit Service 30b792
                        }
Packit Service 30b792
                        resolve(result);
Packit Service 30b792
                        break;
Packit Service 30b792
                    case 'last_update':
Packit Service 30b792
                        if (key.last_update === undefined){
Packit Service 30b792
                            reject(gpgme_error('CONN_UNEXPECTED_ANSWER'));
Packit Service 30b792
                        } else if (key.last_update !== null){
Packit Service 30b792
                            resolve(new Date( key.last_update * 1000));
Packit Service 30b792
                        } else {
Packit Service 30b792
                            resolve(null);
Packit Service 30b792
                        }
Packit Service 30b792
                        break;
Packit Service 30b792
                    default:
Packit Service 30b792
                        if (!validKeyProperties.hasOwnProperty(property)){
Packit Service 30b792
                            reject(gpgme_error('PARAM_WRONG'));
Packit Service 30b792
                        } else {
Packit Service 30b792
                            if (key.hasOwnProperty(property)){
Packit Service 30b792
                                resolve(key[property]);
Packit Service 30b792
                            } else {
Packit Service 30b792
                                reject(gpgme_error(
Packit Service 30b792
                                    'CONN_UNEXPECTED_ANSWER'));
Packit Service 30b792
                            }
Packit Service 30b792
                        }
Packit Service 30b792
                        break;
Packit Service 30b792
                    }
Packit Service 30b792
                }
Packit Service 30b792
            }, function (error){
Packit Service 30b792
                reject(gpgme_error(error));
Packit Service 30b792
            });
Packit Service 30b792
        }
Packit Service 30b792
    });
Packit Service 30b792
}