Implement signAndEncryptMessage function. Fix packet_one_pass_signature.write().

This commit is contained in:
Thomas Oberndörfer 2013-11-19 16:30:41 +01:00
parent 93376b6e13
commit 22ad0d3505
8 changed files with 193 additions and 106 deletions

File diff suppressed because one or more lines are too long

View File

@ -119,6 +119,39 @@ function message(packetlist) {
return new message(packetlist);
}
/**
* Sign the message (the literal data packet of the message)
* @param {key} privateKey private key with decrypted secret key data for signing
* @return {[message]} new message with encrypted content
*/
this.sign = function(privateKey) {
var packetlist = new packet.list();
var onePassSig = new packet.one_pass_signature();
onePassSig.type = enums.signature.text;
//TODO get preferred hashg algo from signature
onePassSig.hashAlgorithm = config.prefer_hash_algorithm;
var signingKeyPacket = privateKey.getSigningKeyPacket();
onePassSig.publicKeyAlgorithm = signingKeyPacket.algorithm;
onePassSig.signingKeyId = signingKeyPacket.getKeyId();
packetlist.push(onePassSig);
var literalDataPacket = this.packets.findPacket(enums.packet.literal);
if (!literalDataPacket) throw new Error('No literal data packet to sign.');
packetlist.push(literalDataPacket);
var signaturePacket = new packet.signature();
signaturePacket.signatureType = enums.signature.text;
signaturePacket.hashAlgorithm = config.prefer_hash_algorithm;
signaturePacket.publicKeyAlgorithm = signingKeyPacket.algorithm;
if (!signingKeyPacket.isDecrypted) throw new Error('Private key is not decrypted.');
signaturePacket.sign(signingKeyPacket, literalDataPacket);
packetlist.push(signaturePacket);
return new message(packetlist);
}
/**
* Decrypts a message and generates user interface message out of the found.
* MDC will be verified as well as message signatures

View File

@ -38,10 +38,10 @@ var message = require('./message.js');
function _openpgp() {
/**
* encrypts message with keys
* @param {[key]} keys array of keys, used to encrypt the message
* encrypts message text with keys
* @param {[key]} keys array of keys, used to encrypt the message
* @param {String} text message as native JavaScript string
* @return {String} encrypted ASCII armored message
* @return {String} encrypted ASCII armored message
*/
function encryptMessage(keys, text) {
var msg = message.fromText(text);
@ -50,16 +50,27 @@ function _openpgp() {
return armored;
}
function encryptAndSignMessage(publicKeys, privateKey, message) {
/**
* signs message text and encrypts it
* @param {[key]} publicKeys array of keys, used to encrypt the message
* @param {key} privateKey private key with decrypted secret key data for signing
* @param {String} text message as native JavaScript string
* @return {String} encrypted ASCII armored message
*/
function signAndEncryptMessage(publicKeys, privateKey, text) {
var msg = message.fromText(text);
msg = msg.sign(privateKey);
msg = msg.encrypt(publicKeys);
var armored = armor.encode(enums.armor.message, msg.packets.write());
return armored;
}
/**
* decrypts message
* @param {key} privateKey private key with decrypted secret key data
* @param {message} message the message object with the encrypted data
* @return {String|null} decrypted message as as native JavaScript string
* or null if no literal data found
* @param {key} privateKey private key with decrypted secret key data
* @param {message} message the message object with the encrypted data
* @return {String|null} decrypted message as as native JavaScript string
* or null if no literal data found
*/
function decryptMessage(privateKey, message) {
message = message.decrypt(privateKey);
@ -274,7 +285,7 @@ function _openpgp() {
this.generateKeyPair = generateKeyPair;
this.write_signed_message = write_signed_message;
this.write_signed_and_encrypted_message = write_signed_and_encrypted_message;
this.signAndEncryptMessage = signAndEncryptMessage;
this.encryptMessage = encryptMessage;
this.decryptMessage = decryptMessage;

View File

@ -41,9 +41,7 @@ module.exports = function packet_one_pass_signature() {
/**
* parsing function for a one-pass signature packet (tag 4).
* @param {String} bytes payload of a tag 4 packet
* @param {Integer} position position to start reading from the bytes string
* @param {Integer} len length of the packet or the remaining length of bytes at position
* @return {openpgp_packet_encrypteddata} object representation
* @return {packet_one_pass_signature} object representation
*/
this.read = function(bytes) {
var mypos = 0;
@ -75,27 +73,17 @@ module.exports = function packet_one_pass_signature() {
/**
* creates a string representation of a one-pass signature packet
* @param {Integer} type Signature types as described in RFC4880 Section 5.2.1.
* @param {Integer} hashalgorithm the hash algorithm used within the signature
* @param {openpgp_msg_privatekey} privatekey the private key used to generate the signature
* @param {Integer} length length of data to be signed
* @param {boolean} nested boolean showing whether the signature is nested.
* "true" indicates that the next packet is another One-Pass Signature packet
* that describes another signature to be applied to the same message data.
* @return {String} a string representation of a one-pass signature packet
*/
this.write = function(type, hashalgorithm, privatekey, length, nested) {
this.write = function() {
var result = "";
result += String.fromCharCode(3);
result += String.fromCharCode(enums.write(enums.signature, type));
result += String.fromCharCode(enums.write(enums.signature, this.type));
result += String.fromCharCode(enums.write(enums.hash, this.hashAlgorithm));
result += String.fromCharCode(enums.write(enums.publicKey, privatekey.algorithm));
result += privatekey.getKeyId().write();
if (nested)
result += String.fromCharCode(0);
else
result += String.fromCharCode(1);
result += String.fromCharCode(enums.write(enums.publicKey, this.publicKeyAlgorithm));
result += this.signingKeyId.write();
result += String.fromCharCode(this.flags);
return result;
}

View File

@ -107,7 +107,7 @@ module.exports = function packetlist() {
/**
* Traverses packet tree and returns first matching packet
* @param {enums.packet} type The packet type
* @return {[type]}
* @return {packet|null}
*/
this.findPacket = function(type) {
var packetlist = this.filterByTag(type);

View File

@ -400,12 +400,9 @@ module.exports = function packet_signature() {
switch (type) {
case t.binary:
return data.getBytes();
// conversion to CRLF line endings done in literal data packet
case t.text:
return this.toSign(t.binary, data)
.replace(/\r\n/g, '\n')
.replace(/\n/g, '\r\n');
return data.getBytes();
case t.standalone:
return '';

View File

@ -133,7 +133,7 @@ unit.register("Message encryption/decryption", function() {
} catch (e) {
error = e;
}
result.push(new unit.result('Calling decryptMessage with not encrypted key packet leads to exception: \'' + (error || '') + '\'', error));
result.push(new unit.result('Calling decryptMessage with not decrypted key packet leads to exception: \'' + (error || '') + '\'', error));
success = privKey.decryptKeyPacket(keyids, 'hello world');

File diff suppressed because one or more lines are too long