Open iamtedko opened 8 years ago
hi @iamtedko - in our email chat you mentioned hitting an error with some sample code. Can you post your attempt and the error?
Here's the error I keep getting:
/node_modules/kbpgp/lib/openpgp/clearsign.js:168 unhashed_subpackets: [new Issuer(this.signing_key.get_key_id())] ^
TypeError: this.signing_key.get_key_id is not a function at ClearSigner._sign_msg (/node_modules/kbpgp/lib/openpgp/clearsign.js:168:59) at iced.Deferrals.parent (/node_modules/kbpgp/lib/openpgp/clearsign.js:233:19) at /node_modules/kbpgp/lib/openpgp/clearsign.js:242:13 at Deferrals.exports.Deferrals.Deferrals._call (/node_modules/kbpgp/node_modules/iced-runtime/lib/runtime.js:86:16) at /node_modules/kbpgp/node_modules/iced-runtime/lib/runtime.js:98:26 at exports.trampoline.trampoline (/node_modules/kbpgp/node_modules/iced-runtime/lib/runtime.js:64:14) at Deferrals.exports.Deferrals.Deferrals._fulfill (/node_modules/kbpgp/node_modules/iced-runtime/lib/runtime.js:96:16) at iced.Deferrals.parent (/node_modules/kbpgp/lib/openpgp/clearsign.js:223:28) at ClearSigner.run (/node_modules/kbpgp/lib/openpgp/clearsign.js:225:15) at /node_modules/kbpgp/lib/openpgp/clearsign.js:449:11
Is this caused by passing in a wrong "signing_key" object?
hey @iamtedko - thanks for posting. I think this'll require a response from @maxtaco but I know he's on vacation this week... so I'd expect next week before he can reply. For what it's worth, I tried too and got the same error, so I think we're just doing it wrong.
Based on the previously closed issue ( https://github.com/keybase/kbpgp/issues/32 ) I thought this code would work (coffeescript):
kbpgp = require 'kbpgp'
F = kbpgp.const.openpgp
opts =
userid: "User McTester (Born 1979) <user@example.com>"
primary:
nbits: 1024 # for testing...
flags: F.certify_keys | F.sign_data | F.auth | F.encrypt_comm | F.encrypt_storage
expire_in: 0 # never expire
subkeys: [
{
nbits: 1024
flags: F.sign_data
expire_in: 86400 * 365 * 8 # 8 years
}
{
nbits: 1024
flags: F.encrypt_comm | F.encrypt_storage
expire_in: 86400 * 365 * 2
}
]
kbpgp.KeyManager.generate opts, (err, alice) ->
# and sign alice's subkeys
if (not err) then alice.sign {}, (err) ->
console.log "Made a nice test key for alice..."
kbpgp.clearsign { msg : "hi", signing_key: alice }, (err, msg) ->
console.log err, msg
Ok, I wouldn't trust this without @maxtaco 's seal of approval, but poking into the code, I think this is what you want:
kbpgp.KeyManager.generate opts, (err, alice) ->
# and sign alice's subkeys
if (not err) then alice.sign {}, (err) ->
console.log "Made a nice test key for alice..."
# figure out which of her keys is best for signing!
# clearsign doesn't do this automatically.
flags = F.key_flags.sign_data
signing_key = alice.find_best_pgp_key(flags)
kbpgp.clearsign { msg : "hi", signing_key}, (err, msg) ->
console.log msg
with other kbpgp operations this step is done automatically with the keymanager, but that hasn't been implemented for clearsigning yet.
@malgorithms, just checking to see if I'm reading your last comment correctly: do you mean that eventually there'll be a box method created to do clearsigning (similar to how signing works now)?
Hi. I would like to know if there is any improvement on the subject? It's hard to find information about kbpgp and clearsign
I've got something which appears to be running and is identified as a signature, GPG is telling me its an invalid signature:
module.exports.signData = function(data, privKey, passphrase){
"use strict";
var deferred = q.defer();
getKey(privKey, passphrase).then(function(key) {
var params = {
msg: data,
signing_key: key.find_signing_pgp_key()
};
kbpgp.clearsign(params, function (err, msg) {
if (err) {
deferred.reject(err);
} else {
var signature = msg.substring(msg.indexOf('-----BEGIN PGP SIGNATURE-----'));
deferred.resolve(signature);
}
});
});
return deferred.promise;
}
function getKey(privKey, passphrase){
"use strict";
var deferred = q.defer();
kbpgp.KeyManager.import_from_armored_pgp({
armored: privKey
}, function(error, key) {
if(error)
deferred.reject(error);
else {
if (key.is_pgp_locked()) {
key.unlock_pgp({
passphrase: passphrase
}, function(err) {
if(err)
deferred.reject(err)
else
deferred.resolve(key);
});
} else
deferred.resolve(key);
}
});
return deferred.promise;
}
Double-checking my work now to make sure I didn't somehow miss something.
This is what I'm running it with:
var fs = require('fs');
var lib_crypto = require('../app-shared-libraries/cryptography.js');
var key = fs.readFileSync('../.Research/SampleFiles/keys/privKey.pgp', 'utf8');
var passphrase = fs.readFileSync('../.Research/SampleFiles/keys/passphrase.txt', 'utf8');
var releaseFile = fs.readFileSync('../.Research/SampleFiles/Release.txt', 'utf8');
lib_crypto.signData(releaseFile, key, passphrase).then(function(answer1){
"use strict";
fs.writeFileSync('../.Research/SampleFiles/Release.txt.asc', answer1);
}, function(error) {
"use strict";
console.log(error.message, error.stack);
});
And this is how I'm validating and it seems to be failing:
gpg --verify Release.txt.asc
gpg: assuming signed data in `Release.txt'
gpg: Signature made Fri Jun 30 22:46:56 2017 EDT using RSA key ID 87DD0060
gpg: BAD signature from "Joe Bob <joe@bob.com>"
Okay, I think I figured it out. There appears to be a bug in the way the final line-feed is handled. Currently it appears that the final line-feed is removed before the signature is generated. This makes the signature properly validate when its a composite message, but not when you try and use the signature to validate the original file. If you simple remove the trailing line-feed from the original file, everything works fine.
Based on the following document: https://superuser.com/questions/933333/how-to-create-a-single-gnupg-signature-which-works-on-both-lf-and-cr-lf-versions
It appears the line-feeds are only supposed to be messed to if the signature is in "text-mode" which is a sigtype of 0x01. Even then it looks like the substitution is typically changing \n to \r\n, but in any case the sigtype being generated is of 0x00 and not the textmode's 0x01.
I'll open a new issue with those repo-steps, but in the meantime anyone who is looking to clear-sign should be able to use the sample-code above. As long as they either have a file without an extra line-feed at the end, or don't try to detach the signature it should be fine.
Hi,
Looking through the documentation, I didn't see anything that would you clearsign a message. However, I know that it works on the command-line client. Would it be possible to provide some more information about that?
Thanks!