js: remove openpgp mode
-- * After discussion, that mode is not required, and can result in being quite misleading and a maintenance hassle later on.
This commit is contained in:
parent
ecad772635
commit
f7ed80ff6a
@ -34,13 +34,6 @@
|
|||||||
Functionality tests with larger/longer running data sets.
|
Functionality tests with larger/longer running data sets.
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
|
||||||
<a href="openpgpModeTest.html">
|
|
||||||
Testing openPGP mode.
|
|
||||||
</a> - Please notice that, due to comparing
|
|
||||||
the inputs and outputs with openpgpjs objects, this test
|
|
||||||
requires a copy of openpgpjs in libs.
|
|
||||||
</li>
|
|
||||||
</ul>
|
</ul>
|
||||||
</p>
|
</p>
|
||||||
</body>
|
</body>
|
||||||
|
@ -1,23 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<meta charset="utf-8">
|
|
||||||
<link href="libs/mocha.css" rel="stylesheet" />
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<h3>Openpgp mode test</h3>
|
|
||||||
<div id="mocha"></div>
|
|
||||||
<!-- load unit tests -->
|
|
||||||
<script src="libs/mocha.js"></script>
|
|
||||||
<script src="libs/chai.js"></script>
|
|
||||||
<script src="setup_testing.js"></script>
|
|
||||||
<script src="libs/gpgmejs.bundle.js"></script>
|
|
||||||
<script src="libs/openpgp.min.js"></script>
|
|
||||||
<script src="tests/inputvalues.js"></script>
|
|
||||||
<script src="tests/inputValues_openpgpjs.js"></script>
|
|
||||||
<!-- insert tests here-->
|
|
||||||
<script src="tests/openpgpModeTest.js"></script>
|
|
||||||
<!-- run tests -->
|
|
||||||
<script src="runbrowsertest.js"></script>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
@ -1,32 +0,0 @@
|
|||||||
const openpgpInputs = {
|
|
||||||
pubKeyArmored: '-----BEGIN PGP PUBLIC KEY BLOCK-----\n'
|
|
||||||
+ '\n'
|
|
||||||
+ 'mQENBFrsKEkBCADKw4Wt8J6M/88qD8PO6lSMCxH1cpwH8iK0uPaFFYsJkkXo7kWf\n'
|
|
||||||
+ 'PTAtrV+REqF/o80dvYcdLvRsV21pvncZz/HXLu1yQ18mC3XObrKokbdgrTTKA5XE\n'
|
|
||||||
+ 'BZkNsqyaMMJauT18H4hYkSg62/tTdO1cu/zWv/LFf7Xyn6+uA74ovXCJlO1s0N2c\n'
|
|
||||||
+ 'PShtr98QRzPMf2owgVk37JnDNp4gGVDGHxSZOuUwxgYAZYnA8SFc+c+3ZrQfY870\n'
|
|
||||||
+ '+O4j3Mz4p7yD13AwP4buQLBsb/icxekeQCqpRJhLH9f7MdEcGXa1x36RcEkHdu+M\n'
|
|
||||||
+ 'yJ392eMgD+dKNfRCtyTPhjZTxvbNELIBYICfABEBAAG0EHRlc3RAZXhhbXBsZS5v\n'
|
|
||||||
+ 'cmeJAVQEEwEIAD4WIQTUFzW5Ejb9uIIEjFojAWNe7/DLBQUCWuwoSQIbAwUJA8Jn\n'
|
|
||||||
+ 'AAULCQgHAgYVCgkICwIEFgIDAQIeAQIXgAAKCRAjAWNe7/DLBf9kB/wOQ/S60HGw\n'
|
|
||||||
+ 'Fq07W9N01HWULyhHKoMmcHL6rfZ64oDqLxolPSasz7WAMW1jN4qtWJ0mFzwO83V6\n'
|
|
||||||
+ 'kaBe+wF6Kqir6udFSBW9rPcFg6/VZXPltT0a6uacIHq6DyQ5iMW4YQWbVy9OR2rN\n'
|
|
||||||
+ 'GkYo1JCBR0XdRJYCSX3yB4TWv/eXnZ37/WjmiTOIZh35rjs+NuU/S5JPDfAp2/k7\n'
|
|
||||||
+ '0DevQeBsv+UjVXjWpNTZmPbvDnd995uSmC6UY4hzyP84ORYMYn9n1QAR0goxDN6U\n'
|
|
||||||
+ 'unOf9Rlp1oMzdxMool/d1MlCxg2h3jheuhv7lgUF4KpvHOuEPXQ7UO417E0TYcDZ\n'
|
|
||||||
+ '1J8Nsv87SZeEuQENBFrsKEkBCADjoEBhG/QPqZHg8VyoD1xYRAWGxyDJkX/GrSs6\n'
|
|
||||||
+ 'yE+x2hk5FoQCajxKa/d4AVxOnJpdwhAfeXeSNaql5Ejgzax+Tdj9BV6vtGVJVv0p\n'
|
|
||||||
+ 'O7bgAiZxkA6RHxtNqhpPnPQoXvUzkzpRgpuL+Nj4yIg7z1ITH6KQH4u5SI9vd+j/\n'
|
|
||||||
+ '8i9Taz67pdZwuJjac8qBuJHjzAo1bjYctFYUSG5pbmMQyNLySzgiNkFa4DajODlt\n'
|
|
||||||
+ '3RuqVGP316Fk+Sy2+60tC/HlX8jgMyMONfOGBQx6jk8tvAphS/LAqrrNepnagIyL\n'
|
|
||||||
+ 'UGKU+L8cB2g1PGGp2biBFWqZbudZoyRBet/0yH/zirBdQJw1ABEBAAGJATwEGAEI\n'
|
|
||||||
+ 'ACYWIQTUFzW5Ejb9uIIEjFojAWNe7/DLBQUCWuwoSQIbDAUJA8JnAAAKCRAjAWNe\n'
|
|
||||||
+ '7/DLBf0pCACPp5hBuUWngu2Hqvg+tNiujfsiYzId3MffFxEk3CbXeHcJ5F32NDJ9\n'
|
|
||||||
+ 'PYCnra4L8wSv+NZt9gIa8lFwoFSFQCjzH7KE86XcV3MhfdJTNb/+9CR7Jq3e/4Iy\n'
|
|
||||||
+ '0N5ip7PNYMCyakcAsxvsNCJKrSaDuYe/OAoTXRBtgRWE2uyT315em02Lkr+2Cc/Q\n'
|
|
||||||
+ 'k6H+vlNOHGRgnpI/OZZjnUuUfBUvMGHr1phW+y7aeymC9PnUGdViRdJe23nntMSD\n'
|
|
||||||
+ 'A+0/I7ESO9JsWvJbyBmuiZpu9JjScOjYH9xpQLqRNyw4WHpZriN69F0t9Mmd7bM1\n'
|
|
||||||
+ '+UyPgbPEr0iWMeyctYsuOLeUyQKMscDT\n'
|
|
||||||
+ '=QyY6\n'
|
|
||||||
+ '-----END PGP PUBLIC KEY BLOCK-----\n'
|
|
||||||
};
|
|
@ -1,169 +0,0 @@
|
|||||||
/* 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+
|
|
||||||
*/
|
|
||||||
|
|
||||||
describe('Encrypting-Decrypting in openpgp mode, using a Message object', function () {
|
|
||||||
it('Simple Encrypt-Decrypt', function (done) {
|
|
||||||
let prm = Gpgmejs.init({api_style: 'gpgme_openpgpjs'});
|
|
||||||
prm.then(function (context) {
|
|
||||||
context.encrypt({
|
|
||||||
data: openpgp.message.fromText(inputvalues.encrypt.good.data),
|
|
||||||
publicKeys: inputvalues.encrypt.good.fingerprint}
|
|
||||||
).then(function (answer) {
|
|
||||||
expect(answer).to.not.be.empty;
|
|
||||||
expect(answer).to.be.an("object");
|
|
||||||
expect(answer.data).to.include('BEGIN PGP MESSAGE');
|
|
||||||
expect(answer.data).to.include('END PGP MESSAGE');
|
|
||||||
let msg = openpgp.message.fromText(answer.data);
|
|
||||||
context.decrypt({message:msg}).then(function (result) {
|
|
||||||
expect(result).to.not.be.empty;
|
|
||||||
expect(result.data).to.be.a('string');
|
|
||||||
expect(result.data).to.equal(inputvalues.encrypt.good.data);
|
|
||||||
context._GpgME.connection.disconnect();
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
it('Keys as Fingerprints', function(done){
|
|
||||||
let prm = Gpgmejs.init({api_style: 'gpgme_openpgpjs'});
|
|
||||||
let input = inputvalues.encrypt.good.data_nonascii;
|
|
||||||
prm.then(function (context) {
|
|
||||||
context.encrypt({
|
|
||||||
data: input,
|
|
||||||
publicKeys: inputvalues.encrypt.good.fingerprint}
|
|
||||||
).then(function (answer) {
|
|
||||||
expect(answer).to.not.be.empty;
|
|
||||||
expect(answer.data).to.be.a("string");
|
|
||||||
expect(answer.data).to.include('BEGIN PGP MESSAGE');
|
|
||||||
expect(answer.data).to.include('END PGP MESSAGE');
|
|
||||||
context.decrypt({message:answer.data}).then(function (result) {
|
|
||||||
expect(result).to.not.be.empty;
|
|
||||||
expect(result.data).to.be.a('string');
|
|
||||||
expect(result.data).to.equal(input);
|
|
||||||
context._GpgME.connection.disconnect();
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
it('Keys as openpgp Keys', function(){
|
|
||||||
let prm = Gpgmejs.init({api_style: 'gpgme_openpgpjs'});
|
|
||||||
let data = inputvalues.encrypt.good.data_nonascii;
|
|
||||||
let key = openpgp.key.readArmored(openpgpInputs.pubKeyArmored);
|
|
||||||
expect(key).to.be.an('object');
|
|
||||||
prm.then(function (context) {
|
|
||||||
context.encrypt({
|
|
||||||
data: data,
|
|
||||||
publicKeys: [key]}
|
|
||||||
).then( function (answer) {
|
|
||||||
expect(answer).to.not.be.empty;
|
|
||||||
expect(answer.data).to.be.a("string");
|
|
||||||
expect(answer.data).to.include('BEGIN PGP MESSAGE');
|
|
||||||
expect(answer.data).to.include('END PGP MESSAGE');
|
|
||||||
context.decrypt({message:answer.data}).then( function (result){
|
|
||||||
expect(result).to.not.be.empty;
|
|
||||||
expect(result.data).to.be.a('string');
|
|
||||||
expect(result.data).to.equal(data);
|
|
||||||
context._GpgME.connection.disconnect();
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
it('Trying to send non-implemented parameters: passwords', function(done){
|
|
||||||
let prm = Gpgmejs.init({api_style: 'gpgme_openpgpjs'});
|
|
||||||
let data = 'Hello World';
|
|
||||||
let key = inputvalues.encrypt.good.fingerprint;
|
|
||||||
prm.then(function (context) {
|
|
||||||
context.encrypt({
|
|
||||||
data: data,
|
|
||||||
publicKeys: [key],
|
|
||||||
passwords: 'My secret password'}
|
|
||||||
).then( function(){},
|
|
||||||
function(error){
|
|
||||||
expect(error).to.be.an.instanceof(Error);
|
|
||||||
expect(error.code).equal('NOT_IMPLEMENTED');
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
it('Trying to send non-implemented parameters: signature', function(done){
|
|
||||||
let prm = Gpgmejs.init({api_style: 'gpgme_openpgpjs'});
|
|
||||||
let data = 'Hello World';
|
|
||||||
let key = inputvalues.encrypt.good.fingerprint;
|
|
||||||
prm.then(function (context) {
|
|
||||||
context.encrypt({
|
|
||||||
data: data,
|
|
||||||
publicKeys: [key],
|
|
||||||
signature: {any: 'value'}
|
|
||||||
}).then(
|
|
||||||
function(){},
|
|
||||||
function(error){
|
|
||||||
expect(error).to.be.an.instanceof(Error);
|
|
||||||
expect(error.code).equal('NOT_IMPLEMENTED');
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('Keyring in openpgp mode', function(){
|
|
||||||
it('Check Existence and structure of Keyring after init', function(done){
|
|
||||||
let prm = Gpgmejs.init({api_style: 'gpgme_openpgpjs'});
|
|
||||||
prm.then(function (context) {
|
|
||||||
expect(context.Keyring).to.be.an('object');
|
|
||||||
expect(context.Keyring.getPublicKeys).to.be.a('function');
|
|
||||||
expect(context.Keyring.deleteKey).to.be.a('function');
|
|
||||||
expect(context.Keyring.getDefaultKey).to.be.a('function');
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
// TODO: gpgme key interface not yet there
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('Decrypting and verification in openpgp mode', function(){
|
|
||||||
it('Decrypt', function(){
|
|
||||||
let msg = openpgp.message.fromText(inputvalues.encryptedData);
|
|
||||||
let prm = Gpgmejs.init({api_style: 'gpgme_openpgpjs'});
|
|
||||||
prm.then(function (context) {
|
|
||||||
context.decrypt({message: msg})
|
|
||||||
.then(function(answer){
|
|
||||||
expect(answer.data).to.be.a('string');
|
|
||||||
expect(result.data).to.equal('¡Äußerste µ€ før ñoquis@hóme! Добрый день\n');
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
it('Decryption attempt with bad data returns gnupg error', function(done){
|
|
||||||
let msg = openpgp.message.fromText(bigString(0.1));
|
|
||||||
let prm = Gpgmejs.init({api_style: 'gpgme_openpgpjs'});
|
|
||||||
prm.then(function (context) {
|
|
||||||
context.decrypt({message: msg})
|
|
||||||
.then( function(){},
|
|
||||||
function(error){
|
|
||||||
expect(error).to.be.an.instanceof(Error);
|
|
||||||
expect(error.code).to.equal('GNUPG_ERROR');
|
|
||||||
expect(error.message).to.be.a('string');
|
|
||||||
// TBD: Type of error
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}).timeout(4000);
|
|
||||||
});
|
|
@ -36,22 +36,6 @@
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
describe('openpgp mode', function(){
|
|
||||||
it('startup of openpgp mode returns the correct parameters', function(done){
|
|
||||||
let prm = Gpgmejs.init({api_style:"gpgme_openpgpjs"});
|
|
||||||
prm.then(function(context){
|
|
||||||
expect(context).to.be.an('object');
|
|
||||||
expect(context.connection).to.be.undefined;
|
|
||||||
expect(context.Keyring).to.be.an('object');
|
|
||||||
expect(context.encrypt).to.be.a('function');
|
|
||||||
expect(context.decrypt).to.be.a('function');
|
|
||||||
done();
|
|
||||||
}, function(error){
|
|
||||||
expect(error).to.be.undefined;
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('GPGME does not start with invalid parameters', function(){
|
describe('GPGME does not start with invalid parameters', function(){
|
||||||
for (let i=0; i < inputvalues.init.invalid_startups.length; i++){
|
for (let i=0; i < inputvalues.init.invalid_startups.length; i++){
|
||||||
|
@ -4,18 +4,15 @@ NativeConnection:
|
|||||||
receiving an answer
|
receiving an answer
|
||||||
[X] nativeConnection successfull on Chromium, chrome and firefox
|
[X] nativeConnection successfull on Chromium, chrome and firefox
|
||||||
[*] nativeConnection successfull on Windows, macOS, Linux
|
[*] nativeConnection successfull on Windows, macOS, Linux
|
||||||
[*] nativeConnection with delayed, multipart (> 1MB) answer
|
[X] nativeConnection with delayed, multipart (> 1MB) answer
|
||||||
|
|
||||||
replicating Openpgpjs API:
|
|
||||||
|
|
||||||
[*] Message handling (encrypt, decrypt verify, sign)
|
[*] Message handling (encrypt, decrypt verify, sign)
|
||||||
[x] encrypt, decrypt
|
[x] encrypt, decrypt
|
||||||
[ ] verify
|
[ ] verify
|
||||||
[ ] sign
|
[ ] sign
|
||||||
[*] Key handling (import/export, modifying, status queries)
|
[*] Key handling (import/export, modifying, status queries)
|
||||||
[ ] Configuration handling
|
[*] Configuration handling
|
||||||
[ ] check for completeness
|
[ ] check for completeness
|
||||||
[*] handling of differences to openpgpjs
|
|
||||||
|
|
||||||
Communication with other implementations
|
Communication with other implementations
|
||||||
|
|
||||||
|
@ -12,11 +12,6 @@ To create a current version of the package, the command is
|
|||||||
If you want a more debuggable (i.e. not minified) build, just change the mode
|
If you want a more debuggable (i.e. not minified) build, just change the mode
|
||||||
in webpack.conf.js.
|
in webpack.conf.js.
|
||||||
|
|
||||||
TODO: gpgme_openpgpjs aims to offer an API similar to openpgpjs, throwing errors
|
|
||||||
if some part of the API is not implemented, 'translating' objects if possible.
|
|
||||||
This will be incorporated into the build process later, for now it is a line to
|
|
||||||
uncomment in src/index.js
|
|
||||||
|
|
||||||
Demo WebExtension:
|
Demo WebExtension:
|
||||||
As soon as a bundled webpack is in dist/
|
As soon as a bundled webpack is in dist/
|
||||||
the gpgmejs folder can just be included in the extensions tab of the browser in
|
the gpgmejs folder can just be included in the extensions tab of the browser in
|
||||||
|
@ -19,13 +19,13 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
export const availableConf = {
|
export const availableConf = {
|
||||||
api_style: ['gpgme', 'gpgme_openpgpjs'],
|
|
||||||
null_expire_is_never: [true, false],
|
null_expire_is_never: [true, false],
|
||||||
unconsidered_params: ['warn','reject', 'ignore'],
|
// cachedKeys: Some Key info will not be queried on each invocation,
|
||||||
|
// manual refresh by Key.refresh()
|
||||||
|
cachedKeys: [true, false]
|
||||||
};
|
};
|
||||||
|
|
||||||
export const defaultConf = {
|
export const defaultConf = {
|
||||||
api_style: 'gpgme',
|
|
||||||
null_expire_is_never: false,
|
null_expire_is_never: false,
|
||||||
unconsidered_params: 'reject',
|
cachedKeys: false
|
||||||
};
|
};
|
@ -80,14 +80,6 @@ const err_list = {
|
|||||||
msg: 'An parameter was set that has no effect in gpgmejs',
|
msg: 'An parameter was set that has no effect in gpgmejs',
|
||||||
type: 'warning'
|
type: 'warning'
|
||||||
},
|
},
|
||||||
'NOT_IMPLEMENTED': {
|
|
||||||
msg: 'A openpgpjs parameter was submitted that is not implemented',
|
|
||||||
type: 'error'
|
|
||||||
},
|
|
||||||
'NOT_YET_IMPLEMENTED': {
|
|
||||||
msg: 'Support of this is probable, but it is not implemented yet',
|
|
||||||
type: 'error'
|
|
||||||
},
|
|
||||||
'GENERIC_ERROR': {
|
'GENERIC_ERROR': {
|
||||||
msg: 'Unspecified error',
|
msg: 'Unspecified error',
|
||||||
type: 'error'
|
type: 'error'
|
||||||
|
@ -54,8 +54,8 @@ export class GpgME {
|
|||||||
}
|
}
|
||||||
|
|
||||||
set Keyring(keyring){
|
set Keyring(keyring){
|
||||||
if (ring && ring instanceof GPGME_Keyring){
|
if (keyring && keyring instanceof GPGME_Keyring){
|
||||||
this._Keyring = ring;
|
this._Keyring = keyring;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,301 +0,0 @@
|
|||||||
/* 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+
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This is a compatibility API to be used as openpgpjs syntax.
|
|
||||||
* Non-implemented options will throw an error if set (not null or undefined)
|
|
||||||
* TODO Some info about differences
|
|
||||||
*/
|
|
||||||
|
|
||||||
import { GpgME } from "./gpgmejs";
|
|
||||||
import {GPGME_Keyring} from "./Keyring";
|
|
||||||
import { GPGME_Key, createKey } from "./Key";
|
|
||||||
import { isFingerprint } from "./Helpers";
|
|
||||||
import { gpgme_error } from "./Errors";
|
|
||||||
import { Connection } from "./Connection";
|
|
||||||
|
|
||||||
|
|
||||||
export class GpgME_openpgpmode {
|
|
||||||
|
|
||||||
constructor(connection, config = {}){
|
|
||||||
this.initGpgME(connection, config);
|
|
||||||
}
|
|
||||||
|
|
||||||
get Keyring(){
|
|
||||||
if (this._keyring){
|
|
||||||
return this._keyring;
|
|
||||||
}
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
initGpgME(connection, config = {}){
|
|
||||||
if (connection && typeof(config) ==='object'){
|
|
||||||
this._config = config;
|
|
||||||
if (!this._GpgME){
|
|
||||||
this._GpgME = new GpgME(connection, config);
|
|
||||||
}
|
|
||||||
if (!this._keyring){
|
|
||||||
this._keyring = new GPGME_Keyring_openpgpmode(connection);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Encrypt Message
|
|
||||||
* Supported:
|
|
||||||
* @param {String|Message} data
|
|
||||||
* an openpgp Message is accepted here.
|
|
||||||
* @param {Key|Array<Key>} publicKeys
|
|
||||||
* //Strings of Fingerprints
|
|
||||||
* @param {Boolean} wildcard
|
|
||||||
* TODO:
|
|
||||||
* @param {Key|Array<Key>} privateKeys // -> encryptsign
|
|
||||||
* @param {module:enums.compression} compression //TODO accepts integer, if 0 (no compression) it won't compress
|
|
||||||
* @param {Boolean} armor // TODO base64 switch
|
|
||||||
* @param {Boolean} detached // --> encryptsign
|
|
||||||
* unsupported:
|
|
||||||
* @param {String|Array<String>} passwords
|
|
||||||
* @param {Object} sessionKey
|
|
||||||
* @param {Signature} signature
|
|
||||||
* @param {Boolean} returnSessionKey
|
|
||||||
* @param {String} filename
|
|
||||||
*
|
|
||||||
* Can be set, but will be ignored:
|
|
||||||
*
|
|
||||||
* @returns {Promise<Object>}
|
|
||||||
* {data: ASCII armored message,
|
|
||||||
* signature: detached signature if 'detached' is true
|
|
||||||
* }
|
|
||||||
* @async
|
|
||||||
* @static
|
|
||||||
*/
|
|
||||||
encrypt(options) {
|
|
||||||
if (!options || typeof(options) !== 'object'){
|
|
||||||
return Promise.reject(gpgme_error('PARAM_WRONG'));
|
|
||||||
}
|
|
||||||
if (options.passwords
|
|
||||||
|| options.sessionKey
|
|
||||||
|| options.signature
|
|
||||||
|| options.returnSessionKey
|
|
||||||
|| (options.hasOwnProperty('date') && options.date !== null)
|
|
||||||
){
|
|
||||||
return Promise.reject(gpgme_error('NOT_IMPLEMENTED'));
|
|
||||||
}
|
|
||||||
if ( options.privateKeys
|
|
||||||
|| options.compression
|
|
||||||
|| (options.hasOwnProperty('armor') && options.armor === false)
|
|
||||||
|| (options.hasOwnProperty('detached') && options.detached == true)
|
|
||||||
){
|
|
||||||
return Promise.reject(gpgme_error('NOT_YET_IMPLEMENTED'));
|
|
||||||
}
|
|
||||||
if (options.filename){
|
|
||||||
if (this._config.unconsidered_params === 'warn'){
|
|
||||||
gpgme_error('PARAM_IGNORED');
|
|
||||||
} else if (this._config.unconsidered_params === 'error'){
|
|
||||||
return Promise.reject(gpgme_error('NOT_IMPLEMENTED'));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return this._GpgME.encrypt(
|
|
||||||
options.data, options.publicKeys, options.wildcard);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Decrypt Message
|
|
||||||
* supported openpgpjs parameters:
|
|
||||||
* @param {Message|String} message Message object from openpgpjs
|
|
||||||
* Unsupported:
|
|
||||||
* @param {String|Array<String>} passwords
|
|
||||||
* @param {Key|Array<Key>} privateKeys
|
|
||||||
* @param {Object|Array<Object>} sessionKeys
|
|
||||||
* Not yet supported, but planned
|
|
||||||
* @param {String} format (optional) return data format either as 'utf8' or 'binary'
|
|
||||||
* @param {Signature} signature (optional) detached signature for verification
|
|
||||||
* Ignored values: can be safely set, but have no effect
|
|
||||||
* @param {Date} date
|
|
||||||
* @param {Key|Array<Key>} publicKeys
|
|
||||||
*
|
|
||||||
* @returns {Promise<Object>} decrypted and verified message in the form:
|
|
||||||
* { data:String, filename:String, signatures:[{ keyid:String, valid:Boolean }] }
|
|
||||||
* @async
|
|
||||||
* @static
|
|
||||||
*/
|
|
||||||
decrypt(options) {
|
|
||||||
if (options.passwords
|
|
||||||
|| options.sessionKeys
|
|
||||||
|| options.privateKeys
|
|
||||||
){
|
|
||||||
return Promise.reject(gpgme_error('NOT_IMPLEMENTED'));
|
|
||||||
}
|
|
||||||
if ((options.hasOwnProperty('format') && options.format !== 'utf8')
|
|
||||||
|| options.signature
|
|
||||||
){
|
|
||||||
return Promise.reject(gpgme_error('NOT_YET_IMPLEMENTED'));
|
|
||||||
}
|
|
||||||
if ((options.hasOwnProperty('date') && options.date !== null)
|
|
||||||
|| options.publicKeys
|
|
||||||
){
|
|
||||||
if (this._config.unconsidered_params === 'warn'){
|
|
||||||
GPMGEJS_Error('PARAM_IGNORED');
|
|
||||||
} else if (this._config.unconsidered_params === 'reject'){
|
|
||||||
return Promise.reject(GPMGEJS_Error('NOT_IMPLEMENTED'));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return this._GpgME.decrypt(options.message);
|
|
||||||
|
|
||||||
// TODO: translate between:
|
|
||||||
// openpgp:
|
|
||||||
// { data:Uint8Array|String,
|
|
||||||
// filename:String,
|
|
||||||
// signatures:[{ keyid:String, valid:Boolean }] }
|
|
||||||
// and gnupg:
|
|
||||||
// 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.
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Translation layer offering basic Keyring API to be used in Mailvelope.
|
|
||||||
* It may still be changed/expanded/merged with GPGME_Keyring
|
|
||||||
*/
|
|
||||||
class GPGME_Keyring_openpgpmode {
|
|
||||||
constructor(connection){
|
|
||||||
this._gpgme_keyring = new GPGME_Keyring(connection);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a GPGME_Key Object for each Key in the gnupg Keyring. This
|
|
||||||
* includes keys openpgpjs considers 'private' (usable for signing), with
|
|
||||||
* the difference that Key.armored will NOT contain any secret information.
|
|
||||||
* Please also note that a GPGME_Key does not offer full openpgpjs- Key
|
|
||||||
* compatibility.
|
|
||||||
* @returns {Array<GPGME_Key_openpgpmode>}
|
|
||||||
* //TODO: Check if IsDefault is also always hasSecret
|
|
||||||
* TODO Check if async is required
|
|
||||||
*/
|
|
||||||
getPublicKeys(){
|
|
||||||
return translateKeys(
|
|
||||||
this._gpgme_keyring.getKeys(null, true));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the Default Key used for crypto operation in gnupg.
|
|
||||||
* Please note that the armored property does not contained secret key blocks,
|
|
||||||
* despite secret blocks being part of the key itself.
|
|
||||||
* @returns {Promise <GPGME_Key>}
|
|
||||||
*/
|
|
||||||
getDefaultKey(){
|
|
||||||
this._gpgme_keyring.getSubset({defaultKey: true}).then(function(result){
|
|
||||||
if (result.length === 1){
|
|
||||||
return Promise.resolve(
|
|
||||||
translateKeys(result)[0]);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// TODO: Can there be "no default key"?
|
|
||||||
// TODO: Can there be several default keys?
|
|
||||||
return gpgme_error('TODO');
|
|
||||||
}
|
|
||||||
}, function(error){
|
|
||||||
//TODO
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Deletes a Key
|
|
||||||
* @param {Object} Object identifying key
|
|
||||||
* @param {String} key.fingerprint - fingerprint of the to be deleted key
|
|
||||||
* @param {Boolean} key.secret - indicator if private key should be deleted as well
|
|
||||||
|
|
||||||
* @returns {Promise.<Array.<undefined>, Error>} TBD: Not sure what is wanted
|
|
||||||
TODO @throws {Error} error.code = ‘KEY_NOT_EXIST’ - there is no key for the given fingerprint
|
|
||||||
TODO @throws {Error} error.code = ‘NO_SECRET_KEY’ - secret indicator set, but no secret key exists
|
|
||||||
*/
|
|
||||||
deleteKey(key){
|
|
||||||
if (typeof(key) !== "object"){
|
|
||||||
return Promise.reject(gpgme_error('PARAM_WRONG'));
|
|
||||||
}
|
|
||||||
if ( !key.fingerprint || ! isFingerprint(key.fingerprint)){
|
|
||||||
return Promise.reject(gpgme_error('PARAM_WRONG'));
|
|
||||||
}
|
|
||||||
let key_to_delete = createKey(key.fingerprint, this._gpgme_keyring_GpgME);
|
|
||||||
return key_to_delete.deleteKey(key.secret);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* TODO error handling.
|
|
||||||
* Offers the Key information as the openpgpmode wants
|
|
||||||
*/
|
|
||||||
class GPGME_Key_openpgpmode {
|
|
||||||
constructor(value, connection){
|
|
||||||
this.init(value, connection);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Can be either constructed using an existing GPGME_Key, or a fingerprint
|
|
||||||
* and a connection
|
|
||||||
* @param {String|GPGME_Key} value
|
|
||||||
* @param {Connection} connection
|
|
||||||
*/
|
|
||||||
init (value, connection){
|
|
||||||
if (!this._GPGME_Key && value instanceof GPGME_Key){
|
|
||||||
this._GPGME_Key = value;
|
|
||||||
} else if (!this._GPGME_Key && isFingerprint(value) &&
|
|
||||||
connection instanceof Connection){
|
|
||||||
this._GPGME_Key = createKey(value, connection);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
get fingerprint(){
|
|
||||||
return this._GPGME_Key.fingerprint;
|
|
||||||
}
|
|
||||||
|
|
||||||
get armor(){
|
|
||||||
return this._GPGME_Key.armored;
|
|
||||||
}
|
|
||||||
|
|
||||||
get secret(){
|
|
||||||
return this._GPGME_Key.hasSecret;
|
|
||||||
}
|
|
||||||
|
|
||||||
get default(){
|
|
||||||
return this._GPGME_Key.isDefault;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* creates GPGME_Key_openpgpmode from GPGME_Keys
|
|
||||||
* @param {GPGME_Key|Array<GPGME_Key>} input keys
|
|
||||||
* @returns {Array<GPGME_Key_openpgpmode>}
|
|
||||||
*/
|
|
||||||
function translateKeys(input){
|
|
||||||
//TODO: does not check if inpout is okay!
|
|
||||||
if (!input){
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
if (!Array.isArray(input)){
|
|
||||||
input = [input];
|
|
||||||
}
|
|
||||||
let resultset = [];
|
|
||||||
for (let i=0; i< input.length; i++) {
|
|
||||||
resultset.push(new GPGME_Key_openpgpmode(input[i]));
|
|
||||||
}
|
|
||||||
return resultset;
|
|
||||||
}
|
|
@ -20,7 +20,6 @@
|
|||||||
|
|
||||||
import { GpgME } from "./gpgmejs";
|
import { GpgME } from "./gpgmejs";
|
||||||
import { gpgme_error } from "./Errors";
|
import { gpgme_error } from "./Errors";
|
||||||
import { GpgME_openpgpmode } from "./gpgmejs_openpgpjs";
|
|
||||||
import { Connection } from "./Connection";
|
import { Connection } from "./Connection";
|
||||||
import { defaultConf, availableConf } from "./Config";
|
import { defaultConf, availableConf } from "./Config";
|
||||||
|
|
||||||
@ -43,11 +42,7 @@ function init(config){
|
|||||||
reject(gpgme_error('CONN_NO_CONNECT'));
|
reject(gpgme_error('CONN_NO_CONNECT'));
|
||||||
}
|
}
|
||||||
if (connection.isConnected === true){
|
if (connection.isConnected === true){
|
||||||
if (_conf.api_style && _conf.api_style === 'gpgme_openpgpjs'){
|
resolve(new GpgME(connection, _conf));
|
||||||
resolve(new GpgME_openpgpmode(connection, _conf));
|
|
||||||
} else {
|
|
||||||
resolve(new GpgME(connection));
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
reject(gpgme_error('CONN_NO_CONNECT'));
|
reject(gpgme_error('CONN_NO_CONNECT'));
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user