diff options
Diffstat (limited to 'lang/js/src/gpgmejs.js')
-rw-r--r-- | lang/js/src/gpgmejs.js | 282 |
1 files changed, 113 insertions, 169 deletions
diff --git a/lang/js/src/gpgmejs.js b/lang/js/src/gpgmejs.js index dedbf809..8323ac3b 100644 --- a/lang/js/src/gpgmejs.js +++ b/lang/js/src/gpgmejs.js @@ -1,187 +1,131 @@ -import {Connection} from "./Connection" - -export function encrypt(data, publicKeys, privateKeys, passwords=null, - sessionKey, filename, compression, armor=true, detached=false, - signature=null, returnSessionKey=false, wildcard=false, date=new Date()){ - // gpgme_op_encrypt ( <-gpgme doc on this operation - // gpgme_ctx_t ctx, - // gpgme_key_t recp[], - // gpgme_encrypt_flags_t flags, - // gpgme_data_t plain, - // gpgme_data_t cipher) - // flags: - // GPGME_ENCRYPT_ALWAYS_TRUST - // GPGME_ENCRYPT_NO_ENCRYPT_TO - // GPGME_ENCRYPT_NO_COMPRESS - // GPGME_ENCRYPT_PREPARE - // GPGME_ENCRYPT_EXPECT_SIGN - // GPGME_ENCRYPT_SYMMETRIC - // GPGME_ENCRYPT_THROW_KEYIDS - // GPGME_ENCRYPT_WRAP - if (passwords !== null){ - throw('Password!'); // TBD - } - - let pubkeys = toKeyIdArray(publicKeys); - let privkeys = toKeyIdArray(privateKeys); - - // TODO filename: data is supposed to be empty, file is provided - // TODO config compression detached signature - // TODO signature to add to the encrypted message (?) || privateKeys: signature is desired - // gpgme_op_encrypt_sign (gpgme_ctx_t ctx, gpgme_key_t recp[], gpgme_encrypt_flags_t flags, gpgme_data_t plain, gpgme_data_t cipher) - - // TODO sign date overwriting implemented in gnupg? - - let conn = new Connection(); - if (wildcard){ - // Connection.set('throw-keyids', true); TODO Connection.set not yet existant - } - return conn.post('encrypt', { - 'data': data, - 'keys': publicKeys, - 'armor': armor}); -}; +/* gpgme.js - Javascript integration for gpgme + * Copyright (C) 2018 Bundesamt für Sicherheit in der Informationstechnik + * + * This file is part of GPGME. + * + * GPGME 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 2.1 of + * the License, or (at your option) any later version. + * + * GPGME 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 program; if not, see <http://www.gnu.org/licenses/>. + * SPDX-License-Identifier: LGPL-2.1+ + */ -export function decrypt(message, privateKeys, passwords, sessionKeys, publicKeys, - format='utf8', signature=null, date=new Date()) { - if (passwords !== null){ - throw('Password!'); // TBD - } - if (format === 'binary'){ - // Connection.set('base64', true); - } - if (publicKeys || signature){ - // Connection.set('signature', signature); - // request verification, too +import {Connection} from "./Connection" +import {GPGME_Message} from './Message' +import {toKeyIdArray} from "./Helpers" + +export class GpgME { + /** + * initial check if connection si successfull. Will throw ERR_NO_CONNECT or + * ERR_NO_CONNECT_RLE (if chrome.runtime.lastError is available) if the + * connection fails. + * TODO The connection to the nativeMessaging host will, for now, be closed + * after each interaction. Session management with gpg_agent is TBD. + * TODO: add configuration + */ + constructor(){ + let conn = new Connection(); + // this.keyring = new Keyring(); TBD + // TODO config, e.g. + this.configuration = { + null_expire_is_never: true + }; + conn.disconnect(); } - //privateKeys optionally if keyId was thrown? - // gpgme_op_decrypt (gpgme_ctx_t ctx, gpgme_data_t cipher, gpgme_data_t plain) - // response is gpgme_op_decrypt_result (gpgme_ctx_t ctx) (next available?) - return conn.post('decrypt', { - 'data': message - }); -} -// BIG TODO. -export function generateKey({userIds=[], passphrase, numBits=2048, unlocked=false, keyExpirationTime=0, curve="", date=new Date()}){ - throw('not implemented here'); - // gpgme_op_createkey (gpgme_ctx_t ctx, const char *userid, const char *algo, unsigned long reserved, unsigned long expires, gpgme_key_t extrakey, unsigned int flags); - return false; -} + /** + * @param {String|Uint8Array} data text/data to be encrypted as String/Uint8Array + * @param {GPGME_Key|String|Array<String>|Array<GPGME_Key>} publicKeys Keys used to encrypt the message + * @param {Boolean} wildcard (optional) If true, recipient information will not be added to the message + */ + encrypt (data, publicKeys, wildcard=false){ -export function sign({ data, privateKeys, armor=true, detached=false, date=new Date() }) { - //TODO detached GPGME_SIG_MODE_DETACH | GPGME_SIG_MODE_NORMAL - // gpgme_op_sign (gpgme_ctx_t ctx, gpgme_data_t plain, gpgme_data_t sig, gpgme_sig_mode_t mode) - // TODO date not supported + let msg = new GPGME_Message; + msg.operation = 'encrypt'; - let conn = new Connection(); - let privkeys = toKeyIdArray(privateKeys); - return conn.post('sign', { - 'data': data, - 'keys': privkeys, - 'armor': armor}); -}; + // TODO temporary + msg.setParameter('armor', true); + msg.setParameter('always-trust', true); -export function verify({ message, publicKeys, signature=null, date=new Date() }) { - //TODO extra signature: sig, signed_text, plain: null - // inline sig: signed_text:null, plain as writable (?) - // date not supported - //gpgme_op_verify (gpgme_ctx_t ctx, gpgme_data_t sig, gpgme_data_t signed_text, gpgme_data_t plain) - let conn = new Connection(); - let privkeys = toKeyIdArray(privateKeys); - return conn.post('sign', { - 'data': data, - 'keys': privkeys, - 'armor': armor}); -} + let pubkeys = toKeyIdArray(publicKeys); + msg.setParameter('keys', pubkeys); + putData(msg, data); + if (wildcard === true){msg.setParameter('throw-keyids', true); + }; -export function reformatKey(privateKey, userIds=[], passphrase="", unlocked=false, keyExpirationTime=0){ - let privKey = toKeyIdArray(privateKey); - if (privKey.length !== 1){ - return false; //TODO some error handling. There is not exactly ONE key we are editing + if (msg.isComplete === true) { + let conn = new Connection(); + return (conn.post(msg.message)); + } + else { + return Promise.reject('NO_CONNECT'); + //TODO + } } - let conn = new Connection(); - // TODO key management needs to be changed somewhat - return conn.post('TODO', { - 'key': privKey[0], - 'keyExpirationTime': keyExpirationTime, //TODO check if this is 0 or a positive and plausible number - 'userIds': userIds //TODO check if empty or plausible strings - }); - // unlocked will be ignored -} -export function decryptKey({ privateKey, passphrase }) { - throw('not implemented here'); - return false; -}; + /** + * @param {String} data TODO Format: base64? String? Message with the encrypted data + * @returns {Promise<Object>} decrypted message: + data: The decrypted data. This may be base64 encoded. + base64: Boolean indicating whether data is base64 encoded. + mime: A Boolean indicating whether the data is a MIME object. + info: An optional object with extra information. + * @async + */ -export function encryptKey({ privateKey, passphrase }) { - throw('not implemented here'); - return false; -}; + decrypt(data){ -export function encryptSessionKey({data, algorithm, publicKeys, passwords, wildcard=false }) { - //openpgpjs: - // Encrypt a symmetric session key with public keys, passwords, or both at - // once. At least either public keys or passwords must be specified. - throw('not implemented here'); - return false; -}; - -export function decryptSessionKeys({ message, privateKeys, passwords }) { - throw('not implemented here'); - return false; -}; - -// //TODO worker handling - -// //TODO key representation -// //TODO: keyring handling - - -/** - * Helper functions and checks - */ - -/** - * Checks if the submitted value is a keyID. - * TODO: should accept all strings that are accepted as keyID by gnupg - * TODO: See if Key becomes an object later on - * @param {*} key input value. Is expected to be a string of 8,16 or 40 chars - * representing hex values. Will return false if that expectation is not met - */ -function isKeyId(key){ - if (!key || typeof(key) !== "string"){ - return false; - } - if ([8,16,40].indexOf(key.length) < 0){ - return false; + if (data === undefined){ + throw('ERR_EMPTY_MSG'); + } + let msg = new GPGME_Message; + msg.operation = 'decrypt'; + putData(msg, data); + // TODO: needs proper EOL to be decrypted. + + if (msg.isComplete === true){ + let conn = new Connection(); + return conn.post(msg.message); + } + else { + return Promise.reject('NO_CONNECT'); + //TODO + } } - let regexp= /^[0-9a-fA-F]*$/i; - return regexp.test(key); -}; +} /** - * Tries to return an array of keyID values, either from a string or an array. - * Filters out those that do not meet the criteria. (TODO: silently for now) - * @param {*} array Input value. + * Sets the data of the message, converting Uint8Array to base64 and setting + * the base64 flag + * @param {GPGME_Message} message The message where this data will be set + * @param {*} data The data to enter + * @param {String} propertyname // TODO unchecked still */ -function toKeyIdArray(array){ - let result = []; - if (!array){ - return result; - } - if (!Array.isArray(array)){ - if (isKeyId(array) === true){ - return [keyId]; - } - return result; +function putData(message, data){ + if (!message || !message instanceof GPGME_Message ) { + throw('NO_MESSAGE_OBJECT'); } - for (let i=0; i < array.length; i++){ - if (isKeyId(array[i]) === true){ - result.push(array[i]); - } + if (!data){ + //TODO Debug only! No data is legitimate + console.log('Warning. no data in message'); + message.setParameter('data', ''); + } else if (data instanceof Uint8Array){ + let decoder = new TextDecoder('utf8'); + message.setParameter('base64', true); + message.setParameter ('data', decoder.decode(data)); + } else if (typeof(data) === 'string') { + message.setParameter('base64', false); + message.setParameter('data', data); + } else { + throw('ERR_WRONG_TYPE'); } - return result; -}; +}
\ No newline at end of file |