diff --git a/.gitignore b/.gitignore index c06d527..36eca63 100644 --- a/.gitignore +++ b/.gitignore @@ -2,4 +2,5 @@ build/ node_modules/ npm-debug.log* .DS_Store -*~ \ No newline at end of file +*~ +yarn-error.log diff --git a/README.md b/README.md index 3697419..0853d1e 100644 --- a/README.md +++ b/README.md @@ -38,6 +38,7 @@ So far, you can only add a key (public or secret) and list those keys. Simple. 1. Adding a key +```js var s = "-----BEGIN PGP PUBLIC KEY BLOCK ..." var fingerprint = gpgme.importKey(s) if (fingerprint === false) { @@ -45,6 +46,7 @@ So far, you can only add a key (public or secret) and list those keys. Simple. } else { console.log("Key fingerprint :" + fingerprint); } +``` 2. Listing keys ```js diff --git a/src/context.cc b/src/context.cc index b69eddc..fe4ca98 100644 --- a/src/context.cc +++ b/src/context.cc @@ -1,10 +1,41 @@ #include /* locale support */ #include "context.h" #include +#include using namespace v8; Nan::Persistent ContextWrapper::constructor; +static gpgme_error_t passphrase_cb (void *opaque, const char *uid_hint, const char *passphrase_info, int last_was_bad, int fd) { + int res; + char pass[255]; + + int inputLen = strlen((const char*) opaque); + + if (inputLen >= 255) { + // Avoid Buffer Overflow + inputLen = 254; + } + + memcpy(pass, (const char *)opaque, inputLen); + int passlen = strlen (pass); + pass[passlen] = '\n'; + pass[passlen+1] = 0; + passlen += 1; + int off = 0; + + do { + res = write (fd, &pass[off], passlen - off); + if (res > 0) + off += res; + } + while (res > 0 && off != passlen); + + return off == passlen ? 0 : gpgme_error_from_errno (errno); + + return 0; +} + ContextWrapper::ContextWrapper(Local conf) : _context(NULL) { /* Fetch the configuration options or use defaults */ @@ -76,6 +107,7 @@ ContextWrapper::ContextWrapper(Local conf) : _context(NULL) { return; } gpgme_set_armor(_context, armored); + gpgme_set_pinentry_mode(_context, GPGME_PINENTRY_MODE_LOOPBACK); } ContextWrapper::~ContextWrapper() { @@ -93,7 +125,8 @@ NAN_MODULE_INIT(ContextWrapper::Init) { SetPrototypeMethod(tpl, "toString", toString); SetPrototypeMethod(tpl, "importKey", importKey); SetPrototypeMethod(tpl, "listKeys", listKeys); - SetPrototypeMethod(tpl, "cipher", cipher); + SetPrototypeMethod(tpl, "cipher", cipher); + SetPrototypeMethod(tpl, "sign", sign); constructor.Reset(tpl->GetFunction()); Nan::Set(target, Nan::New("GpgMeContext").ToLocalChecked(), tpl->GetFunction()); @@ -105,13 +138,13 @@ NAN_METHOD(ContextWrapper::New) { Local configuration; // Invoked as constructor: `new MyObject(...)` if (info.Length() >= 1 && info[0]->IsObject()) { - configuration = Nan::To(info[0]).ToLocalChecked(); + configuration = Nan::To(info[0]).ToLocalChecked(); } else { configuration = Nan::New(); } ContextWrapper *contextWrapper = new ContextWrapper(configuration); - + contextWrapper->Wrap(info.This()); info.GetReturnValue().Set(info.This()); } else { @@ -174,6 +207,32 @@ NAN_METHOD(ContextWrapper::cipher) { } +NAN_METHOD(ContextWrapper::sign) { + ContextWrapper* context = ObjectWrap::Unwrap(info.This()); + //arg0 should be the finger print of the key to use + //arg1 should be the payload to sign + //arg2 should be the password for the key + + if (info.Length() != 3) Nan::ThrowError("Missing argument (fingerprint, message, password)"); + if (!info[0]->IsString()) Nan::ThrowError("fingerprint should be a string"); + if (!info[1]->IsString()) Nan::ThrowError("message should be a string"); + if (!info[2]->IsString()) Nan::ThrowError("password should be a string"); + + Local fingerprint = Nan::To(info[0]).ToLocalChecked(); + Local message = Nan::To(info[1]).ToLocalChecked(); + Local password = Nan::To(info[2]).ToLocalChecked(); + + char *data = context->signPayload(fingerprint, message, password); + if (data == NULL) { + info.GetReturnValue().Set(false); + return; + } + + info.GetReturnValue().Set(Nan::New(data).ToLocalChecked()); + gpgme_free(data); +} + + NAN_METHOD(ContextWrapper::listKeys) { ContextWrapper* context = ObjectWrap::Unwrap(info.This()); @@ -185,7 +244,7 @@ NAN_METHOD(ContextWrapper::listKeys) { Nan::ThrowError("Internal error when retrieving the keys"); return; } - + Local v8Keys= Nan::New(); std::list::const_iterator iterator; int i; @@ -216,11 +275,11 @@ NAN_METHOD(ContextWrapper::listKeys) { v8Keys->Set(i, v8Key); v8Key->Set(Nan::New("secret").ToLocalChecked(), (*iterator)->secret ? Nan::True() : Nan::False()); - + v8Keys->Set(i, v8Key); gpgme_key_unref((*iterator)); } - + info.GetReturnValue().Set(v8Keys); } @@ -235,7 +294,7 @@ char* ContextWrapper::getVersion() { } -bool ContextWrapper::addKey(char *key, int length, std::string& fingerprint) { +bool ContextWrapper::addKey(char *key, int length, std::string& fingerprint) { gpgme_data_t gpgme_key_data; gpgme_error_t err; @@ -267,7 +326,7 @@ bool ContextWrapper::getKeys(std::list *keys) { do { err = gpgme_op_keylist_next(_context, &key); if (err) break; - keys->insert(keys->end(), key); + keys->insert(keys->end(), key); } while (err == GPG_ERR_NO_ERROR); if (gpg_err_code (err) != GPG_ERR_EOF) { std::cout << "FAIL\n"; @@ -277,6 +336,73 @@ bool ContextWrapper::getKeys(std::list *keys) { return true; } +char *ContextWrapper::signPayload(v8::Local fpr, v8::Local msg, v8::Local passphrase) { + gpgme_error_t err; + gpgme_key_t recp = NULL; + char *fingerprint = StringToCharPointer(fpr); + char *message = StringToCharPointer(msg); + char *pass = StringToCharPointer(passphrase); + + gpgme_set_passphrase_cb (_context, passphrase_cb, pass); + + err = gpgme_get_key(_context, fingerprint, &recp, 1); + if(err != GPG_ERR_NO_ERROR) { + free(fingerprint); + free(message); + free(pass); + Nan::ThrowError("Error loading private key."); + return NULL; + } + + gpgme_signers_clear(_context); + err = gpgme_signers_add (_context, recp); + gpgme_key_unref (recp); + if(err != GPG_ERR_NO_ERROR) { + Nan::ThrowError("Error adding key to signer list"); + free(fingerprint); + free(message); + free(pass); + return NULL; + } + + gpgme_data_t message_data; + err = gpgme_data_new_from_mem(&message_data, message, msg->Length(), 0); + if(err != GPG_ERR_NO_ERROR) { + Nan::ThrowError("Error allocating buffer for message"); + free(fingerprint); + free(message); + free(pass); + return NULL; + } + + gpgme_data_t signer; + gpgme_data_new(&signer); + err = gpgme_op_sign(_context, message_data, signer, GPGME_SIG_MODE_NORMAL); + free(fingerprint); + free(message); + free(pass); + + if (err != GPG_ERR_NO_ERROR) { + Nan::ThrowError("Error signing message. If GPG2 check if allow-pinentry-loopback is enabled in agent or use gpg-preset-passphrase"); + gpgme_data_release(signer); + return NULL; + } + + gpgme_sign_result_t res = gpgme_op_sign_result(_context); + if (!res->signatures) { + gpgme_data_release(signer); + return NULL; + }; + + size_t nread; + char *data = gpgme_data_release_and_get_mem(signer, &nread); + char *encrypted_message = (char *) malloc((nread + 1) * sizeof(char)); + memset(encrypted_message, 0, nread); + memcpy(encrypted_message, data, nread); + gpgme_free(data); + return encrypted_message; +} + char *ContextWrapper::cipherPayload(Local fpr, Local msg) { gpgme_error_t err; @@ -296,15 +422,16 @@ char *ContextWrapper::cipherPayload(Local fpr, Local msg) { if(err != GPG_ERR_NO_ERROR) { free(fingerprint); free(message); - return NULL; + return NULL; } gpgme_data_t cipher; gpgme_data_new(&cipher); err = gpgme_op_encrypt(_context, recp, GPGME_ENCRYPT_ALWAYS_TRUST, message_data, cipher); + gpgme_key_unref (recp[0]); free(fingerprint); free(message); - + if (err != GPG_ERR_NO_ERROR) { gpgme_data_release(cipher); return NULL; diff --git a/src/context.h b/src/context.h index 10c4fc8..0a94a74 100644 --- a/src/context.h +++ b/src/context.h @@ -23,14 +23,16 @@ class ContextWrapper : public ObjectWrap { bool addKey(char *key, int length, std::string& fingerprint); bool getKeys(std::list *keys); char *cipherPayload(v8::Local fpr, v8::Local msg); + char *signPayload(v8::Local fpr, v8::Local msg, v8::Local passphrase); char *StringToCharPointer(v8::Local str); static NAN_METHOD(New); - static NAN_METHOD(toString); + static NAN_METHOD(toString); static NAN_METHOD(importKey); static NAN_METHOD(listKeys); static NAN_METHOD(cipher); - + static NAN_METHOD(sign); + public: static Persistent constructor; diff --git a/tests/context.js b/tests/context.js index c860a1c..ada189a 100644 --- a/tests/context.js +++ b/tests/context.js @@ -1,9 +1,14 @@ var test = require('tape'); var GpgMe = require('..'); +var tmpFolder = '/tmp/' + Date.now().toString(36).toUpperCase(); // To avoid other keys in test. +var fs = require('fs'); + +fs.mkdirSync(tmpFolder); +fs.writeFileSync(tmpFolder + '/gpg-agent.conf', 'allow-loopback-pinentry\n'); test('import_keys', function (t) { t.plan(2); - + var ascii_key = '-----BEGIN PGP PUBLIC KEY BLOCK-----\n\ Version: GnuPG v1\n\ \n\ @@ -35,12 +40,121 @@ hRdoZcvrkhSh5RKiADM8RfW04UEkb/tDHSuvkH7HrgdIzd/WQwDsZHnIjNMQAEMl\n\ oezv1L1SiuNonPtwiYcbphGo\n\ =2bdq\n\ -----END PGP PUBLIC KEY BLOCK-----', - + privateKey = '-----BEGIN PGP PRIVATE KEY BLOCK-----\n\ +Version: GnuPG v1\n\ +\n\ +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\n\ +lbMia0X7KJbYnbG5XLEDiMjzDQ==\n\ +=SC0f\n\ +-----END PGP PRIVATE KEY BLOCK-----', fingerprint = '3B2302E57CC7AA3D8D4600E89DAC32BD82A1C9DC', + privateKeyFingerPrint = '629307840E6D187E6388192FD7362B4CC546DB11', import_fingerprint, gpgme; - gpgme = new GpgMe(); + gpgme = new GpgMe({ + keyring_path: tmpFolder, + }); import_fingerprint = gpgme.importKey(ascii_key); t.equal(fingerprint, import_fingerprint); @@ -48,17 +162,21 @@ oezv1L1SiuNonPtwiYcbphGo\n\ import_fingerprint = gpgme.importKey(ascii_key); t.equal(false, import_fingerprint); + private_key_fp = gpgme.importKey(privateKey); }); test('list_keys', function (t) { t.plan(2); - + var keys, gpgme, fingerprint = '3B2302E57CC7AA3D8D4600E89DAC32BD82A1C9DC', email = 'sebastien@requiem.fr'; - gpgme = new GpgMe(); + + gpgme = new GpgMe({ + keyring_path: tmpFolder, + }); keys = gpgme.listKeys(); t.equal(fingerprint, keys[0].fingerprint); @@ -67,14 +185,16 @@ test('list_keys', function (t) { test('cipher', function (t) { t.plan(2); - + var gpgme, fingerprint = '3B2302E57CC7AA3D8D4600E89DAC32BD82A1C9DC', payload = 'Can you read this ?', needle = '-----BEGIN PGP MESSAGE-----', cipher; - gpgme = new GpgMe(); + gpgme = new GpgMe({ + keyring_path: tmpFolder, + }); cipher = gpgme.cipher(fingerprint, payload); t.equal(0, cipher.indexOf(needle)); @@ -83,3 +203,20 @@ test('cipher', function (t) { cipher = gpgme.cipher('unknown-fingerprint', payload); t.equal(false, cipher); }); + +test('signing', function (t) { + t.plan(1); + + var gpgme, + fingerprint = '629307840E6D187E6388192FD7362B4CC546DB11', + payload = 'Can you read this ?', + needle = '-----BEGIN PGP MESSAGE-----', + cipher; + + gpgme = new GpgMe({ + keyring_path: tmpFolder, + }); + + var signed = gpgme.sign(fingerprint, payload, "123456"); + t.equal(0, signed.indexOf(needle)); +}) diff --git a/yarn.lock b/yarn.lock new file mode 100644 index 0000000..b620b40 --- /dev/null +++ b/yarn.lock @@ -0,0 +1,205 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +balanced-match@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" + +bindings@^1.2.1: + version "1.3.0" + resolved "https://registry.yarnpkg.com/bindings/-/bindings-1.3.0.tgz#b346f6ecf6a95f5a815c5839fc7cdb22502f1ed7" + +brace-expansion@^1.1.7: + version "1.1.8" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.8.tgz#c07b211c7c952ec1f8efd51a77ef0d1d3990a292" + dependencies: + balanced-match "^1.0.0" + concat-map "0.0.1" + +concat-map@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" + +deep-equal@~1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-1.0.1.tgz#f5d260292b660e084eff4cdbc9f08ad3247448b5" + +define-properties@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.2.tgz#83a73f2fea569898fb737193c8f873caf6d45c94" + dependencies: + foreach "^2.0.5" + object-keys "^1.0.8" + +defined@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/defined/-/defined-1.0.0.tgz#c98d9bcef75674188e110969151199e39b1fa693" + +es-abstract@^1.5.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.10.0.tgz#1ecb36c197842a00d8ee4c2dfd8646bb97d60864" + dependencies: + es-to-primitive "^1.1.1" + function-bind "^1.1.1" + has "^1.0.1" + is-callable "^1.1.3" + is-regex "^1.0.4" + +es-to-primitive@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.1.1.tgz#45355248a88979034b6792e19bb81f2b7975dd0d" + dependencies: + is-callable "^1.1.1" + is-date-object "^1.0.1" + is-symbol "^1.0.1" + +for-each@~0.3.2: + version "0.3.2" + resolved "https://registry.yarnpkg.com/for-each/-/for-each-0.3.2.tgz#2c40450b9348e97f281322593ba96704b9abd4d4" + dependencies: + is-function "~1.0.0" + +foreach@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/foreach/-/foreach-2.0.5.tgz#0bee005018aeb260d0a3af3ae658dd0136ec1b99" + +fs.realpath@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" + +function-bind@^1.0.2, function-bind@^1.1.1, function-bind@~1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" + +glob@~7.1.2: + version "7.1.2" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.2.tgz#c19c9df9a028702d678612384a6552404c636d15" + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.4" + once "^1.3.0" + path-is-absolute "^1.0.0" + +has@^1.0.1, has@~1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/has/-/has-1.0.1.tgz#8461733f538b0837c9361e39a9ab9e9704dc2f28" + dependencies: + function-bind "^1.0.2" + +inflight@^1.0.4: + version "1.0.6" + resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" + dependencies: + once "^1.3.0" + wrappy "1" + +inherits@2, inherits@~2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" + +is-callable@^1.1.1, is-callable@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.1.3.tgz#86eb75392805ddc33af71c92a0eedf74ee7604b2" + +is-date-object@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.1.tgz#9aa20eb6aeebbff77fbd33e74ca01b33581d3a16" + +is-function@~1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-function/-/is-function-1.0.1.tgz#12cfb98b65b57dd3d193a3121f5f6e2f437602b5" + +is-regex@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.0.4.tgz#5517489b547091b0930e095654ced25ee97e9491" + dependencies: + has "^1.0.1" + +is-symbol@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.1.tgz#3cc59f00025194b6ab2e38dbae6689256b660572" + +minimatch@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" + dependencies: + brace-expansion "^1.1.7" + +minimist@~1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284" + +nan@^2.3.5: + version "2.8.0" + resolved "https://registry.yarnpkg.com/nan/-/nan-2.8.0.tgz#ed715f3fe9de02b57a5e6252d90a96675e1f085a" + +object-inspect@~1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.3.0.tgz#5b1eb8e6742e2ee83342a637034d844928ba2f6d" + +object-keys@^1.0.8: + version "1.0.11" + resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.0.11.tgz#c54601778ad560f1142ce0e01bcca8b56d13426d" + +once@^1.3.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" + dependencies: + wrappy "1" + +path-is-absolute@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" + +path-parse@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.5.tgz#3c1adf871ea9cd6c9431b6ea2bd74a0ff055c4c1" + +resolve@~1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.4.0.tgz#a75be01c53da25d934a98ebd0e4c4a7312f92a86" + dependencies: + path-parse "^1.0.5" + +resumer@~0.0.0: + version "0.0.0" + resolved "https://registry.yarnpkg.com/resumer/-/resumer-0.0.0.tgz#f1e8f461e4064ba39e82af3cdc2a8c893d076759" + dependencies: + through "~2.3.4" + +string.prototype.trim@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/string.prototype.trim/-/string.prototype.trim-1.1.2.tgz#d04de2c89e137f4d7d206f086b5ed2fae6be8cea" + dependencies: + define-properties "^1.1.2" + es-abstract "^1.5.0" + function-bind "^1.0.2" + +tape@^4.2.0: + version "4.8.0" + resolved "https://registry.yarnpkg.com/tape/-/tape-4.8.0.tgz#f6a9fec41cc50a1de50fa33603ab580991f6068e" + dependencies: + deep-equal "~1.0.1" + defined "~1.0.0" + for-each "~0.3.2" + function-bind "~1.1.0" + glob "~7.1.2" + has "~1.0.1" + inherits "~2.0.3" + minimist "~1.2.0" + object-inspect "~1.3.0" + resolve "~1.4.0" + resumer "~0.0.0" + string.prototype.trim "~1.1.2" + through "~2.3.8" + +through@~2.3.4, through@~2.3.8: + version "2.3.8" + resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" + +wrappy@1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"