Refactor key generation to use callback
* TODO: reactive native web crypto in rsa.js:142 * TODO: generate publicExponent Uint8Array from argument E in rsa.js:148 * TODO: signing with generated web crypto key fails with "Could not find valid key packet for signing in key"
This commit is contained in:
parent
d6963f2017
commit
cbe4a17ccb
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
"name": "openpgp",
|
"name": "openpgp",
|
||||||
"description": "OpenPGP.js is a Javascript implementation of the OpenPGP protocol. This is defined in RFC 4880.",
|
"description": "OpenPGP.js is a Javascript implementation of the OpenPGP protocol. This is defined in RFC 4880.",
|
||||||
"version": "0.7.2",
|
"version": "0.8.0-dev",
|
||||||
"homepage": "http://openpgpjs.org/",
|
"homepage": "http://openpgpjs.org/",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=0.8"
|
"node": ">=0.8"
|
||||||
|
|
|
@ -1,19 +1,19 @@
|
||||||
// GPG4Browsers - An OpenPGP implementation in javascript
|
// GPG4Browsers - An OpenPGP implementation in javascript
|
||||||
// Copyright (C) 2011 Recurity Labs GmbH
|
// Copyright (C) 2011 Recurity Labs GmbH
|
||||||
//
|
//
|
||||||
// This library is free software; you can redistribute it and/or
|
// This library is free software; you can redistribute it and/or
|
||||||
// modify it under the terms of the GNU Lesser General Public
|
// modify it under the terms of the GNU Lesser General Public
|
||||||
// License as published by the Free Software Foundation; either
|
// License as published by the Free Software Foundation; either
|
||||||
// version 3.0 of the License, or (at your option) any later version.
|
// version 3.0 of the License, or (at your option) any later version.
|
||||||
//
|
//
|
||||||
// This library is distributed in the hope that it will be useful,
|
// This library is distributed in the hope that it will be useful,
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
// Lesser General Public License for more details.
|
// Lesser General Public License for more details.
|
||||||
//
|
//
|
||||||
// You should have received a copy of the GNU Lesser General Public
|
// You should have received a copy of the GNU Lesser General Public
|
||||||
// License along with this library; if not, write to the Free Software
|
// License along with this library; if not, write to the Free Software
|
||||||
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
|
||||||
// The GPG4Browsers crypto interface
|
// The GPG4Browsers crypto interface
|
||||||
|
|
||||||
|
@ -32,12 +32,12 @@ var random = require('./random.js'),
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
/**
|
/**
|
||||||
* Encrypts data using the specified public key multiprecision integers
|
* Encrypts data using the specified public key multiprecision integers
|
||||||
* and the specified algorithm.
|
* and the specified algorithm.
|
||||||
* @param {module:enums.publicKey} algo Algorithm to be used (See {@link http://tools.ietf.org/html/rfc4880#section-9.1|RFC 4880 9.1})
|
* @param {module:enums.publicKey} algo Algorithm to be used (See {@link http://tools.ietf.org/html/rfc4880#section-9.1|RFC 4880 9.1})
|
||||||
* @param {Array<module:type/mpi>} publicMPIs Algorithm dependent multiprecision integers
|
* @param {Array<module:type/mpi>} publicMPIs Algorithm dependent multiprecision integers
|
||||||
* @param {module:type/mpi} data Data to be encrypted as MPI
|
* @param {module:type/mpi} data Data to be encrypted as MPI
|
||||||
* @return {Array<module:type/mpi>} if RSA an module:type/mpi;
|
* @return {Array<module:type/mpi>} if RSA an module:type/mpi;
|
||||||
* if elgamal encryption an array of two module:type/mpi is returned; otherwise null
|
* if elgamal encryption an array of two module:type/mpi is returned; otherwise null
|
||||||
*/
|
*/
|
||||||
publicKeyEncrypt: function(algo, publicMPIs, data) {
|
publicKeyEncrypt: function(algo, publicMPIs, data) {
|
||||||
|
@ -76,9 +76,9 @@ module.exports = {
|
||||||
* Decrypts data using the specified public key multiprecision integers of the private key,
|
* Decrypts data using the specified public key multiprecision integers of the private key,
|
||||||
* the specified secretMPIs of the private key and the specified algorithm.
|
* the specified secretMPIs of the private key and the specified algorithm.
|
||||||
* @param {module:enums.publicKey} algo Algorithm to be used (See {@link http://tools.ietf.org/html/rfc4880#section-9.1|RFC 4880 9.1})
|
* @param {module:enums.publicKey} algo Algorithm to be used (See {@link http://tools.ietf.org/html/rfc4880#section-9.1|RFC 4880 9.1})
|
||||||
* @param {Array<module:type/mpi>} publicMPIs Algorithm dependent multiprecision integers
|
* @param {Array<module:type/mpi>} publicMPIs Algorithm dependent multiprecision integers
|
||||||
* of the public key part of the private key
|
* of the public key part of the private key
|
||||||
* @param {Array<module:type/mpi>} secretMPIs Algorithm dependent multiprecision integers
|
* @param {Array<module:type/mpi>} secretMPIs Algorithm dependent multiprecision integers
|
||||||
* of the private key used
|
* of the private key used
|
||||||
* @param {module:type/mpi} data Data to be encrypted as MPI
|
* @param {module:type/mpi} data Data to be encrypted as MPI
|
||||||
* @return {module:type/mpi} returns a big integer containing the decrypted data; otherwise null
|
* @return {module:type/mpi} returns a big integer containing the decrypted data; otherwise null
|
||||||
|
@ -178,15 +178,19 @@ module.exports = {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
generateMpi: function(algo, bits) {
|
generateMpi: function(algo, bits, callback) {
|
||||||
var result = (function() {
|
switch (algo) {
|
||||||
switch (algo) {
|
case 'rsa_encrypt':
|
||||||
case 'rsa_encrypt':
|
case 'rsa_encrypt_sign':
|
||||||
case 'rsa_encrypt_sign':
|
case 'rsa_sign':
|
||||||
case 'rsa_sign':
|
//remember "publicKey" refers to the crypto/public_key dir
|
||||||
//remember "publicKey" refers to the crypto/public_key dir
|
var rsa = new publicKey.rsa();
|
||||||
var rsa = new publicKey.rsa();
|
rsa.generate(bits, "10001", function(err, keyObject) {
|
||||||
var keyObject = rsa.generate(bits, "10001");
|
if (err) {
|
||||||
|
callback(err);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
var output = [];
|
var output = [];
|
||||||
output.push(keyObject.n);
|
output.push(keyObject.n);
|
||||||
output.push(keyObject.ee);
|
output.push(keyObject.ee);
|
||||||
|
@ -194,17 +198,21 @@ module.exports = {
|
||||||
output.push(keyObject.p);
|
output.push(keyObject.p);
|
||||||
output.push(keyObject.q);
|
output.push(keyObject.q);
|
||||||
output.push(keyObject.u);
|
output.push(keyObject.u);
|
||||||
return output;
|
|
||||||
default:
|
|
||||||
throw new Error('Unsupported algorithm for key generation.');
|
|
||||||
}
|
|
||||||
})();
|
|
||||||
|
|
||||||
return result.map(function(bn) {
|
callback(null, mapResult(output));
|
||||||
var mpi = new type_mpi();
|
});
|
||||||
mpi.fromBigInteger(bn);
|
break;
|
||||||
return mpi;
|
default:
|
||||||
});
|
callback(new Error('Unsupported algorithm for key generation.'));
|
||||||
|
}
|
||||||
|
|
||||||
|
function mapResult(result) {
|
||||||
|
return result.map(function(bn) {
|
||||||
|
var mpi = new type_mpi();
|
||||||
|
mpi.fromBigInteger(bn);
|
||||||
|
return mpi;
|
||||||
|
});
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -133,13 +133,15 @@ function RSA() {
|
||||||
|
|
||||||
// Generate a new random private key B bits long, using public expt E
|
// Generate a new random private key B bits long, using public expt E
|
||||||
|
|
||||||
function generate(B, E) {
|
function generate(B, E, callback) {
|
||||||
|
|
||||||
//
|
//
|
||||||
// Web Crypto RSA keygen proposal example
|
// Native RSA keygen using Web Crypto
|
||||||
//
|
//
|
||||||
|
|
||||||
if (typeof window !== 'undefined' && window.crypto && window.crypto.subtle) {
|
if (false && typeof window !== 'undefined' && window.crypto && (window.crypto.subtle || window.crypto.webkitSubtle)) {
|
||||||
|
var subtle = window.crypto.subtle || window.crypto.webkitSubtle;
|
||||||
|
|
||||||
var keyGenOpt = {
|
var keyGenOpt = {
|
||||||
name: 'RSASSA-PKCS1-v1_5',
|
name: 'RSASSA-PKCS1-v1_5',
|
||||||
modulusLength: B, // the specified keysize in bits
|
modulusLength: B, // the specified keysize in bits
|
||||||
|
@ -151,52 +153,34 @@ function RSA() {
|
||||||
|
|
||||||
var extractable = true; // make generated key extractable
|
var extractable = true; // make generated key extractable
|
||||||
|
|
||||||
window.crypto.subtle.generateKey(keyGenOpt, extractable, ['sign', 'verify'])
|
subtle.generateKey(keyGenOpt, extractable, ['sign', 'verify'])
|
||||||
.then(onGenerated)
|
.then(onGenerated, callback)
|
||||||
.then(onExported);
|
.then(onExported, callback);
|
||||||
|
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
function onGenerated(key) {
|
function onGenerated(key) {
|
||||||
// export the generated keys as JsonWebKey (JWK)
|
// export the generated keys as JsonWebKey (JWK)
|
||||||
// https://tools.ietf.org/html/draft-ietf-jose-json-web-key-33
|
// https://tools.ietf.org/html/draft-ietf-jose-json-web-key-33
|
||||||
var p1 = window.crypto.subtle.exportKey('jwk', key.privateKey);
|
return subtle.exportKey('jwk', key.privateKey);
|
||||||
var p2 = window.crypto.subtle.exportKey('jwk', key.publicKey);
|
|
||||||
|
|
||||||
return window.Promise.all([p1, p2]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function onExported(exported) {
|
function onExported(jwk) {
|
||||||
// Exported JWK has the following encoded parameters: n, p, q, qi, ...
|
|
||||||
|
|
||||||
var privKey = exported[0];
|
|
||||||
var pubKey = exported[1];
|
|
||||||
|
|
||||||
console.log('Exported private key: ', privKey);
|
|
||||||
console.log('Exported public key: ', pubKey);
|
|
||||||
|
|
||||||
var d = privKey.d;
|
|
||||||
var dp = privKey.dp;
|
|
||||||
var dq = privKey.dq;
|
|
||||||
var e = privKey.e;
|
|
||||||
var n = privKey.n;
|
|
||||||
var p = privKey.p;
|
|
||||||
var q = privKey.q;
|
|
||||||
var qi = privKey.qi;
|
|
||||||
|
|
||||||
// map JWK parameters to local BigInteger type system
|
// map JWK parameters to local BigInteger type system
|
||||||
var key = new keyObject();
|
var key = new keyObject();
|
||||||
key.n = new BigInteger(util.hexstrdump(base64(n)), 16);
|
key.n = new BigInteger(util.hexstrdump(base64(jwk.n)), 16);
|
||||||
key.ee = new BigInteger(E, 16);
|
key.ee = new BigInteger(E, 16);
|
||||||
key.d = new BigInteger(util.hexstrdump(base64(d)), 16);
|
key.d = new BigInteger(util.hexstrdump(base64(jwk.d)), 16);
|
||||||
key.p = new BigInteger(util.hexstrdump(base64(p)), 16);
|
key.p = new BigInteger(util.hexstrdump(base64(jwk.p)), 16);
|
||||||
key.q = new BigInteger(util.hexstrdump(base64(q)), 16);
|
key.q = new BigInteger(util.hexstrdump(base64(jwk.q)), 16);
|
||||||
key.u = key.p.modInverse(key.q);
|
key.u = key.p.modInverse(key.q);
|
||||||
|
|
||||||
function base64(base64url) {
|
function base64(base64url) {
|
||||||
return base64url.replace(/-/g, '+').replace(/_/g, '/')
|
return base64url.replace(/-/g, '+').replace(/_/g, '/');
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: add async style callback
|
callback(null, key);
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -236,7 +220,8 @@ function RSA() {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return key;
|
|
||||||
|
callback(null, key);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.encrypt = encrypt;
|
this.encrypt = encrypt;
|
||||||
|
|
194
src/key.js
194
src/key.js
|
@ -1,6 +1,6 @@
|
||||||
// GPG4Browsers - An OpenPGP implementation in javascript
|
// GPG4Browsers - An OpenPGP implementation in javascript
|
||||||
// Copyright (C) 2011 Recurity Labs GmbH
|
// Copyright (C) 2011 Recurity Labs GmbH
|
||||||
//
|
//
|
||||||
// This library is free software; you can redistribute it and/or
|
// This library is free software; you can redistribute it and/or
|
||||||
// modify it under the terms of the GNU Lesser General Public
|
// modify it under the terms of the GNU Lesser General Public
|
||||||
// License as published by the Free Software Foundation; either
|
// License as published by the Free Software Foundation; either
|
||||||
|
@ -10,7 +10,7 @@
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
// Lesser General Public License for more details.
|
// Lesser General Public License for more details.
|
||||||
//
|
//
|
||||||
// You should have received a copy of the GNU Lesser General Public
|
// You should have received a copy of the GNU Lesser General Public
|
||||||
// License along with this library; if not, write to the Free Software
|
// License along with this library; if not, write to the Free Software
|
||||||
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
@ -148,14 +148,14 @@ Key.prototype.toPacketlist = function() {
|
||||||
if (this.subKeys) {
|
if (this.subKeys) {
|
||||||
for (i = 0; i < this.subKeys.length; i++) {
|
for (i = 0; i < this.subKeys.length; i++) {
|
||||||
packetlist.concat(this.subKeys[i].toPacketlist());
|
packetlist.concat(this.subKeys[i].toPacketlist());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return packetlist;
|
return packetlist;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns all the private and public subkey packets
|
* Returns all the private and public subkey packets
|
||||||
* @returns {Array<(module:packet/public_subkey|module:packet/secret_subkey)>}
|
* @returns {Array<(module:packet/public_subkey|module:packet/secret_subkey)>}
|
||||||
*/
|
*/
|
||||||
Key.prototype.getSubkeyPackets = function() {
|
Key.prototype.getSubkeyPackets = function() {
|
||||||
var subKeys = [];
|
var subKeys = [];
|
||||||
|
@ -167,17 +167,17 @@ Key.prototype.getSubkeyPackets = function() {
|
||||||
return subKeys;
|
return subKeys;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns all the private and public key and subkey packets
|
* Returns all the private and public key and subkey packets
|
||||||
* @returns {Array<(module:packet/public_subkey|module:packet/secret_subkey|module:packet/secret_key|module:packet/public_key)>}
|
* @returns {Array<(module:packet/public_subkey|module:packet/secret_subkey|module:packet/secret_key|module:packet/public_key)>}
|
||||||
*/
|
*/
|
||||||
Key.prototype.getAllKeyPackets = function() {
|
Key.prototype.getAllKeyPackets = function() {
|
||||||
return [this.primaryKey].concat(this.getSubkeyPackets());
|
return [this.primaryKey].concat(this.getSubkeyPackets());
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns key IDs of all key packets
|
* Returns key IDs of all key packets
|
||||||
* @returns {Array<module:type/keyid>}
|
* @returns {Array<module:type/keyid>}
|
||||||
*/
|
*/
|
||||||
Key.prototype.getKeyIds = function() {
|
Key.prototype.getKeyIds = function() {
|
||||||
var keyIds = [];
|
var keyIds = [];
|
||||||
|
@ -197,7 +197,7 @@ Key.prototype.getKeyIds = function() {
|
||||||
Key.prototype.getKeyPacket = function(keyIds) {
|
Key.prototype.getKeyPacket = function(keyIds) {
|
||||||
var keys = this.getAllKeyPackets();
|
var keys = this.getAllKeyPackets();
|
||||||
for (var i = 0; i < keys.length; i++) {
|
for (var i = 0; i < keys.length; i++) {
|
||||||
var keyId = keys[i].getKeyId();
|
var keyId = keys[i].getKeyId();
|
||||||
for (var j = 0; j < keyIds.length; j++) {
|
for (var j = 0; j < keyIds.length; j++) {
|
||||||
if (keyId.equals(keyIds[j])) {
|
if (keyId.equals(keyIds[j])) {
|
||||||
return keys[i];
|
return keys[i];
|
||||||
|
@ -284,7 +284,7 @@ Key.prototype.getSigningKeyPacket = function() {
|
||||||
throw new Error('Need private key for signing');
|
throw new Error('Need private key for signing');
|
||||||
}
|
}
|
||||||
var primaryUser = this.getPrimaryUser();
|
var primaryUser = this.getPrimaryUser();
|
||||||
if (primaryUser &&
|
if (primaryUser &&
|
||||||
isValidSigningKeyPacket(this.primaryKey, primaryUser.selfCertificate)) {
|
isValidSigningKeyPacket(this.primaryKey, primaryUser.selfCertificate)) {
|
||||||
return this.primaryKey;
|
return this.primaryKey;
|
||||||
}
|
}
|
||||||
|
@ -342,7 +342,7 @@ Key.prototype.getEncryptionKeyPacket = function() {
|
||||||
}
|
}
|
||||||
// if no valid subkey for encryption, evaluate primary key
|
// if no valid subkey for encryption, evaluate primary key
|
||||||
var primaryUser = this.getPrimaryUser();
|
var primaryUser = this.getPrimaryUser();
|
||||||
if (primaryUser &&
|
if (primaryUser &&
|
||||||
isValidEncryptionKeyPacket(this.primaryKey, primaryUser.selfCertificate)) {
|
isValidEncryptionKeyPacket(this.primaryKey, primaryUser.selfCertificate)) {
|
||||||
return this.primaryKey;
|
return this.primaryKey;
|
||||||
}
|
}
|
||||||
|
@ -351,7 +351,7 @@ Key.prototype.getEncryptionKeyPacket = function() {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Decrypts all secret key and subkey packets
|
* Decrypts all secret key and subkey packets
|
||||||
* @param {String} passphrase
|
* @param {String} passphrase
|
||||||
* @return {Boolean} true if all key and subkey packets decrypted successfully
|
* @return {Boolean} true if all key and subkey packets decrypted successfully
|
||||||
*/
|
*/
|
||||||
Key.prototype.decrypt = function(passphrase) {
|
Key.prototype.decrypt = function(passphrase) {
|
||||||
|
@ -370,14 +370,14 @@ Key.prototype.decrypt = function(passphrase) {
|
||||||
/**
|
/**
|
||||||
* Decrypts specific key packets by key ID
|
* Decrypts specific key packets by key ID
|
||||||
* @param {Array<module:type/keyid>} keyIds
|
* @param {Array<module:type/keyid>} keyIds
|
||||||
* @param {String} passphrase
|
* @param {String} passphrase
|
||||||
* @return {Boolean} true if all key packets decrypted successfully
|
* @return {Boolean} true if all key packets decrypted successfully
|
||||||
*/
|
*/
|
||||||
Key.prototype.decryptKeyPacket = function(keyIds, passphrase) {
|
Key.prototype.decryptKeyPacket = function(keyIds, passphrase) {
|
||||||
if (this.isPrivate()) {
|
if (this.isPrivate()) {
|
||||||
var keys = this.getAllKeyPackets();
|
var keys = this.getAllKeyPackets();
|
||||||
for (var i = 0; i < keys.length; i++) {
|
for (var i = 0; i < keys.length; i++) {
|
||||||
var keyId = keys[i].getKeyId();
|
var keyId = keys[i].getKeyId();
|
||||||
for (var j = 0; j < keyIds.length; j++) {
|
for (var j = 0; j < keyIds.length; j++) {
|
||||||
if (keyId.equals(keyIds[j])) {
|
if (keyId.equals(keyIds[j])) {
|
||||||
var success = keys[i].decrypt(passphrase);
|
var success = keys[i].decrypt(passphrase);
|
||||||
|
@ -398,8 +398,8 @@ Key.prototype.decryptKeyPacket = function(keyIds, passphrase) {
|
||||||
*/
|
*/
|
||||||
Key.prototype.verifyPrimaryKey = function() {
|
Key.prototype.verifyPrimaryKey = function() {
|
||||||
// check revocation signature
|
// check revocation signature
|
||||||
if (this.revocationSignature && !this.revocationSignature.isExpired() &&
|
if (this.revocationSignature && !this.revocationSignature.isExpired() &&
|
||||||
(this.revocationSignature.verified ||
|
(this.revocationSignature.verified ||
|
||||||
this.revocationSignature.verify(this.primaryKey, {key: this.primaryKey}))) {
|
this.revocationSignature.verify(this.primaryKey, {key: this.primaryKey}))) {
|
||||||
return enums.keyStatus.revoked;
|
return enums.keyStatus.revoked;
|
||||||
}
|
}
|
||||||
|
@ -641,8 +641,8 @@ User.prototype.isRevoked = function(certificate, primaryKey) {
|
||||||
var that = this;
|
var that = this;
|
||||||
return this.revocationCertifications.some(function(revCert) {
|
return this.revocationCertifications.some(function(revCert) {
|
||||||
return revCert.issuerKeyId.equals(certificate.issuerKeyId) &&
|
return revCert.issuerKeyId.equals(certificate.issuerKeyId) &&
|
||||||
!revCert.isExpired() &&
|
!revCert.isExpired() &&
|
||||||
(revCert.verified ||
|
(revCert.verified ||
|
||||||
revCert.verify(primaryKey, {userid: that.userId || that.userAttribute, key: primaryKey}));
|
revCert.verify(primaryKey, {userid: that.userId || that.userAttribute, key: primaryKey}));
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
|
@ -695,7 +695,7 @@ User.prototype.isValidSelfCertificate = function(primaryKey, selfCertificate) {
|
||||||
* Verify User. Checks for existence of self signatures, revocation signatures
|
* Verify User. Checks for existence of self signatures, revocation signatures
|
||||||
* and validity of self signature
|
* and validity of self signature
|
||||||
* @param {module:packet/secret_key|module:packet/public_key} primaryKey The primary key packet
|
* @param {module:packet/secret_key|module:packet/public_key} primaryKey The primary key packet
|
||||||
* @return {module:enums.keyStatus} status of user
|
* @return {module:enums.keyStatus} status of user
|
||||||
*/
|
*/
|
||||||
User.prototype.verify = function(primaryKey) {
|
User.prototype.verify = function(primaryKey) {
|
||||||
if (!this.selfCertifications) {
|
if (!this.selfCertifications) {
|
||||||
|
@ -707,7 +707,7 @@ User.prototype.verify = function(primaryKey) {
|
||||||
status = enums.keyStatus.revoked;
|
status = enums.keyStatus.revoked;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (!(this.selfCertifications[i].verified ||
|
if (!(this.selfCertifications[i].verified ||
|
||||||
this.selfCertifications[i].verify(primaryKey, {userid: this.userId || this.userAttribute, key: primaryKey}))) {
|
this.selfCertifications[i].verify(primaryKey, {userid: this.userId || this.userAttribute, key: primaryKey}))) {
|
||||||
status = enums.keyStatus.invalid;
|
status = enums.keyStatus.invalid;
|
||||||
continue;
|
continue;
|
||||||
|
@ -792,8 +792,8 @@ SubKey.prototype.isValidSigningKey = function(primaryKey) {
|
||||||
*/
|
*/
|
||||||
SubKey.prototype.verify = function(primaryKey) {
|
SubKey.prototype.verify = function(primaryKey) {
|
||||||
// check subkey revocation signature
|
// check subkey revocation signature
|
||||||
if (this.revocationSignature && !this.revocationSignature.isExpired() &&
|
if (this.revocationSignature && !this.revocationSignature.isExpired() &&
|
||||||
(this.revocationSignature.verified ||
|
(this.revocationSignature.verified ||
|
||||||
this.revocationSignature.verify(primaryKey, {key:primaryKey, bind: this.subKey}))) {
|
this.revocationSignature.verify(primaryKey, {key:primaryKey, bind: this.subKey}))) {
|
||||||
return enums.keyStatus.revoked;
|
return enums.keyStatus.revoked;
|
||||||
}
|
}
|
||||||
|
@ -888,12 +888,12 @@ function readArmored(armoredText) {
|
||||||
result.keys.push(newKey);
|
result.keys.push(newKey);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
result.err = result.err || [];
|
result.err = result.err || [];
|
||||||
result.err.push(e);
|
result.err.push(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
result.err = result.err || [];
|
result.err = result.err || [];
|
||||||
result.err.push(e);
|
result.err.push(e);
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -910,7 +910,9 @@ function readArmored(armoredText) {
|
||||||
* @return {module:key~Key}
|
* @return {module:key~Key}
|
||||||
* @static
|
* @static
|
||||||
*/
|
*/
|
||||||
function generate(options) {
|
function generate(options, callback) {
|
||||||
|
var packetlist, secretKeyPacket, userIdPacket, dataToSign, signaturePacket, secretSubkeyPacket, subkeySignaturePacket;
|
||||||
|
|
||||||
options.keyType = options.keyType || enums.publicKey.rsa_encrypt_sign;
|
options.keyType = options.keyType || enums.publicKey.rsa_encrypt_sign;
|
||||||
// RSA Encrypt-Only and RSA Sign-Only are deprecated and SHOULD NOT be generated
|
// RSA Encrypt-Only and RSA Sign-Only are deprecated and SHOULD NOT be generated
|
||||||
if (options.keyType !== enums.publicKey.rsa_encrypt_sign) {
|
if (options.keyType !== enums.publicKey.rsa_encrypt_sign) {
|
||||||
|
@ -921,74 +923,90 @@ function generate(options) {
|
||||||
options.unlocked = true;
|
options.unlocked = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
var packetlist = new packet.List();
|
packetlist = new packet.List();
|
||||||
|
|
||||||
var secretKeyPacket = new packet.SecretKey();
|
secretKeyPacket = new packet.SecretKey();
|
||||||
secretKeyPacket.algorithm = enums.read(enums.publicKey, options.keyType);
|
secretKeyPacket.algorithm = enums.read(enums.publicKey, options.keyType);
|
||||||
secretKeyPacket.generate(options.numBits);
|
secretKeyPacket.generate(options.numBits, onSecretKeyGenerated);
|
||||||
if (options.passphrase) {
|
|
||||||
secretKeyPacket.encrypt(options.passphrase);
|
function onSecretKeyGenerated(err) {
|
||||||
|
if (err) {
|
||||||
|
callback(err);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (options.passphrase) {
|
||||||
|
secretKeyPacket.encrypt(options.passphrase);
|
||||||
|
}
|
||||||
|
|
||||||
|
userIdPacket = new packet.Userid();
|
||||||
|
userIdPacket.read(options.userId);
|
||||||
|
|
||||||
|
dataToSign = {};
|
||||||
|
dataToSign.userid = userIdPacket;
|
||||||
|
dataToSign.key = secretKeyPacket;
|
||||||
|
signaturePacket = new packet.Signature();
|
||||||
|
signaturePacket.signatureType = enums.signature.cert_generic;
|
||||||
|
signaturePacket.publicKeyAlgorithm = options.keyType;
|
||||||
|
signaturePacket.hashAlgorithm = config.prefer_hash_algorithm;
|
||||||
|
signaturePacket.keyFlags = [enums.keyFlags.certify_keys | enums.keyFlags.sign_data];
|
||||||
|
signaturePacket.preferredSymmetricAlgorithms = [];
|
||||||
|
signaturePacket.preferredSymmetricAlgorithms.push(enums.symmetric.aes256);
|
||||||
|
signaturePacket.preferredSymmetricAlgorithms.push(enums.symmetric.aes192);
|
||||||
|
signaturePacket.preferredSymmetricAlgorithms.push(enums.symmetric.aes128);
|
||||||
|
signaturePacket.preferredSymmetricAlgorithms.push(enums.symmetric.cast5);
|
||||||
|
signaturePacket.preferredSymmetricAlgorithms.push(enums.symmetric.tripledes);
|
||||||
|
signaturePacket.preferredHashAlgorithms = [];
|
||||||
|
signaturePacket.preferredHashAlgorithms.push(enums.hash.sha256);
|
||||||
|
signaturePacket.preferredHashAlgorithms.push(enums.hash.sha1);
|
||||||
|
signaturePacket.preferredHashAlgorithms.push(enums.hash.sha512);
|
||||||
|
signaturePacket.preferredCompressionAlgorithms = [];
|
||||||
|
signaturePacket.preferredCompressionAlgorithms.push(enums.compression.zlib);
|
||||||
|
signaturePacket.preferredCompressionAlgorithms.push(enums.compression.zip);
|
||||||
|
if (config.integrity_protect) {
|
||||||
|
signaturePacket.features = [];
|
||||||
|
signaturePacket.features.push(1); // Modification Detection
|
||||||
|
}
|
||||||
|
signaturePacket.sign(secretKeyPacket, dataToSign);
|
||||||
|
|
||||||
|
secretSubkeyPacket = new packet.SecretSubkey();
|
||||||
|
secretSubkeyPacket.algorithm = enums.read(enums.publicKey, options.keyType);
|
||||||
|
secretSubkeyPacket.generate(options.numBits, onSecretSubkeyGenerated);
|
||||||
}
|
}
|
||||||
|
|
||||||
var userIdPacket = new packet.Userid();
|
function onSecretSubkeyGenerated(err) {
|
||||||
userIdPacket.read(options.userId);
|
if (err) {
|
||||||
|
callback(err);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
var dataToSign = {};
|
if (options.passphrase) {
|
||||||
dataToSign.userid = userIdPacket;
|
secretSubkeyPacket.encrypt(options.passphrase);
|
||||||
dataToSign.key = secretKeyPacket;
|
}
|
||||||
var signaturePacket = new packet.Signature();
|
|
||||||
signaturePacket.signatureType = enums.signature.cert_generic;
|
dataToSign = {};
|
||||||
signaturePacket.publicKeyAlgorithm = options.keyType;
|
dataToSign.key = secretKeyPacket;
|
||||||
signaturePacket.hashAlgorithm = config.prefer_hash_algorithm;
|
dataToSign.bind = secretSubkeyPacket;
|
||||||
signaturePacket.keyFlags = [enums.keyFlags.certify_keys | enums.keyFlags.sign_data];
|
subkeySignaturePacket = new packet.Signature();
|
||||||
signaturePacket.preferredSymmetricAlgorithms = [];
|
subkeySignaturePacket.signatureType = enums.signature.subkey_binding;
|
||||||
signaturePacket.preferredSymmetricAlgorithms.push(enums.symmetric.aes256);
|
subkeySignaturePacket.publicKeyAlgorithm = options.keyType;
|
||||||
signaturePacket.preferredSymmetricAlgorithms.push(enums.symmetric.aes192);
|
subkeySignaturePacket.hashAlgorithm = config.prefer_hash_algorithm;
|
||||||
signaturePacket.preferredSymmetricAlgorithms.push(enums.symmetric.aes128);
|
subkeySignaturePacket.keyFlags = [enums.keyFlags.encrypt_communication | enums.keyFlags.encrypt_storage];
|
||||||
signaturePacket.preferredSymmetricAlgorithms.push(enums.symmetric.cast5);
|
subkeySignaturePacket.sign(secretKeyPacket, dataToSign);
|
||||||
signaturePacket.preferredSymmetricAlgorithms.push(enums.symmetric.tripledes);
|
|
||||||
signaturePacket.preferredHashAlgorithms = [];
|
packetlist.push(secretKeyPacket);
|
||||||
signaturePacket.preferredHashAlgorithms.push(enums.hash.sha256);
|
packetlist.push(userIdPacket);
|
||||||
signaturePacket.preferredHashAlgorithms.push(enums.hash.sha1);
|
packetlist.push(signaturePacket);
|
||||||
signaturePacket.preferredHashAlgorithms.push(enums.hash.sha512);
|
packetlist.push(secretSubkeyPacket);
|
||||||
signaturePacket.preferredCompressionAlgorithms = [];
|
packetlist.push(subkeySignaturePacket);
|
||||||
signaturePacket.preferredCompressionAlgorithms.push(enums.compression.zlib);
|
|
||||||
signaturePacket.preferredCompressionAlgorithms.push(enums.compression.zip);
|
if (!options.unlocked) {
|
||||||
if (config.integrity_protect) {
|
secretKeyPacket.clearPrivateMPIs();
|
||||||
signaturePacket.features = [];
|
secretSubkeyPacket.clearPrivateMPIs();
|
||||||
signaturePacket.features.push(1); // Modification Detection
|
}
|
||||||
|
|
||||||
|
callback(null, new Key(packetlist));
|
||||||
}
|
}
|
||||||
signaturePacket.sign(secretKeyPacket, dataToSign);
|
|
||||||
|
|
||||||
var secretSubkeyPacket = new packet.SecretSubkey();
|
|
||||||
secretSubkeyPacket.algorithm = enums.read(enums.publicKey, options.keyType);
|
|
||||||
secretSubkeyPacket.generate(options.numBits);
|
|
||||||
if (options.passphrase) {
|
|
||||||
secretSubkeyPacket.encrypt(options.passphrase);
|
|
||||||
}
|
|
||||||
|
|
||||||
dataToSign = {};
|
|
||||||
dataToSign.key = secretKeyPacket;
|
|
||||||
dataToSign.bind = secretSubkeyPacket;
|
|
||||||
var subkeySignaturePacket = new packet.Signature();
|
|
||||||
subkeySignaturePacket.signatureType = enums.signature.subkey_binding;
|
|
||||||
subkeySignaturePacket.publicKeyAlgorithm = options.keyType;
|
|
||||||
subkeySignaturePacket.hashAlgorithm = config.prefer_hash_algorithm;
|
|
||||||
subkeySignaturePacket.keyFlags = [enums.keyFlags.encrypt_communication | enums.keyFlags.encrypt_storage];
|
|
||||||
subkeySignaturePacket.sign(secretKeyPacket, dataToSign);
|
|
||||||
|
|
||||||
packetlist.push(secretKeyPacket);
|
|
||||||
packetlist.push(userIdPacket);
|
|
||||||
packetlist.push(signaturePacket);
|
|
||||||
packetlist.push(secretSubkeyPacket);
|
|
||||||
packetlist.push(subkeySignaturePacket);
|
|
||||||
|
|
||||||
if (!options.unlocked) {
|
|
||||||
secretKeyPacket.clearPrivateMPIs();
|
|
||||||
secretSubkeyPacket.clearPrivateMPIs();
|
|
||||||
}
|
|
||||||
|
|
||||||
return new Key(packetlist);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -224,24 +224,28 @@ function verifyClearSignedMessage(publicKeys, msg, callback) {
|
||||||
* @param {String} options.userId assumes already in form of "User Name <username@email.com>"
|
* @param {String} options.userId assumes already in form of "User Name <username@email.com>"
|
||||||
* @param {String} options.passphrase The passphrase used to encrypt the resulting private key
|
* @param {String} options.passphrase The passphrase used to encrypt the resulting private key
|
||||||
* @param {Boolean} [options.unlocked=false] The secret part of the generated key is unlocked
|
* @param {Boolean} [options.unlocked=false] The secret part of the generated key is unlocked
|
||||||
* @param {function} callback (optional) callback(error, result) for async style
|
* @param {function} callback(error, result) The required callback
|
||||||
* @return {Object} {key: module:key~Key, privateKeyArmored: String, publicKeyArmored: String}
|
* @return {Object} {key: module:key~Key, privateKeyArmored: String, publicKeyArmored: String}
|
||||||
* @static
|
* @static
|
||||||
*/
|
*/
|
||||||
function generateKeyPair(options, callback) {
|
function generateKeyPair(options, callback) {
|
||||||
if (useWorker(callback)) {
|
if (!callback) {
|
||||||
|
throw new Error('Callback must be set for key generation!');
|
||||||
|
}
|
||||||
|
|
||||||
|
// use web worker if web crypto apis are not supported
|
||||||
|
if (!useWebCrypto() && useWorker(callback)) {
|
||||||
asyncProxy.generateKeyPair(options, callback);
|
asyncProxy.generateKeyPair(options, callback);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
return execute(function() {
|
key.generate(options, function(err, newKey) {
|
||||||
var result = {};
|
var result = {};
|
||||||
var newKey = key.generate(options);
|
|
||||||
result.key = newKey;
|
result.key = newKey;
|
||||||
result.privateKeyArmored = newKey.armor();
|
result.privateKeyArmored = newKey.armor();
|
||||||
result.publicKeyArmored = newKey.toPublic().armor();
|
result.publicKeyArmored = newKey.toPublic().armor();
|
||||||
return result;
|
callback(null, result);
|
||||||
}, callback);
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -257,12 +261,20 @@ function useWorker(callback) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!asyncProxy) {
|
if (!asyncProxy) {
|
||||||
throw new Error('You need to set the worker path!');
|
console.log('You need to set the worker path!');
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check for WebCrypto support
|
||||||
|
*/
|
||||||
|
function useWebCrypto() {
|
||||||
|
return typeof window !== 'undefined' && window.crypto && (window.crypto.subtle || window.crypto.webkitSubtle);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Command pattern that handles async calls gracefully
|
* Command pattern that handles async calls gracefully
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
// GPG4Browsers - An OpenPGP implementation in javascript
|
// GPG4Browsers - An OpenPGP implementation in javascript
|
||||||
// Copyright (C) 2011 Recurity Labs GmbH
|
// Copyright (C) 2011 Recurity Labs GmbH
|
||||||
//
|
//
|
||||||
// This library is free software; you can redistribute it and/or
|
// This library is free software; you can redistribute it and/or
|
||||||
// modify it under the terms of the GNU Lesser General Public
|
// modify it under the terms of the GNU Lesser General Public
|
||||||
// License as published by the Free Software Foundation; either
|
// License as published by the Free Software Foundation; either
|
||||||
|
@ -10,7 +10,7 @@
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
// Lesser General Public License for more details.
|
// Lesser General Public License for more details.
|
||||||
//
|
//
|
||||||
// You should have received a copy of the GNU Lesser General Public
|
// You should have received a copy of the GNU Lesser General Public
|
||||||
// License along with this library; if not, write to the Free Software
|
// License along with this library; if not, write to the Free Software
|
||||||
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
@ -270,9 +270,19 @@ SecretKey.prototype.decrypt = function (passphrase) {
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
|
||||||
SecretKey.prototype.generate = function (bits) {
|
SecretKey.prototype.generate = function (bits, callback) {
|
||||||
this.mpi = crypto.generateMpi(this.algorithm, bits);
|
var self = this;
|
||||||
this.isDecrypted = true;
|
|
||||||
|
crypto.generateMpi(self.algorithm, bits, function(err, mpi) {
|
||||||
|
if (err) {
|
||||||
|
callback(err);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
self.mpi = mpi;
|
||||||
|
self.isDecrypted = true;
|
||||||
|
callback();
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
// GPG4Browsers - An OpenPGP implementation in javascript
|
// GPG4Browsers - An OpenPGP implementation in javascript
|
||||||
// Copyright (C) 2011 Recurity Labs GmbH
|
// Copyright (C) 2011 Recurity Labs GmbH
|
||||||
//
|
//
|
||||||
// This library is free software; you can redistribute it and/or
|
// This library is free software; you can redistribute it and/or
|
||||||
// modify it under the terms of the GNU Lesser General Public
|
// modify it under the terms of the GNU Lesser General Public
|
||||||
// License as published by the Free Software Foundation; either
|
// License as published by the Free Software Foundation; either
|
||||||
|
@ -10,7 +10,7 @@
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
// Lesser General Public License for more details.
|
// Lesser General Public License for more details.
|
||||||
//
|
//
|
||||||
// You should have received a copy of the GNU Lesser General Public
|
// You should have received a copy of the GNU Lesser General Public
|
||||||
// License along with this library; if not, write to the Free Software
|
// License along with this library; if not, write to the Free Software
|
||||||
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
@ -25,7 +25,7 @@ var MAX_SIZE_RANDOM_BUFFER = 60000;
|
||||||
window.openpgp.crypto.random.randomBuffer.init(MAX_SIZE_RANDOM_BUFFER);
|
window.openpgp.crypto.random.randomBuffer.init(MAX_SIZE_RANDOM_BUFFER);
|
||||||
|
|
||||||
onmessage = function (event) {
|
onmessage = function (event) {
|
||||||
var data = null,
|
var data = null,
|
||||||
err = null,
|
err = null,
|
||||||
msg = event.data,
|
msg = event.data,
|
||||||
correct = false;
|
correct = false;
|
||||||
|
@ -101,7 +101,7 @@ onmessage = function (event) {
|
||||||
}
|
}
|
||||||
msg.publicKeys = msg.publicKeys.map(packetlistCloneToKey);
|
msg.publicKeys = msg.publicKeys.map(packetlistCloneToKey);
|
||||||
var packetlist = window.openpgp.packet.List.fromStructuredClone(msg.message.packets);
|
var packetlist = window.openpgp.packet.List.fromStructuredClone(msg.message.packets);
|
||||||
msg.message = new window.openpgp.cleartext.CleartextMessage(msg.message.text, packetlist);
|
msg.message = new window.openpgp.cleartext.CleartextMessage(msg.message.text, packetlist);
|
||||||
data = window.openpgp.verifyClearSignedMessage(msg.publicKeys, msg.message);
|
data = window.openpgp.verifyClearSignedMessage(msg.publicKeys, msg.message);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
err = e.message;
|
err = e.message;
|
||||||
|
@ -110,12 +110,20 @@ onmessage = function (event) {
|
||||||
break;
|
break;
|
||||||
case 'generate-key-pair':
|
case 'generate-key-pair':
|
||||||
try {
|
try {
|
||||||
data = window.openpgp.generateKeyPair(msg.options);
|
window.openpgp.generateKeyPair(msg.options, function(error, data) {
|
||||||
data.key = data.key.toPacketlist();
|
if (error) {
|
||||||
|
err = error.message;
|
||||||
|
response({event: 'method-return', data: data, err: err});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
data.key = data.key.toPacketlist();
|
||||||
|
response({event: 'method-return', data: data, err: err});
|
||||||
|
});
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
err = e.message;
|
err = e.message;
|
||||||
|
response({event: 'method-return', data: data, err: err});
|
||||||
}
|
}
|
||||||
response({event: 'method-return', data: data, err: err});
|
|
||||||
break;
|
break;
|
||||||
case 'decrypt-key':
|
case 'decrypt-key':
|
||||||
try {
|
try {
|
||||||
|
|
|
@ -8,57 +8,61 @@ var chai = require('chai'),
|
||||||
describe('Basic', function() {
|
describe('Basic', function() {
|
||||||
|
|
||||||
describe("Key generation/encryption/decryption", function() {
|
describe("Key generation/encryption/decryption", function() {
|
||||||
var testHelper = function(passphrase, userid, message) {
|
var testHelper = function(passphrase, userid, message, done) {
|
||||||
var key = openpgp.generateKeyPair({numBits: 512, userId: userid, passphrase: passphrase});
|
var opt = {numBits: 512, userId: userid, passphrase: passphrase};
|
||||||
expect(key).to.exist;
|
openpgp.generateKeyPair(opt, function(err, key) {
|
||||||
expect(key.key).to.exist;
|
expect(err).to.not.exist;
|
||||||
expect(key.privateKeyArmored).to.exist;
|
|
||||||
expect(key.publicKeyArmored).to.exist;
|
|
||||||
|
|
||||||
var info = '\npassphrase: ' + passphrase + '\n' + 'userid: ' + userid + '\n' + 'message: ' + message;
|
expect(key).to.exist;
|
||||||
|
expect(key.key).to.exist;
|
||||||
|
expect(key.privateKeyArmored).to.exist;
|
||||||
|
expect(key.publicKeyArmored).to.exist;
|
||||||
|
|
||||||
var privKeys = openpgp.key.readArmored(key.privateKeyArmored);
|
var info = '\npassphrase: ' + passphrase + '\n' + 'userid: ' + userid + '\n' + 'message: ' + message;
|
||||||
var publicKeys = openpgp.key.readArmored(key.publicKeyArmored);
|
|
||||||
|
|
||||||
expect(privKeys).to.exist;
|
var privKeys = openpgp.key.readArmored(key.privateKeyArmored);
|
||||||
expect(privKeys.err).to.not.exist;
|
var publicKeys = openpgp.key.readArmored(key.publicKeyArmored);
|
||||||
expect(privKeys.keys).to.have.length(1);
|
|
||||||
|
|
||||||
var privKey = privKeys.keys[0];
|
expect(privKeys).to.exist;
|
||||||
var pubKey = publicKeys.keys[0];
|
expect(privKeys.err).to.not.exist;
|
||||||
|
expect(privKeys.keys).to.have.length(1);
|
||||||
|
|
||||||
expect(privKey).to.exist;
|
var privKey = privKeys.keys[0];
|
||||||
expect(pubKey).to.exist;
|
var pubKey = publicKeys.keys[0];
|
||||||
|
|
||||||
var success = privKey.decrypt(passphrase);
|
expect(privKey).to.exist;
|
||||||
|
expect(pubKey).to.exist;
|
||||||
|
|
||||||
expect(success).to.be.true;
|
var success = privKey.decrypt(passphrase);
|
||||||
|
|
||||||
var encrypted = openpgp.signAndEncryptMessage([pubKey], privKey, message);
|
expect(success).to.be.true;
|
||||||
|
|
||||||
expect(encrypted).to.exist;
|
var encrypted = openpgp.signAndEncryptMessage([pubKey], privKey, message);
|
||||||
|
|
||||||
var msg = openpgp.message.readArmored(encrypted);
|
expect(encrypted).to.exist;
|
||||||
|
|
||||||
expect(msg).to.exist;
|
var msg = openpgp.message.readArmored(encrypted);
|
||||||
|
|
||||||
var keyids = msg.getEncryptionKeyIds();
|
expect(msg).to.exist;
|
||||||
|
|
||||||
expect(keyids).to.exist;
|
var keyids = msg.getEncryptionKeyIds();
|
||||||
|
|
||||||
var decrypted = openpgp.decryptAndVerifyMessage(privKey, [pubKey], msg);
|
expect(keyids).to.exist;
|
||||||
expect(decrypted).to.exist;
|
|
||||||
expect(decrypted.signatures[0].valid).to.be.true;
|
var decrypted = openpgp.decryptAndVerifyMessage(privKey, [pubKey], msg);
|
||||||
expect(decrypted.text).to.equal(message);
|
expect(decrypted).to.exist;
|
||||||
|
expect(decrypted.signatures[0].valid).to.be.true;
|
||||||
|
expect(decrypted.text).to.equal(message);
|
||||||
|
|
||||||
|
done();
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
it('ASCII Text', function (done) {
|
it('ASCII Text', function (done) {
|
||||||
testHelper('password', 'Test McTestington <test@example.com>', 'hello world');
|
testHelper('password', 'Test McTestington <test@example.com>', 'hello world', done);
|
||||||
done();
|
|
||||||
});
|
});
|
||||||
it('Unicode Text', function (done) {
|
it('Unicode Text', function (done) {
|
||||||
testHelper('●●●●', '♔♔♔♔ <test@example.com>', 'łäóć');
|
testHelper('●●●●', '♔♔♔♔ <test@example.com>', 'łäóć', done);
|
||||||
done();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should fail to verify signature for wrong public key', function (done) {
|
it('should fail to verify signature for wrong public key', function (done) {
|
||||||
|
@ -66,29 +70,35 @@ describe('Basic', function() {
|
||||||
var passphrase = 'password';
|
var passphrase = 'password';
|
||||||
var message = 'hello world';
|
var message = 'hello world';
|
||||||
|
|
||||||
var key = openpgp.generateKeyPair({numBits: 512, userId: userid, passphrase: passphrase});
|
var opt = {numBits: 512, userId: userid, passphrase: passphrase};
|
||||||
|
openpgp.generateKeyPair(opt, function(err, key) {
|
||||||
|
expect(err).to.not.exist;
|
||||||
|
|
||||||
var privKeys = openpgp.key.readArmored(key.privateKeyArmored);
|
var privKeys = openpgp.key.readArmored(key.privateKeyArmored);
|
||||||
var publicKeys = openpgp.key.readArmored(key.publicKeyArmored);
|
var publicKeys = openpgp.key.readArmored(key.publicKeyArmored);
|
||||||
|
|
||||||
var privKey = privKeys.keys[0];
|
var privKey = privKeys.keys[0];
|
||||||
var pubKey = publicKeys.keys[0];
|
var pubKey = publicKeys.keys[0];
|
||||||
|
|
||||||
var success = privKey.decrypt(passphrase);
|
var success = privKey.decrypt(passphrase);
|
||||||
|
|
||||||
var encrypted = openpgp.signAndEncryptMessage([pubKey], privKey, message);
|
var encrypted = openpgp.signAndEncryptMessage([pubKey], privKey, message);
|
||||||
|
|
||||||
var msg = openpgp.message.readArmored(encrypted);
|
var msg = openpgp.message.readArmored(encrypted);
|
||||||
expect(msg).to.exist;
|
expect(msg).to.exist;
|
||||||
|
|
||||||
var anotherKey = openpgp.generateKeyPair({numBits: 512, userId: userid, passphrase: passphrase});
|
openpgp.generateKeyPair(opt, function(err, anotherKey) {
|
||||||
var anotherPubKey = openpgp.key.readArmored(anotherKey.publicKeyArmored).keys[0];
|
expect(err).to.not.exist;
|
||||||
|
|
||||||
var decrypted = openpgp.decryptAndVerifyMessage(privKey, [anotherPubKey], msg);
|
var anotherPubKey = openpgp.key.readArmored(anotherKey.publicKeyArmored).keys[0];
|
||||||
expect(decrypted).to.exist;
|
|
||||||
expect(decrypted.signatures[0].valid).to.be.null;
|
var decrypted = openpgp.decryptAndVerifyMessage(privKey, [anotherPubKey], msg);
|
||||||
expect(decrypted.text).to.equal(message);
|
expect(decrypted).to.exist;
|
||||||
done();
|
expect(decrypted.signatures[0].valid).to.be.null;
|
||||||
|
expect(decrypted.text).to.equal(message);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Performance test', function (done) {
|
it('Performance test', function (done) {
|
||||||
|
@ -103,46 +113,49 @@ describe('Basic', function() {
|
||||||
var userid = 'Test McTestington <test@example.com>';
|
var userid = 'Test McTestington <test@example.com>';
|
||||||
var passphrase = 'password';
|
var passphrase = 'password';
|
||||||
|
|
||||||
var key = openpgp.generateKeyPair({numBits: 512, userId: userid, passphrase: passphrase});
|
var opt = {numBits: 512, userId: userid, passphrase: passphrase};
|
||||||
|
openpgp.generateKeyPair(opt, function(err, key) {
|
||||||
|
expect(err).to.not.exist;
|
||||||
|
|
||||||
var info = '\npassphrase: ' + passphrase + '\n' + 'userid: ' + userid + '\n' + 'message: ' + message;
|
var info = '\npassphrase: ' + passphrase + '\n' + 'userid: ' + userid + '\n' + 'message: ' + message;
|
||||||
|
|
||||||
var privKeys = openpgp.key.readArmored(key.privateKeyArmored);
|
var privKeys = openpgp.key.readArmored(key.privateKeyArmored);
|
||||||
var publicKeys = openpgp.key.readArmored(key.publicKeyArmored);
|
var publicKeys = openpgp.key.readArmored(key.publicKeyArmored);
|
||||||
|
|
||||||
var privKey = privKeys.keys[0];
|
var privKey = privKeys.keys[0];
|
||||||
var pubKey = publicKeys.keys[0];
|
var pubKey = publicKeys.keys[0];
|
||||||
|
|
||||||
var success = privKey.decrypt(passphrase);
|
var success = privKey.decrypt(passphrase);
|
||||||
|
|
||||||
if (console.profile) {
|
if (console.profile) {
|
||||||
console.profile("encrypt/sign/verify/decrypt");
|
console.profile("encrypt/sign/verify/decrypt");
|
||||||
}
|
}
|
||||||
|
|
||||||
// sign and encrypt
|
// sign and encrypt
|
||||||
var msg, encrypted;
|
var msg, encrypted;
|
||||||
msg = openpgp.message.fromBinary(message);
|
msg = openpgp.message.fromBinary(message);
|
||||||
msg = msg.sign([privKey]);
|
msg = msg.sign([privKey]);
|
||||||
msg = msg.encrypt([pubKey]);
|
msg = msg.encrypt([pubKey]);
|
||||||
encrypted = openpgp.armor.encode(openpgp.enums.armor.message, msg.packets.write());
|
encrypted = openpgp.armor.encode(openpgp.enums.armor.message, msg.packets.write());
|
||||||
|
|
||||||
if (console.profileEnd) {
|
if (console.profileEnd) {
|
||||||
console.profileEnd();
|
console.profileEnd();
|
||||||
}
|
}
|
||||||
|
|
||||||
msg = openpgp.message.readArmored(encrypted);
|
msg = openpgp.message.readArmored(encrypted);
|
||||||
|
|
||||||
var keyids = msg.getEncryptionKeyIds();
|
var keyids = msg.getEncryptionKeyIds();
|
||||||
|
|
||||||
expect(keyids).to.exist;
|
expect(keyids).to.exist;
|
||||||
|
|
||||||
var decrypted = openpgp.decryptAndVerifyMessage(privKey, [pubKey], msg);
|
var decrypted = openpgp.decryptAndVerifyMessage(privKey, [pubKey], msg);
|
||||||
|
|
||||||
expect(decrypted).to.exist;
|
expect(decrypted).to.exist;
|
||||||
expect(decrypted.signatures[0].valid).to.be.true;
|
expect(decrypted.signatures[0].valid).to.be.true;
|
||||||
expect(decrypted.text).to.equal(message);
|
expect(decrypted.text).to.equal(message);
|
||||||
|
|
||||||
done();
|
done();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -137,7 +137,7 @@ describe('Key', function() {
|
||||||
'=eoGb',
|
'=eoGb',
|
||||||
'-----END PGP PUBLIC KEY BLOCK-----'].join('\n');
|
'-----END PGP PUBLIC KEY BLOCK-----'].join('\n');
|
||||||
|
|
||||||
var pub_sig_test =
|
var pub_sig_test =
|
||||||
['-----BEGIN PGP PUBLIC KEY BLOCK-----',
|
['-----BEGIN PGP PUBLIC KEY BLOCK-----',
|
||||||
'Version: GnuPG v2.0.19 (GNU/Linux)',
|
'Version: GnuPG v2.0.19 (GNU/Linux)',
|
||||||
'',
|
'',
|
||||||
|
@ -618,7 +618,7 @@ var pgp_desktop_priv =
|
||||||
expect(prefAlgo).to.equal(openpgp.config.encryption_cipher);
|
expect(prefAlgo).to.equal(openpgp.config.encryption_cipher);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Preferences of generated key', function() {
|
it('Preferences of generated key', function(done) {
|
||||||
var testPref = function(key) {
|
var testPref = function(key) {
|
||||||
// key flags
|
// key flags
|
||||||
var keyFlags = openpgp.enums.keyFlags;
|
var keyFlags = openpgp.enums.keyFlags;
|
||||||
|
@ -633,10 +633,14 @@ var pgp_desktop_priv =
|
||||||
var compr = openpgp.enums.compression;
|
var compr = openpgp.enums.compression;
|
||||||
expect(key.users[0].selfCertifications[0].preferredCompressionAlgorithms).to.eql([compr.zlib, compr.zip]);
|
expect(key.users[0].selfCertifications[0].preferredCompressionAlgorithms).to.eql([compr.zlib, compr.zip]);
|
||||||
expect(key.users[0].selfCertifications[0].features).to.eql(openpgp.config.integrity_protect ? [1] : null); // modification detection
|
expect(key.users[0].selfCertifications[0].features).to.eql(openpgp.config.integrity_protect ? [1] : null); // modification detection
|
||||||
}
|
};
|
||||||
var key = openpgp.generateKeyPair({numBits: 512, userId: 'test', passphrase: 'hello'});
|
var opt = {numBits: 512, userId: 'test', passphrase: 'hello'};
|
||||||
testPref(key.key);
|
openpgp.generateKeyPair(opt, function(err, key) {
|
||||||
testPref(openpgp.key.readArmored(key.publicKeyArmored).keys[0]);
|
expect(err).to.not.exist;
|
||||||
|
testPref(key.key);
|
||||||
|
testPref(openpgp.key.readArmored(key.publicKeyArmored).keys[0]);
|
||||||
|
done();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('User attribute packet read & write', function() {
|
it('User attribute packet read & write', function() {
|
||||||
|
@ -653,11 +657,15 @@ var pgp_desktop_priv =
|
||||||
expect(primUser.selfCertificate).to.be.an.instanceof(openpgp.packet.Signature);
|
expect(primUser.selfCertificate).to.be.an.instanceof(openpgp.packet.Signature);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Generated key is not unlocked by default', function() {
|
it('Generated key is not unlocked by default', function(done) {
|
||||||
var key = openpgp.generateKeyPair({numBits: 512, userId: 'test', passphrase: '123'});
|
var opt = {numBits: 512, userId: 'test', passphrase: '123'};
|
||||||
var msg = openpgp.message.fromText('hello').encrypt([key.key]);
|
openpgp.generateKeyPair(opt, function(err, key) {
|
||||||
msg = msg.decrypt.bind(msg, key.key);
|
expect(err).to.not.exist;
|
||||||
expect(msg).to.throw('Private key is not decrypted.');
|
var msg = openpgp.message.fromText('hello').encrypt([key.key]);
|
||||||
|
msg = msg.decrypt.bind(msg, key.key);
|
||||||
|
expect(msg).to.throw('Private key is not decrypted.');
|
||||||
|
done();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
|
@ -6,445 +6,452 @@ var chai = require('chai'),
|
||||||
expect = chai.expect;
|
expect = chai.expect;
|
||||||
|
|
||||||
describe("Packet", function() {
|
describe("Packet", function() {
|
||||||
var armored_key =
|
var armored_key =
|
||||||
'-----BEGIN PGP PRIVATE KEY BLOCK-----\n' +
|
'-----BEGIN PGP PRIVATE KEY BLOCK-----\n' +
|
||||||
'Version: GnuPG v2.0.19 (GNU/Linux)\n' +
|
'Version: GnuPG v2.0.19 (GNU/Linux)\n' +
|
||||||
'\n' +
|
'\n' +
|
||||||
'lQH+BFF79J8BBADDhRUOMUSGdYM1Kq9J/vVS3qLfaZHweycAKm9SnpLGLJE+Qbki\n' +
|
'lQH+BFF79J8BBADDhRUOMUSGdYM1Kq9J/vVS3qLfaZHweycAKm9SnpLGLJE+Qbki\n' +
|
||||||
'JRXLAhxZ+HgVThR9VXs8wbPR2UXnDhMJGe+VcMA0jiwIOEAF0y9M3ZQsPFWguej2\n' +
|
'JRXLAhxZ+HgVThR9VXs8wbPR2UXnDhMJGe+VcMA0jiwIOEAF0y9M3ZQsPFWguej2\n' +
|
||||||
'1ZycgOwxYHehbKdPqRK+nFgFbhvg6f6x2Gt+a0ZbvivGL1BqSSGsL+dchQARAQAB\n' +
|
'1ZycgOwxYHehbKdPqRK+nFgFbhvg6f6x2Gt+a0ZbvivGL1BqSSGsL+dchQARAQAB\n' +
|
||||||
'/gMDAijatUNeUFZSyfg16x343/1Jo6u07LVTdH6Bcbx4yBQjEHvlgb6m1eqEIbZ1\n' +
|
'/gMDAijatUNeUFZSyfg16x343/1Jo6u07LVTdH6Bcbx4yBQjEHvlgb6m1eqEIbZ1\n' +
|
||||||
'holVzt0fSKTzmlxltDaOwFLf7i42lqNoWyfaqFrOblJ5Ays7Q+6xiJTBROG9po+j\n' +
|
'holVzt0fSKTzmlxltDaOwFLf7i42lqNoWyfaqFrOblJ5Ays7Q+6xiJTBROG9po+j\n' +
|
||||||
'Z2AE+hkBIwKghB645OikchR4sn9Ej3ipea5v9+a7YimHlVmIiqgLDygQvXkzXVaf\n' +
|
'Z2AE+hkBIwKghB645OikchR4sn9Ej3ipea5v9+a7YimHlVmIiqgLDygQvXkzXVaf\n' +
|
||||||
'Zi1P2wB7eU6If2xeeX5GSR8rWo+I7ujns0W8S9PxBHlH3n1oXUmFWsWLZCY/qpkD\n' +
|
'Zi1P2wB7eU6If2xeeX5GSR8rWo+I7ujns0W8S9PxBHlH3n1oXUmFWsWLZCY/qpkD\n' +
|
||||||
'I/FroBhXxBVRpQhQmdsWPUdcgmQTEj8jnP++lwSQexfgk2QboAW7ODUA8Cl9oy87\n' +
|
'I/FroBhXxBVRpQhQmdsWPUdcgmQTEj8jnP++lwSQexfgk2QboAW7ODUA8Cl9oy87\n' +
|
||||||
'Uor5schwwdD3oRoLGcJZfR6Dyu9dCYdQSDWj+IQs95hJQfHNcfj7XFtTyOi7Kxx0\n' +
|
'Uor5schwwdD3oRoLGcJZfR6Dyu9dCYdQSDWj+IQs95hJQfHNcfj7XFtTyOi7Kxx0\n' +
|
||||||
'Jxio9De84QnxNAoNYuLtwkaRgkUVKVph2nYWJfAJunuMMosM2WdcidHJ5d6RIdxB\n' +
|
'Jxio9De84QnxNAoNYuLtwkaRgkUVKVph2nYWJfAJunuMMosM2WdcidHJ5d6RIdxB\n' +
|
||||||
'U6o3T+d8BPXuRQEZH9+FkDkb4ihakKO3+Zcon85e1ZUUtB1QYXRyaWNrIDxwYXRy\n' +
|
'U6o3T+d8BPXuRQEZH9+FkDkb4ihakKO3+Zcon85e1ZUUtB1QYXRyaWNrIDxwYXRy\n' +
|
||||||
'aWNrQGV4YW1wbGUuY29tPoi5BBMBAgAjBQJRe/SfAhsDBwsJCAcDAgEGFQgCCQoL\n' +
|
'aWNrQGV4YW1wbGUuY29tPoi5BBMBAgAjBQJRe/SfAhsDBwsJCAcDAgEGFQgCCQoL\n' +
|
||||||
'BBYCAwECHgECF4AACgkQObliSdM/GEJbjgP/ffei4lU6fXp8Qu0ubNHh4A6swkTO\n' +
|
'BBYCAwECHgECF4AACgkQObliSdM/GEJbjgP/ffei4lU6fXp8Qu0ubNHh4A6swkTO\n' +
|
||||||
'b3suuBELE4A2/pK5YnW5yByFFSi4kq8bJp5O6p9ydXpOA38t3aQ8wrbo0yDvGekr\n' +
|
'b3suuBELE4A2/pK5YnW5yByFFSi4kq8bJp5O6p9ydXpOA38t3aQ8wrbo0yDvGekr\n' +
|
||||||
'1S1HWOLgCaY7rEDQubuCOHd2R81/VQOJyG3zgX4KFIgkVyV9BZXUpz4PXuhMORmv\n' +
|
'1S1HWOLgCaY7rEDQubuCOHd2R81/VQOJyG3zgX4KFIgkVyV9BZXUpz4PXuhMORmv\n' +
|
||||||
'81uzej9r7BYkJ6GdAf4EUXv0nwEEAKbO02jtGEHet2fQfkAYyO+789sTxyfrUy5y\n' +
|
'81uzej9r7BYkJ6GdAf4EUXv0nwEEAKbO02jtGEHet2fQfkAYyO+789sTxyfrUy5y\n' +
|
||||||
'SAf5n3GgkuiHz8dFevhgqYyMK0OYEOCZqdd1lRBjL6Us7PxTljHc2jtGhoAgE4aZ\n' +
|
'SAf5n3GgkuiHz8dFevhgqYyMK0OYEOCZqdd1lRBjL6Us7PxTljHc2jtGhoAgE4aZ\n' +
|
||||||
'LKarI3j+5Oofcaq0+S0bhqiQ5hl6C4SkdYOEeJ0Hlq2008n0pJIlU4E5yIu0oNvb\n' +
|
'LKarI3j+5Oofcaq0+S0bhqiQ5hl6C4SkdYOEeJ0Hlq2008n0pJIlU4E5yIu0oNvb\n' +
|
||||||
'4+4owTpRABEBAAH+AwMCKNq1Q15QVlLJyeuGBEA+7nXS3aSy6mE4lR5f3Ml5NRqt\n' +
|
'4+4owTpRABEBAAH+AwMCKNq1Q15QVlLJyeuGBEA+7nXS3aSy6mE4lR5f3Ml5NRqt\n' +
|
||||||
'jm6Q+UUI69DzhLGX4jHRxna6NMP74S3CghOz9eChMndkfWLC/c11h1npzLci+AwJ\n' +
|
'jm6Q+UUI69DzhLGX4jHRxna6NMP74S3CghOz9eChMndkfWLC/c11h1npzLci+AwJ\n' +
|
||||||
'45xMbw/OW5PLlaxdtkg/SnsHpFGCAuTUWY87kuWoG0HSVMn9Clm+67rdicOW6L5a\n' +
|
'45xMbw/OW5PLlaxdtkg/SnsHpFGCAuTUWY87kuWoG0HSVMn9Clm+67rdicOW6L5a\n' +
|
||||||
'ChfyWcVZ+Hvwjx8YM0/j11If7oUkCZEstSUeJYOI10JQLhNLpDdkB89vXhAMaCuU\n' +
|
'ChfyWcVZ+Hvwjx8YM0/j11If7oUkCZEstSUeJYOI10JQLhNLpDdkB89vXhAMaCuU\n' +
|
||||||
'Ijhdq0vvJi6JruKQGPK+jajJ4MMannpQtKAvt8aifqpdovYy8w4yh2pGkadFvrsZ\n' +
|
'Ijhdq0vvJi6JruKQGPK+jajJ4MMannpQtKAvt8aifqpdovYy8w4yh2pGkadFvrsZ\n' +
|
||||||
'mxpjqmmawab6zlOW5WrLxQVL1cQRdrIQ7jYtuLApGWkPfytSCBZ20pSyWnmkxd4X\n' +
|
'mxpjqmmawab6zlOW5WrLxQVL1cQRdrIQ7jYtuLApGWkPfytSCBZ20pSyWnmkxd4X\n' +
|
||||||
'OIms6BjqrP9LxBEXsPBwdUA5Iranr+UBIPDxQrTp5k0DJhXBCpJ1k3ZT+2dxiRS2\n' +
|
'OIms6BjqrP9LxBEXsPBwdUA5Iranr+UBIPDxQrTp5k0DJhXBCpJ1k3ZT+2dxiRS2\n' +
|
||||||
'sk83w2VUBnXdYWZx0YlMqr3bDT6J5fO+8V8pbgY5BkHRCFMacFx45km/fvmInwQY\n' +
|
'sk83w2VUBnXdYWZx0YlMqr3bDT6J5fO+8V8pbgY5BkHRCFMacFx45km/fvmInwQY\n' +
|
||||||
'AQIACQUCUXv0nwIbDAAKCRA5uWJJ0z8YQqb3A/97njLl33OQYXVp9OTk/VgE6O+w\n' +
|
'AQIACQUCUXv0nwIbDAAKCRA5uWJJ0z8YQqb3A/97njLl33OQYXVp9OTk/VgE6O+w\n' +
|
||||||
'oSYa+6xMOzsk7tluLIRQtnIprga/e8vEZXGTomV2a77HBksg+YjlTh/l8oMuaoxG\n' +
|
'oSYa+6xMOzsk7tluLIRQtnIprga/e8vEZXGTomV2a77HBksg+YjlTh/l8oMuaoxG\n' +
|
||||||
'QNkMpoRJKPip29RTW4gLdnoJVekZ/awkBN2S3NMArOZGca8U+M1IuV7OyVchSVSl\n' +
|
'QNkMpoRJKPip29RTW4gLdnoJVekZ/awkBN2S3NMArOZGca8U+M1IuV7OyVchSVSl\n' +
|
||||||
'YRlci72GHhlyos8YHA==\n' +
|
'YRlci72GHhlyos8YHA==\n' +
|
||||||
'=KXkj\n' +
|
'=KXkj\n' +
|
||||||
'-----END PGP PRIVATE KEY BLOCK-----';
|
'-----END PGP PRIVATE KEY BLOCK-----';
|
||||||
|
|
||||||
it('Symmetrically encrypted packet', function(done) {
|
it('Symmetrically encrypted packet', function(done) {
|
||||||
var message = new openpgp.packet.List();
|
var message = new openpgp.packet.List();
|
||||||
|
|
||||||
var literal = new openpgp.packet.Literal();
|
var literal = new openpgp.packet.Literal();
|
||||||
literal.setText('Hello world');
|
literal.setText('Hello world');
|
||||||
|
|
||||||
var enc = new openpgp.packet.SymmetricallyEncrypted();
|
|
||||||
message.push(enc);
|
|
||||||
enc.packets.push(literal);
|
|
||||||
|
|
||||||
var key = '12345678901234567890123456789012',
|
var enc = new openpgp.packet.SymmetricallyEncrypted();
|
||||||
algo = 'aes256';
|
message.push(enc);
|
||||||
|
enc.packets.push(literal);
|
||||||
|
|
||||||
enc.encrypt(algo, key);
|
var key = '12345678901234567890123456789012',
|
||||||
|
algo = 'aes256';
|
||||||
|
|
||||||
var msg2 = new openpgp.packet.List();
|
enc.encrypt(algo, key);
|
||||||
msg2.read(message.write());
|
|
||||||
|
|
||||||
msg2[0].decrypt(algo, key);
|
var msg2 = new openpgp.packet.List();
|
||||||
|
msg2.read(message.write());
|
||||||
|
|
||||||
|
msg2[0].decrypt(algo, key);
|
||||||
|
|
||||||
expect(msg2[0].packets[0].data).to.equal(literal.data);
|
expect(msg2[0].packets[0].data).to.equal(literal.data);
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Sym. encrypted integrity protected packet', function(done) {
|
it('Sym. encrypted integrity protected packet', function(done) {
|
||||||
var key = '12345678901234567890123456789012',
|
var key = '12345678901234567890123456789012',
|
||||||
algo = 'aes256';
|
algo = 'aes256';
|
||||||
|
|
||||||
var literal = new openpgp.packet.Literal(),
|
var literal = new openpgp.packet.Literal(),
|
||||||
enc = new openpgp.packet.SymEncryptedIntegrityProtected(),
|
enc = new openpgp.packet.SymEncryptedIntegrityProtected(),
|
||||||
msg = new openpgp.packet.List();
|
msg = new openpgp.packet.List();
|
||||||
|
|
||||||
msg.push(enc);
|
msg.push(enc);
|
||||||
literal.setText('Hello world!');
|
literal.setText('Hello world!');
|
||||||
enc.packets.push(literal);
|
enc.packets.push(literal);
|
||||||
enc.encrypt(algo, key);
|
enc.encrypt(algo, key);
|
||||||
|
|
||||||
var msg2 = new openpgp.packet.List();
|
|
||||||
msg2.read(msg.write());
|
|
||||||
|
|
||||||
msg2[0].decrypt(algo, key);
|
var msg2 = new openpgp.packet.List();
|
||||||
|
msg2.read(msg.write());
|
||||||
|
|
||||||
|
msg2[0].decrypt(algo, key);
|
||||||
|
|
||||||
expect(msg2[0].packets[0].data).to.equal(literal.data);
|
expect(msg2[0].packets[0].data).to.equal(literal.data);
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Sym encrypted session key with a compressed packet', function(done) {
|
it('Sym encrypted session key with a compressed packet', function(done) {
|
||||||
var msg =
|
var msg =
|
||||||
'-----BEGIN PGP MESSAGE-----\n' +
|
'-----BEGIN PGP MESSAGE-----\n' +
|
||||||
'Version: GnuPG v2.0.19 (GNU/Linux)\n' +
|
'Version: GnuPG v2.0.19 (GNU/Linux)\n' +
|
||||||
'\n' +
|
'\n' +
|
||||||
'jA0ECQMCpo7I8WqsebTJ0koBmm6/oqdHXJU9aPe+Po+nk/k4/PZrLmlXwz2lhqBg\n' +
|
'jA0ECQMCpo7I8WqsebTJ0koBmm6/oqdHXJU9aPe+Po+nk/k4/PZrLmlXwz2lhqBg\n' +
|
||||||
'GAlY9rxVStLBrg0Hn+5gkhyHI9B85rM1BEYXQ8pP5CSFuTwbJ3O2s67dzQ==\n' +
|
'GAlY9rxVStLBrg0Hn+5gkhyHI9B85rM1BEYXQ8pP5CSFuTwbJ3O2s67dzQ==\n' +
|
||||||
'=VZ0/\n' +
|
'=VZ0/\n' +
|
||||||
'-----END PGP MESSAGE-----';
|
'-----END PGP MESSAGE-----';
|
||||||
|
|
||||||
var msgbytes = openpgp.armor.decode(msg).data;
|
var msgbytes = openpgp.armor.decode(msg).data;
|
||||||
|
|
||||||
var parsed = new openpgp.packet.List();
|
var parsed = new openpgp.packet.List();
|
||||||
parsed.read(msgbytes);
|
parsed.read(msgbytes);
|
||||||
|
|
||||||
parsed[0].decrypt('test');
|
parsed[0].decrypt('test');
|
||||||
|
|
||||||
var key = parsed[0].sessionKey;
|
var key = parsed[0].sessionKey;
|
||||||
parsed[1].decrypt(parsed[0].sessionKeyAlgorithm, key);
|
parsed[1].decrypt(parsed[0].sessionKeyAlgorithm, key);
|
||||||
var compressed = parsed[1].packets[0];
|
var compressed = parsed[1].packets[0];
|
||||||
|
|
||||||
var result = compressed.packets[0].data;
|
var result = compressed.packets[0].data;
|
||||||
|
|
||||||
expect(result).to.equal('Hello world!\n');
|
expect(result).to.equal('Hello world!\n');
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Public key encrypted symmetric key packet', function(done) {
|
it('Public key encrypted symmetric key packet', function(done) {
|
||||||
var rsa = new openpgp.crypto.publicKey.rsa(),
|
var rsa = new openpgp.crypto.publicKey.rsa();
|
||||||
mpi = rsa.generate(512, "10001")
|
|
||||||
|
|
||||||
var mpi = [mpi.n, mpi.ee, mpi.d, mpi.p, mpi.q, mpi.u];
|
rsa.generate(512, "10001", function(error, mpiGen) {
|
||||||
|
expect(error).to.not.exist;
|
||||||
|
|
||||||
mpi = mpi.map(function(k) {
|
var mpi = [mpiGen.n, mpiGen.ee, mpiGen.d, mpiGen.p, mpiGen.q, mpiGen.u];
|
||||||
var mpi = new openpgp.MPI();
|
|
||||||
mpi.fromBigInteger(k);
|
|
||||||
return mpi;
|
|
||||||
});
|
|
||||||
|
|
||||||
var enc = new openpgp.packet.PublicKeyEncryptedSessionKey(),
|
mpi = mpi.map(function(k) {
|
||||||
msg = new openpgp.packet.List(),
|
var mpi = new openpgp.MPI();
|
||||||
msg2 = new openpgp.packet.List();
|
mpi.fromBigInteger(k);
|
||||||
|
return mpi;
|
||||||
|
});
|
||||||
|
|
||||||
enc.sessionKey = '12345678901234567890123456789012';
|
var enc = new openpgp.packet.PublicKeyEncryptedSessionKey(),
|
||||||
enc.publicKeyAlgorithm = 'rsa_encrypt';
|
msg = new openpgp.packet.List(),
|
||||||
enc.sessionKeyAlgorithm = 'aes256';
|
msg2 = new openpgp.packet.List();
|
||||||
enc.publicKeyId.bytes = '12345678';
|
|
||||||
enc.encrypt({ mpi: mpi });
|
|
||||||
|
|
||||||
msg.push(enc);
|
enc.sessionKey = '12345678901234567890123456789012';
|
||||||
|
enc.publicKeyAlgorithm = 'rsa_encrypt';
|
||||||
|
enc.sessionKeyAlgorithm = 'aes256';
|
||||||
|
enc.publicKeyId.bytes = '12345678';
|
||||||
|
enc.encrypt({ mpi: mpi });
|
||||||
|
|
||||||
msg2.read(msg.write());
|
msg.push(enc);
|
||||||
|
|
||||||
msg2[0].decrypt({ mpi: mpi });
|
msg2.read(msg.write());
|
||||||
|
|
||||||
expect(msg2[0].sessionKey).to.equal(enc.sessionKey);
|
msg2[0].decrypt({ mpi: mpi });
|
||||||
expect(msg2[0].sessionKeyAlgorithm).to.equal(enc.sessionKeyAlgorithm);
|
|
||||||
done();
|
expect(msg2[0].sessionKey).to.equal(enc.sessionKey);
|
||||||
|
expect(msg2[0].sessionKeyAlgorithm).to.equal(enc.sessionKeyAlgorithm);
|
||||||
|
done();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Secret key packet (reading, unencrpted)', function(done) {
|
it('Secret key packet (reading, unencrpted)', function(done) {
|
||||||
var armored_key =
|
var armored_key =
|
||||||
'-----BEGIN PGP PRIVATE KEY BLOCK-----\n' +
|
'-----BEGIN PGP PRIVATE KEY BLOCK-----\n' +
|
||||||
'Version: GnuPG v2.0.19 (GNU/Linux)\n' +
|
'Version: GnuPG v2.0.19 (GNU/Linux)\n' +
|
||||||
'\n' +
|
'\n' +
|
||||||
'lQHYBFF33iMBBAC9YfOYahJlWrVj2J1TjQiZLunWljI4G9e6ARTyD99nfOkV3swh\n' +
|
'lQHYBFF33iMBBAC9YfOYahJlWrVj2J1TjQiZLunWljI4G9e6ARTyD99nfOkV3swh\n' +
|
||||||
'0WaOse4Utj7BfTqdYcoezhCaQpuExUupKWZqmduBcwSmEBfNu1XyKcxlDQuuk0Vk\n' +
|
'0WaOse4Utj7BfTqdYcoezhCaQpuExUupKWZqmduBcwSmEBfNu1XyKcxlDQuuk0Vk\n' +
|
||||||
'viGC3kFRce/cJaKVFSRU8V5zPgt6KQNv/wNz7ydEisaSoNbk51vQt5oGfwARAQAB\n' +
|
'viGC3kFRce/cJaKVFSRU8V5zPgt6KQNv/wNz7ydEisaSoNbk51vQt5oGfwARAQAB\n' +
|
||||||
'AAP5AVL8xWMuKgLj9g7/wftMH+jO7vhAxje2W3Y+8r8TnOSn0536lQvzl/eQyeLC\n' +
|
'AAP5AVL8xWMuKgLj9g7/wftMH+jO7vhAxje2W3Y+8r8TnOSn0536lQvzl/eQyeLC\n' +
|
||||||
'VK2k3+7+trgO7I4KuXCXZqgAbEi3niDYXDaCJ+8gdR9qvPM2gi9NM71TGXZvGE0w\n' +
|
'VK2k3+7+trgO7I4KuXCXZqgAbEi3niDYXDaCJ+8gdR9qvPM2gi9NM71TGXZvGE0w\n' +
|
||||||
'X8gIZfqLTQWKm9TIS/3tdrth4nwhiye0ASychOboIiN6VIECAMbCQ4/noxGV6yTK\n' +
|
'X8gIZfqLTQWKm9TIS/3tdrth4nwhiye0ASychOboIiN6VIECAMbCQ4/noxGV6yTK\n' +
|
||||||
'VezsGSz+iCMxz2lV270/Ac2C5WPk+OlxXloxUXeEkGIr6Xkmhhpceed2KL41UC8Y\n' +
|
'VezsGSz+iCMxz2lV270/Ac2C5WPk+OlxXloxUXeEkGIr6Xkmhhpceed2KL41UC8Y\n' +
|
||||||
'w5ttGIECAPPsahniKGyqp9CHy6W0B83yhhcIbmLlaVG2ftKyUEDxIggzOlXuVrue\n' +
|
'w5ttGIECAPPsahniKGyqp9CHy6W0B83yhhcIbmLlaVG2ftKyUEDxIggzOlXuVrue\n' +
|
||||||
'z9XRd6wFqwDd1QMFW0uUyHPDCIFPnv8CAJaDFSZutuWdWMt15NZXjfgRgfJuDrtv\n' +
|
'z9XRd6wFqwDd1QMFW0uUyHPDCIFPnv8CAJaDFSZutuWdWMt15NZXjfgRgfJuDrtv\n' +
|
||||||
'E7yFY/p0el8lCihOT8WoHbTn1PbCYMzNBc0IhHaZKAtA2pjkE+wzz9ClP7QbR2Vv\n' +
|
'E7yFY/p0el8lCihOT8WoHbTn1PbCYMzNBc0IhHaZKAtA2pjkE+wzz9ClP7QbR2Vv\n' +
|
||||||
'cmdlIDxnZW9yZ2VAZXhhbXBsZS5jb20+iLkEEwECACMFAlF33iMCGwMHCwkIBwMC\n' +
|
'cmdlIDxnZW9yZ2VAZXhhbXBsZS5jb20+iLkEEwECACMFAlF33iMCGwMHCwkIBwMC\n' +
|
||||||
'AQYVCAIJCgsEFgIDAQIeAQIXgAAKCRBcqs36fwJCXRbvA/9LPiK6WFKcFoNBnLEJ\n' +
|
'AQYVCAIJCgsEFgIDAQIeAQIXgAAKCRBcqs36fwJCXRbvA/9LPiK6WFKcFoNBnLEJ\n' +
|
||||||
'mS/CNkL8yTpkslpCP6+TwJMc8uXqwYl9/PW2+CwmzZjs6JsvTzMcR/ZbfZJuSW6Y\n' +
|
'mS/CNkL8yTpkslpCP6+TwJMc8uXqwYl9/PW2+CwmzZjs6JsvTzMcR/ZbfZJuSW6Y\n' +
|
||||||
'EsLNejsSpgcY9aiewGtE+53e5oKYnlmVMTWOPywciIgMvXlzdGhxcwqJ8u0hT+ug\n' +
|
'EsLNejsSpgcY9aiewGtE+53e5oKYnlmVMTWOPywciIgMvXlzdGhxcwqJ8u0hT+ug\n' +
|
||||||
'9CjcAfuX9yw85LwXtdGwNh7J8Q==\n' +
|
'9CjcAfuX9yw85LwXtdGwNh7J8Q==\n' +
|
||||||
'=lKiS\n' +
|
'=lKiS\n' +
|
||||||
'-----END PGP PRIVATE KEY BLOCK-----';
|
'-----END PGP PRIVATE KEY BLOCK-----';
|
||||||
|
|
||||||
var key = new openpgp.packet.List();
|
var key = new openpgp.packet.List();
|
||||||
key.read(openpgp.armor.decode(armored_key).data);
|
key.read(openpgp.armor.decode(armored_key).data);
|
||||||
key = key[0];
|
key = key[0];
|
||||||
|
|
||||||
var enc = new openpgp.packet.PublicKeyEncryptedSessionKey(),
|
var enc = new openpgp.packet.PublicKeyEncryptedSessionKey(),
|
||||||
secret = '12345678901234567890123456789012';
|
secret = '12345678901234567890123456789012';
|
||||||
|
|
||||||
enc.sessionKey = secret;
|
enc.sessionKey = secret;
|
||||||
enc.publicKeyAlgorithm = 'rsa_encrypt';
|
enc.publicKeyAlgorithm = 'rsa_encrypt';
|
||||||
enc.sessionKeyAlgorithm = 'aes256';
|
enc.sessionKeyAlgorithm = 'aes256';
|
||||||
enc.publicKeyId.bytes = '12345678';
|
enc.publicKeyId.bytes = '12345678';
|
||||||
|
|
||||||
enc.encrypt(key);
|
enc.encrypt(key);
|
||||||
|
|
||||||
enc.decrypt(key);
|
enc.decrypt(key);
|
||||||
|
|
||||||
expect(enc.sessionKey).to.equal(secret);
|
expect(enc.sessionKey).to.equal(secret);
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Public key encrypted packet (reading, GPG)', function(done) {
|
it('Public key encrypted packet (reading, GPG)', function(done) {
|
||||||
var armored_key =
|
var armored_key =
|
||||||
'-----BEGIN PGP PRIVATE KEY BLOCK-----\n' +
|
'-----BEGIN PGP PRIVATE KEY BLOCK-----\n' +
|
||||||
'Version: GnuPG v2.0.19 (GNU/Linux)\n' +
|
'Version: GnuPG v2.0.19 (GNU/Linux)\n' +
|
||||||
'\n' +
|
'\n' +
|
||||||
'lQHYBFF6gtkBBADKUOWZK6/V75MNwBS+hLYicoS0Sojbo3qWXXpS7eM+uhiDm4bP\n' +
|
'lQHYBFF6gtkBBADKUOWZK6/V75MNwBS+hLYicoS0Sojbo3qWXXpS7eM+uhiDm4bP\n' +
|
||||||
'DNjdNVA0R+TCjvhWbc3W6cvdHYTmHRMhTIOefncZRt3OwF7AvVk53fKKPiNNv5C9\n' +
|
'DNjdNVA0R+TCjvhWbc3W6cvdHYTmHRMhTIOefncZRt3OwF7AvVk53fKKPiNNv5C9\n' +
|
||||||
'IK8bcDhAknSOg1TXRSpXLHtYy36A6iDgffNSjoCOVaeKpuRDMA37PvJWFQARAQAB\n' +
|
'IK8bcDhAknSOg1TXRSpXLHtYy36A6iDgffNSjoCOVaeKpuRDMA37PvJWFQARAQAB\n' +
|
||||||
'AAP+KxHbOwcrnPPuXppCYEew3Xb7LMWESpvMFFgsmxx1COzFnLjek1P1E+yOWT7n\n' +
|
'AAP+KxHbOwcrnPPuXppCYEew3Xb7LMWESpvMFFgsmxx1COzFnLjek1P1E+yOWT7n\n' +
|
||||||
'4opcsEuaazLk+TrYSMOuR6O6DgGg5c+ctVPU+NGNNCiiTkOzuD+8ow8NgsoINOxi\n' +
|
'4opcsEuaazLk+TrYSMOuR6O6DgGg5c+ctVPU+NGNNCiiTkOzuD+8ow8NgsoINOxi\n' +
|
||||||
'481qLK0NYpc5sEg394J3fRuzpfEi6DTS/RzCN7YDiGFccNECAM71NuaAzH5LrZ+B\n' +
|
'481qLK0NYpc5sEg394J3fRuzpfEi6DTS/RzCN7YDiGFccNECAM71NuaAzH5LrZ+B\n' +
|
||||||
'4Okwy9CQQbgoYrdaia24CjEaUODaROnyNsvOb0ydEebVAbGzrsBr6LrisTidyZsG\n' +
|
'4Okwy9CQQbgoYrdaia24CjEaUODaROnyNsvOb0ydEebVAbGzrsBr6LrisTidyZsG\n' +
|
||||||
't2T+L7ECAPpCFzZIwwk6giZ10HmXEhXZLXYmdhQD/1fwegpTrEciMA6MCcdkcCyO\n' +
|
't2T+L7ECAPpCFzZIwwk6giZ10HmXEhXZLXYmdhQD/1fwegpTrEciMA6MCcdkcCyO\n' +
|
||||||
'2/J+S+NXM62ykMGDhg2cjhU1rj/uaaUCAJfCjkwpxMsDKHYDFDXyjJFy2vEmA3s8\n' +
|
'2/J+S+NXM62ykMGDhg2cjhU1rj/uaaUCAJfCjkwpxMsDKHYDFDXyjJFy2vEmA3s8\n' +
|
||||||
'cnmAUDF1caPyEcPEZmYJRE+KdroOD6IGhzp7oA34Ef3D6HOCovH9YaCgbbQbSm9o\n' +
|
'cnmAUDF1caPyEcPEZmYJRE+KdroOD6IGhzp7oA34Ef3D6HOCovH9YaCgbbQbSm9o\n' +
|
||||||
'bm55IDxqb2hubnlAZXhhbXBsZS5jb20+iLkEEwECACMFAlF6gtkCGwMHCwkIBwMC\n' +
|
'bm55IDxqb2hubnlAZXhhbXBsZS5jb20+iLkEEwECACMFAlF6gtkCGwMHCwkIBwMC\n' +
|
||||||
'AQYVCAIJCgsEFgIDAQIeAQIXgAAKCRA6HTM8yP08keZgA/4vL273zrqnmOrqmo/K\n' +
|
'AQYVCAIJCgsEFgIDAQIeAQIXgAAKCRA6HTM8yP08keZgA/4vL273zrqnmOrqmo/K\n' +
|
||||||
'UxQgD0vMhM58d25UjGYI6LAZkAls/k4FvFt5GUHVWJR3HBRuuNlB7UndH/uYlU7j\n' +
|
'UxQgD0vMhM58d25UjGYI6LAZkAls/k4FvFt5GUHVWJR3HBRuuNlB7UndH/uYlU7j\n' +
|
||||||
'm/bQLiP4uvFQuRGuG76f0O5t/KyeUdzrpNiJpe8tYDAnoPxUzENYsIv0fm2ZISo1\n' +
|
'm/bQLiP4uvFQuRGuG76f0O5t/KyeUdzrpNiJpe8tYDAnoPxUzENYsIv0fm2ZISo1\n' +
|
||||||
'QnnXX2WuVZGMZH1YhQoakZxbnp0B2ARReoLZAQQAvQvPp2MLu9vnRvZ3Py559kQf\n' +
|
'QnnXX2WuVZGMZH1YhQoakZxbnp0B2ARReoLZAQQAvQvPp2MLu9vnRvZ3Py559kQf\n' +
|
||||||
'0Z5AnEXVokALTn5A2m51dLekQ9T3Rhz8p9I6C/XjVQwBkp1USOaDUz+L7lsbNdY4\n' +
|
'0Z5AnEXVokALTn5A2m51dLekQ9T3Rhz8p9I6C/XjVQwBkp1USOaDUz+L7lsbNdY4\n' +
|
||||||
'YbUi3eIA5RImVXeTIrD1hE4CllDNKmqT5wFN07eEu7QhDEuYioO+4gtjjhUDYeIA\n' +
|
'YbUi3eIA5RImVXeTIrD1hE4CllDNKmqT5wFN07eEu7QhDEuYioO+4gtjjhUDYeIA\n' +
|
||||||
'dCVtVO//q8rP8ukZEc8AEQEAAQAD/RHlttyNe3RnDr/AoKx6HXDLpUmGlm5VDDMm\n' +
|
'dCVtVO//q8rP8ukZEc8AEQEAAQAD/RHlttyNe3RnDr/AoKx6HXDLpUmGlm5VDDMm\n' +
|
||||||
'pgth14j2cSdCJYqIdHqOTvsiY31zY3jPQKzdOTgHnsI4X2qK9InbwXepSBkaOJzY\n' +
|
'pgth14j2cSdCJYqIdHqOTvsiY31zY3jPQKzdOTgHnsI4X2qK9InbwXepSBkaOJzY\n' +
|
||||||
'iNhifPSUs9qoNawDqbFJ8PMXd4QQGgM93w+tudKC650Zuq7M7eWSdQg0u9aoLY97\n' +
|
'iNhifPSUs9qoNawDqbFJ8PMXd4QQGgM93w+tudKC650Zuq7M7eWSdQg0u9aoLY97\n' +
|
||||||
'MpKx3DUFAgDA/RgoO8xYMgkKN1tuKWa61qesLdJRAZI/3cnvtsmmEBt9tdbcDoBz\n' +
|
'MpKx3DUFAgDA/RgoO8xYMgkKN1tuKWa61qesLdJRAZI/3cnvtsmmEBt9tdbcDoBz\n' +
|
||||||
'gOIAAvUFgipuP6dBWLyf2NRNRVVQdNTlAgD6xS7S87g3kTa3GLcEI2cveaP1WWNK\n' +
|
'gOIAAvUFgipuP6dBWLyf2NRNRVVQdNTlAgD6xS7S87g3kTa3GLcEI2cveaP1WWNK\n' +
|
||||||
'rKFnVWsjBKArKFzMQ5N6FMnFD4T96i3sYlACE5UjH90SpOgBKOpdKzSjAf9nghrw\n' +
|
'rKFnVWsjBKArKFzMQ5N6FMnFD4T96i3sYlACE5UjH90SpOgBKOpdKzSjAf9nghrw\n' +
|
||||||
'kbFbF708ZIpVEwxvp/JoSutYUQ4v01MImnCGqzDVuSef3eutLLu4ZG7kLekxNauV\n' +
|
'kbFbF708ZIpVEwxvp/JoSutYUQ4v01MImnCGqzDVuSef3eutLLu4ZG7kLekxNauV\n' +
|
||||||
'8tGFwxsdtv30RL/3nW+InwQYAQIACQUCUXqC2QIbDAAKCRA6HTM8yP08kRXjBACu\n' +
|
'8tGFwxsdtv30RL/3nW+InwQYAQIACQUCUXqC2QIbDAAKCRA6HTM8yP08kRXjBACu\n' +
|
||||||
'RtEwjU+p6qqm3pmh7xz1CzhQN1F7VOj9dFUeECJJ1iv8J71w5UINH0otIceeBeWy\n' +
|
'RtEwjU+p6qqm3pmh7xz1CzhQN1F7VOj9dFUeECJJ1iv8J71w5UINH0otIceeBeWy\n' +
|
||||||
'NLA/QvK8+4/b9QW+S8aDZyeZpYg37gBwdTNGNT7TsEAxz9SUbx9uRja0wNmtb5xW\n' +
|
'NLA/QvK8+4/b9QW+S8aDZyeZpYg37gBwdTNGNT7TsEAxz9SUbx9uRja0wNmtb5xW\n' +
|
||||||
'mG+VE8CBXNkp8JTWx05AHwtK3baWlHWwpwnRlbU94Q==\n' +
|
'mG+VE8CBXNkp8JTWx05AHwtK3baWlHWwpwnRlbU94Q==\n' +
|
||||||
'=FSwA\n' +
|
'=FSwA\n' +
|
||||||
'-----END PGP PRIVATE KEY BLOCK-----';
|
'-----END PGP PRIVATE KEY BLOCK-----';
|
||||||
|
|
||||||
var armored_msg =
|
var armored_msg =
|
||||||
'-----BEGIN PGP MESSAGE-----\n' +
|
'-----BEGIN PGP MESSAGE-----\n' +
|
||||||
'Version: GnuPG v2.0.19 (GNU/Linux)\n' +
|
'Version: GnuPG v2.0.19 (GNU/Linux)\n' +
|
||||||
'\n' +
|
'\n' +
|
||||||
'hIwDFYET+7bfx/ABA/95Uc9942Tg8oqpO0vEu2eSKwPALM3a0DrVdAiFOIK/dJmZ\n' +
|
'hIwDFYET+7bfx/ABA/95Uc9942Tg8oqpO0vEu2eSKwPALM3a0DrVdAiFOIK/dJmZ\n' +
|
||||||
'YrtPRw3EEwHZjl6CO9RD+95iE27tPbsICw1K43gofSV/wWsPO6vvs3eftQYHSxxa\n' +
|
'YrtPRw3EEwHZjl6CO9RD+95iE27tPbsICw1K43gofSV/wWsPO6vvs3eftQYHSxxa\n' +
|
||||||
'IQbTPImiRaJ73Mf7iM3CNtQM4iUBsx1HnUGl+rtD0nz3fLm6i3CjwiNQWW42I9JH\n' +
|
'IQbTPImiRaJ73Mf7iM3CNtQM4iUBsx1HnUGl+rtD0nz3fLm6i3CjwiNQWW42I9JH\n' +
|
||||||
'AWv8EvvpxZ8X2ClFfSW3UVBoROHe9CAWHM/40nGutAZK8MIgmUI4xqkLFBbqqTyx\n' +
|
'AWv8EvvpxZ8X2ClFfSW3UVBoROHe9CAWHM/40nGutAZK8MIgmUI4xqkLFBbqqTyx\n' +
|
||||||
'/cDSC4Q+sv65UX4urbfc7uJuk1Cpj54=\n' +
|
'/cDSC4Q+sv65UX4urbfc7uJuk1Cpj54=\n' +
|
||||||
'=iSaK\n' +
|
'=iSaK\n' +
|
||||||
'-----END PGP MESSAGE-----';
|
'-----END PGP MESSAGE-----';
|
||||||
|
|
||||||
|
var key = new openpgp.packet.List();
|
||||||
|
key.read(openpgp.armor.decode(armored_key).data);
|
||||||
|
key = key[3];
|
||||||
|
|
||||||
var key = new openpgp.packet.List();
|
var msg = new openpgp.packet.List();
|
||||||
key.read(openpgp.armor.decode(armored_key).data);
|
msg.read(openpgp.armor.decode(armored_msg).data);
|
||||||
key = key[3];
|
|
||||||
|
|
||||||
var msg = new openpgp.packet.List();
|
msg[0].decrypt(key);
|
||||||
msg.read(openpgp.armor.decode(armored_msg).data);
|
msg[1].decrypt(msg[0].sessionKeyAlgorithm, msg[0].sessionKey);
|
||||||
|
|
||||||
msg[0].decrypt(key);
|
var text = msg[1].packets[0].packets[0].data;
|
||||||
msg[1].decrypt(msg[0].sessionKeyAlgorithm, msg[0].sessionKey);
|
|
||||||
|
|
||||||
var text = msg[1].packets[0].packets[0].data;
|
|
||||||
|
|
||||||
expect(text).to.equal('Hello world!');
|
expect(text).to.equal('Hello world!');
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Sym encrypted session key reading/writing', function(done) {
|
it('Sym encrypted session key reading/writing', function(done) {
|
||||||
var passphrase = 'hello',
|
var passphrase = 'hello',
|
||||||
algo = 'aes256';
|
algo = 'aes256';
|
||||||
|
|
||||||
var literal = new openpgp.packet.Literal(),
|
var literal = new openpgp.packet.Literal(),
|
||||||
key_enc = new openpgp.packet.SymEncryptedSessionKey(),
|
key_enc = new openpgp.packet.SymEncryptedSessionKey(),
|
||||||
enc = new openpgp.packet.SymEncryptedIntegrityProtected(),
|
enc = new openpgp.packet.SymEncryptedIntegrityProtected(),
|
||||||
msg = new openpgp.packet.List();
|
msg = new openpgp.packet.List();
|
||||||
|
|
||||||
msg.push(key_enc);
|
msg.push(key_enc);
|
||||||
msg.push(enc);
|
msg.push(enc);
|
||||||
|
|
||||||
key_enc.sessionKeyAlgorithm = algo;
|
key_enc.sessionKeyAlgorithm = algo;
|
||||||
key_enc.decrypt(passphrase);
|
key_enc.decrypt(passphrase);
|
||||||
|
|
||||||
var key = key_enc.sessionKey;
|
var key = key_enc.sessionKey;
|
||||||
|
|
||||||
literal.setText('Hello world!');
|
literal.setText('Hello world!');
|
||||||
enc.packets.push(literal);
|
enc.packets.push(literal);
|
||||||
enc.encrypt(algo, key);
|
enc.encrypt(algo, key);
|
||||||
|
|
||||||
|
|
||||||
var msg2 = new openpgp.packet.List();
|
var msg2 = new openpgp.packet.List();
|
||||||
msg2.read(msg.write());
|
msg2.read(msg.write());
|
||||||
|
|
||||||
msg2[0].decrypt(passphrase);
|
msg2[0].decrypt(passphrase);
|
||||||
var key2 = msg2[0].sessionKey;
|
var key2 = msg2[0].sessionKey;
|
||||||
msg2[1].decrypt(msg2[0].sessionKeyAlgorithm, key2);
|
msg2[1].decrypt(msg2[0].sessionKeyAlgorithm, key2);
|
||||||
|
|
||||||
expect(msg2[1].packets[0].data).to.equal(literal.data);
|
expect(msg2[1].packets[0].data).to.equal(literal.data);
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Secret key encryption/decryption test', function(done) {
|
it('Secret key encryption/decryption test', function(done) {
|
||||||
var armored_msg =
|
var armored_msg =
|
||||||
'-----BEGIN PGP MESSAGE-----\n' +
|
'-----BEGIN PGP MESSAGE-----\n' +
|
||||||
'Version: GnuPG v2.0.19 (GNU/Linux)\n' +
|
'Version: GnuPG v2.0.19 (GNU/Linux)\n' +
|
||||||
'\n' +
|
'\n' +
|
||||||
'hIwD95D9aHS5fxEBA/98CwH54XZmwobOmHUcvWcDDQysBEC4uf7wASiGcRbejDaO\n' +
|
'hIwD95D9aHS5fxEBA/98CwH54XZmwobOmHUcvWcDDQysBEC4uf7wASiGcRbejDaO\n' +
|
||||||
'aJqcrK/3k8sBQMO7yOhvrCRqqpGDqnmx7IaaKLnZS7nYAZoHEsK9UyG0hDa8Cfbo\n' +
|
'aJqcrK/3k8sBQMO7yOhvrCRqqpGDqnmx7IaaKLnZS7nYAZoHEsK9UyG0hDa8Cfbo\n' +
|
||||||
'CP4xZVcgIvIfAW/in1LeT2td0QcQNbeewBmPea+vQEEvRgIP10tlE7MK8Ay48dJH\n' +
|
'CP4xZVcgIvIfAW/in1LeT2td0QcQNbeewBmPea+vQEEvRgIP10tlE7MK8Ay48dJH\n' +
|
||||||
'AagMgNYg7MBUjpuOCVrjM1pWja8uzbULfYhTq3IJ8H3QhbdT+k9khY9f0aJPEeYi\n' +
|
'AagMgNYg7MBUjpuOCVrjM1pWja8uzbULfYhTq3IJ8H3QhbdT+k9khY9f0aJPEeYi\n' +
|
||||||
'dVv6DK9uviMGc/DsVCw5K8lQRLlkcHc=\n' +
|
'dVv6DK9uviMGc/DsVCw5K8lQRLlkcHc=\n' +
|
||||||
'=pR+C\n' +
|
'=pR+C\n' +
|
||||||
'-----END PGP MESSAGE-----';
|
'-----END PGP MESSAGE-----';
|
||||||
|
|
||||||
var key = new openpgp.packet.List();
|
var key = new openpgp.packet.List();
|
||||||
key.read(openpgp.armor.decode(armored_key).data);
|
key.read(openpgp.armor.decode(armored_key).data);
|
||||||
key = key[3];
|
key = key[3];
|
||||||
key.decrypt('test');
|
key.decrypt('test');
|
||||||
|
|
||||||
var msg = new openpgp.packet.List();
|
var msg = new openpgp.packet.List();
|
||||||
msg.read(openpgp.armor.decode(armored_msg).data);
|
msg.read(openpgp.armor.decode(armored_msg).data);
|
||||||
|
|
||||||
msg[0].decrypt(key);
|
msg[0].decrypt(key);
|
||||||
msg[1].decrypt(msg[0].sessionKeyAlgorithm, msg[0].sessionKey);
|
msg[1].decrypt(msg[0].sessionKeyAlgorithm, msg[0].sessionKey);
|
||||||
|
|
||||||
var text = msg[1].packets[0].packets[0].data;
|
var text = msg[1].packets[0].packets[0].data;
|
||||||
|
|
||||||
expect(text).to.equal('Hello world!');
|
expect(text).to.equal('Hello world!');
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Secret key reading with signature verification.', function(done) {
|
it('Secret key reading with signature verification.', function(done) {
|
||||||
var key = new openpgp.packet.List();
|
var key = new openpgp.packet.List();
|
||||||
key.read(openpgp.armor.decode(armored_key).data);
|
key.read(openpgp.armor.decode(armored_key).data);
|
||||||
|
|
||||||
|
|
||||||
var verified = key[2].verify(key[0],
|
var verified = key[2].verify(key[0],
|
||||||
{
|
{
|
||||||
userid: key[1],
|
userid: key[1],
|
||||||
key: key[0]
|
key: key[0]
|
||||||
});
|
});
|
||||||
|
|
||||||
verified = verified && key[4].verify(key[0],
|
verified = verified && key[4].verify(key[0],
|
||||||
{
|
{
|
||||||
key: key[0],
|
key: key[0],
|
||||||
bind: key[3]
|
bind: key[3]
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(verified).to.be.true;
|
expect(verified).to.be.true;
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Reading a signed, encrypted message.', function(done) {
|
it('Reading a signed, encrypted message.', function(done) {
|
||||||
var armored_msg =
|
var armored_msg =
|
||||||
'-----BEGIN PGP MESSAGE-----\n' +
|
'-----BEGIN PGP MESSAGE-----\n' +
|
||||||
'Version: GnuPG v2.0.19 (GNU/Linux)\n' +
|
'Version: GnuPG v2.0.19 (GNU/Linux)\n' +
|
||||||
'\n' +
|
'\n' +
|
||||||
'hIwD95D9aHS5fxEBA/4/X4myvH+jB1HYNeZvdK+WsBNDMfLsBGOf205Rxr3vSob/\n' +
|
'hIwD95D9aHS5fxEBA/4/X4myvH+jB1HYNeZvdK+WsBNDMfLsBGOf205Rxr3vSob/\n' +
|
||||||
'A09boj8/9lFaipqu+AEdQKEjCB8sZ+OY0WiQPEPpuhG+mVqDqEiPFkdpcqNtS0VV\n' +
|
'A09boj8/9lFaipqu+AEdQKEjCB8sZ+OY0WiQPEPpuhG+mVqDqEiPFkdpcqNtS0VV\n' +
|
||||||
'pwqplHo6QnH2MHfxprZHYuwcEC9ynJCxJ6kSCD8Xs99h+PjxNNw7NhMjkF+N69LA\n' +
|
'pwqplHo6QnH2MHfxprZHYuwcEC9ynJCxJ6kSCD8Xs99h+PjxNNw7NhMjkF+N69LA\n' +
|
||||||
'NwGPtbLx2/r2nR4gO8gV92A2RQCOwPP7ZV+6fXgWIs+mhyCHFP3xUP5DaFCNM8mo\n' +
|
'NwGPtbLx2/r2nR4gO8gV92A2RQCOwPP7ZV+6fXgWIs+mhyCHFP3xUP5DaFCNM8mo\n' +
|
||||||
'PN97i659ucxF6IbOoK56FEaUbOPTD6xdyhWamxKfMsIb0UJgVUNhGaq+VlvOJxaB\n' +
|
'PN97i659ucxF6IbOoK56FEaUbOPTD6xdyhWamxKfMsIb0UJgVUNhGaq+VlvOJxaB\n' +
|
||||||
'iRcnY5UxsypKgtqfcKIseb21MIo4vcNdogyxBIDlAO472Zfxn0udzr6W2aQ77+NK\n' +
|
'iRcnY5UxsypKgtqfcKIseb21MIo4vcNdogyxBIDlAO472Zfxn0udzr6W2aQ77+NK\n' +
|
||||||
'FE1O0kCXS+DTFOYYVD7X8rXGSglQsdXJmHd89sdYFQkO7D7bOLdRJuXgdgH2czCs\n' +
|
'FE1O0kCXS+DTFOYYVD7X8rXGSglQsdXJmHd89sdYFQkO7D7bOLdRJuXgdgH2czCs\n' +
|
||||||
'UBGuHZzsGbTdyKvpVBuS3rnyHHBk6oCnsm1Nl7eLs64VkZUxjEUbq5pb4dlr1pw2\n' +
|
'UBGuHZzsGbTdyKvpVBuS3rnyHHBk6oCnsm1Nl7eLs64VkZUxjEUbq5pb4dlr1pw2\n' +
|
||||||
'ztpmpAnRcmM=\n' +
|
'ztpmpAnRcmM=\n' +
|
||||||
'=htrB\n' +
|
'=htrB\n' +
|
||||||
'-----END PGP MESSAGE-----'
|
'-----END PGP MESSAGE-----'
|
||||||
|
|
||||||
var key = new openpgp.packet.List();
|
var key = new openpgp.packet.List();
|
||||||
key.read(openpgp.armor.decode(armored_key).data);
|
key.read(openpgp.armor.decode(armored_key).data);
|
||||||
key[3].decrypt('test')
|
key[3].decrypt('test')
|
||||||
|
|
||||||
var msg = new openpgp.packet.List();
|
var msg = new openpgp.packet.List();
|
||||||
msg.read(openpgp.armor.decode(armored_msg).data);
|
msg.read(openpgp.armor.decode(armored_msg).data);
|
||||||
|
|
||||||
msg[0].decrypt(key[3]);
|
msg[0].decrypt(key[3]);
|
||||||
msg[1].decrypt(msg[0].sessionKeyAlgorithm, msg[0].sessionKey);
|
msg[1].decrypt(msg[0].sessionKeyAlgorithm, msg[0].sessionKey);
|
||||||
|
|
||||||
var payload = msg[1].packets[0].packets
|
var payload = msg[1].packets[0].packets
|
||||||
|
|
||||||
var verified = payload[2].verify(key[0], payload[1]);
|
var verified = payload[2].verify(key[0], payload[1]);
|
||||||
|
|
||||||
expect(verified).to.be.true;
|
expect(verified).to.be.true;
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Writing and encryption of a secret key packet.', function(done) {
|
it('Writing and encryption of a secret key packet.', function(done) {
|
||||||
var key = new openpgp.packet.List();
|
var key = new openpgp.packet.List();
|
||||||
key.push(new openpgp.packet.SecretKey);
|
key.push(new openpgp.packet.SecretKey);
|
||||||
|
|
||||||
var rsa = new openpgp.crypto.publicKey.rsa(),
|
var rsa = new openpgp.crypto.publicKey.rsa();
|
||||||
mpi = rsa.generate(512, "10001")
|
|
||||||
|
|
||||||
|
rsa.generate(512, "10001", function(err, mipGen) {
|
||||||
|
expect(err).to.not.exist;
|
||||||
|
|
||||||
var mpi = [mpi.n, mpi.ee, mpi.d, mpi.p, mpi.q, mpi.u];
|
var mpi = [mipGen.n, mipGen.ee, mipGen.d, mipGen.p, mipGen.q, mipGen.u];
|
||||||
|
|
||||||
mpi = mpi.map(function(k) {
|
mpi = mpi.map(function(k) {
|
||||||
var mpi = new openpgp.MPI();
|
var mpi = new openpgp.MPI();
|
||||||
mpi.fromBigInteger(k);
|
mpi.fromBigInteger(k);
|
||||||
return mpi;
|
return mpi;
|
||||||
});
|
});
|
||||||
|
|
||||||
key[0].mpi = mpi;
|
key[0].mpi = mpi;
|
||||||
|
|
||||||
key[0].encrypt('hello');
|
key[0].encrypt('hello');
|
||||||
|
|
||||||
var raw = key.write();
|
var raw = key.write();
|
||||||
|
|
||||||
var key2 = new openpgp.packet.List();
|
var key2 = new openpgp.packet.List();
|
||||||
key2.read(raw);
|
key2.read(raw);
|
||||||
key2[0].decrypt('hello');
|
key2[0].decrypt('hello');
|
||||||
|
|
||||||
expect(key[0].mpi.toString()).to.equal(key2[0].mpi.toString());
|
expect(key[0].mpi.toString()).to.equal(key2[0].mpi.toString());
|
||||||
done();
|
done();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Writing and verification of a signature packet.', function(done) {
|
it('Writing and verification of a signature packet.', function(done) {
|
||||||
var key = new openpgp.packet.SecretKey();
|
var key = new openpgp.packet.SecretKey();
|
||||||
|
|
||||||
var rsa = new openpgp.crypto.publicKey.rsa,
|
var rsa = new openpgp.crypto.publicKey.rsa;
|
||||||
mpi = rsa.generate(512, "10001")
|
|
||||||
|
|
||||||
var mpi = [mpi.n, mpi.ee, mpi.d, mpi.p, mpi.q, mpi.u];
|
rsa.generate(512, "10001", function(err, mpiGen) {
|
||||||
|
expect(err).to.not.exist;
|
||||||
|
|
||||||
mpi = mpi.map(function(k) {
|
var mpi = [mpiGen.n, mpiGen.ee, mpiGen.d, mpiGen.p, mpiGen.q, mpiGen.u];
|
||||||
var mpi = new openpgp.MPI();
|
|
||||||
mpi.fromBigInteger(k);
|
|
||||||
return mpi;
|
|
||||||
});
|
|
||||||
|
|
||||||
key.mpi = mpi;
|
mpi = mpi.map(function(k) {
|
||||||
|
var mpi = new openpgp.MPI();
|
||||||
|
mpi.fromBigInteger(k);
|
||||||
|
return mpi;
|
||||||
|
});
|
||||||
|
|
||||||
var signed = new openpgp.packet.List(),
|
key.mpi = mpi;
|
||||||
literal = new openpgp.packet.Literal(),
|
|
||||||
signature = new openpgp.packet.Signature();
|
|
||||||
|
|
||||||
literal.setText('Hello world');
|
var signed = new openpgp.packet.List(),
|
||||||
|
literal = new openpgp.packet.Literal(),
|
||||||
|
signature = new openpgp.packet.Signature();
|
||||||
|
|
||||||
signature.hashAlgorithm = 'sha256';
|
literal.setText('Hello world');
|
||||||
signature.publicKeyAlgorithm = 'rsa_sign';
|
|
||||||
signature.signatureType = 'binary';
|
|
||||||
|
|
||||||
signature.sign(key, literal);
|
signature.hashAlgorithm = 'sha256';
|
||||||
|
signature.publicKeyAlgorithm = 'rsa_sign';
|
||||||
|
signature.signatureType = 'binary';
|
||||||
|
|
||||||
signed.push(literal);
|
signature.sign(key, literal);
|
||||||
signed.push(signature);
|
|
||||||
|
|
||||||
var raw = signed.write();
|
signed.push(literal);
|
||||||
|
signed.push(signature);
|
||||||
|
|
||||||
var signed2 = new openpgp.packet.List();
|
var raw = signed.write();
|
||||||
signed2.read(raw);
|
|
||||||
|
|
||||||
var verified = signed2[1].verify(key, signed2[0]);
|
var signed2 = new openpgp.packet.List();
|
||||||
|
signed2.read(raw);
|
||||||
|
|
||||||
expect(verified).to.be.true;
|
var verified = signed2[1].verify(key, signed2[0]);
|
||||||
done();
|
|
||||||
|
expect(verified).to.be.true;
|
||||||
|
done();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -312,7 +312,7 @@ describe("Signature", function() {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Verify V4 signature. Hash: SHA1. PK: RSA. Signature Type: 0x00 (binary document)', function(done) {
|
it('Verify V4 signature. Hash: SHA1. PK: RSA. Signature Type: 0x00 (binary document)', function(done) {
|
||||||
var signedArmor =
|
var signedArmor =
|
||||||
[ '-----BEGIN PGP MESSAGE-----',
|
[ '-----BEGIN PGP MESSAGE-----',
|
||||||
'Version: GnuPG v2.0.19 (GNU/Linux)',
|
'Version: GnuPG v2.0.19 (GNU/Linux)',
|
||||||
'',
|
'',
|
||||||
|
@ -335,7 +335,7 @@ describe("Signature", function() {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Verify V3 signature. Hash: MD5. PK: RSA. Signature Type: 0x01 (text document)', function(done) {
|
it('Verify V3 signature. Hash: MD5. PK: RSA. Signature Type: 0x01 (text document)', function(done) {
|
||||||
var signedArmor =
|
var signedArmor =
|
||||||
[ '-----BEGIN PGP MESSAGE-----',
|
[ '-----BEGIN PGP MESSAGE-----',
|
||||||
'Version: GnuPG v2.0.19 (GNU/Linux)',
|
'Version: GnuPG v2.0.19 (GNU/Linux)',
|
||||||
'',
|
'',
|
||||||
|
@ -358,7 +358,7 @@ describe("Signature", function() {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Verify signature of signed and encrypted message from GPG2 with openpgp.decryptAndVerifyMessage', function(done) {
|
it('Verify signature of signed and encrypted message from GPG2 with openpgp.decryptAndVerifyMessage', function(done) {
|
||||||
var msg_armor =
|
var msg_armor =
|
||||||
[ '-----BEGIN PGP MESSAGE-----',
|
[ '-----BEGIN PGP MESSAGE-----',
|
||||||
'Version: GnuPG v2.0.19 (GNU/Linux)',
|
'Version: GnuPG v2.0.19 (GNU/Linux)',
|
||||||
'',
|
'',
|
||||||
|
@ -393,7 +393,7 @@ describe("Signature", function() {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Verify signature of signed and encrypted message from PGP 10.3.0 with openpgp.decryptAndVerifyMessage', function(done) {
|
it('Verify signature of signed and encrypted message from PGP 10.3.0 with openpgp.decryptAndVerifyMessage', function(done) {
|
||||||
var msg_armor =
|
var msg_armor =
|
||||||
[ '-----BEGIN PGP MESSAGE-----',
|
[ '-----BEGIN PGP MESSAGE-----',
|
||||||
'Version: Encryption Desktop 10.3.0 (Build 9307)',
|
'Version: Encryption Desktop 10.3.0 (Build 9307)',
|
||||||
'Charset: utf-8',
|
'Charset: utf-8',
|
||||||
|
@ -429,7 +429,7 @@ describe("Signature", function() {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Verify signed message with two one pass signatures', function(done) {
|
it('Verify signed message with two one pass signatures', function(done) {
|
||||||
var msg_armor =
|
var msg_armor =
|
||||||
[ '-----BEGIN PGP MESSAGE-----',
|
[ '-----BEGIN PGP MESSAGE-----',
|
||||||
'Version: GnuPG v2.0.19 (GNU/Linux)',
|
'Version: GnuPG v2.0.19 (GNU/Linux)',
|
||||||
'',
|
'',
|
||||||
|
@ -470,7 +470,7 @@ describe("Signature", function() {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Verify cleartext signed message with two signatures with openpgp.verifyClearSignedMessage', function(done) {
|
it('Verify cleartext signed message with two signatures with openpgp.verifyClearSignedMessage', function(done) {
|
||||||
var msg_armor =
|
var msg_armor =
|
||||||
[ '-----BEGIN PGP SIGNED MESSAGE-----',
|
[ '-----BEGIN PGP SIGNED MESSAGE-----',
|
||||||
'Hash: SHA256',
|
'Hash: SHA256',
|
||||||
'',
|
'',
|
||||||
|
@ -523,7 +523,7 @@ describe("Signature", function() {
|
||||||
var clearSignedArmor = openpgp.signClearMessage([privKey], plaintext);
|
var clearSignedArmor = openpgp.signClearMessage([privKey], plaintext);
|
||||||
|
|
||||||
var csMsg = openpgp.cleartext.readArmored(clearSignedArmor);
|
var csMsg = openpgp.cleartext.readArmored(clearSignedArmor);
|
||||||
|
|
||||||
var cleartextSig = openpgp.verifyClearSignedMessage([pubKey], csMsg);
|
var cleartextSig = openpgp.verifyClearSignedMessage([pubKey], csMsg);
|
||||||
|
|
||||||
expect(cleartextSig).to.exist;
|
expect(cleartextSig).to.exist;
|
||||||
|
@ -636,13 +636,19 @@ describe("Signature", function() {
|
||||||
expect(result[0].valid).to.be.true;
|
expect(result[0].valid).to.be.true;
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Sign message with key without password', function() {
|
it('Sign message with key without password', function(done) {
|
||||||
var key = openpgp.generateKeyPair({numBits: 512, userId: 'ABC', passphrase: null}).key;
|
var opt = {numBits: 512, userId: 'ABC', passphrase: null};
|
||||||
|
openpgp.generateKeyPair(opt, function(err, gen) {
|
||||||
|
expect(err).to.not.exist;
|
||||||
|
|
||||||
var message = openpgp.message.fromText('hello world');
|
var key = gen.key;
|
||||||
message = message.sign([key]);
|
|
||||||
|
|
||||||
expect(message).to.exist;
|
var message = openpgp.message.fromText('hello world');
|
||||||
|
message = message.sign([key]);
|
||||||
|
|
||||||
|
expect(message).to.exist;
|
||||||
|
done();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
|
@ -427,14 +427,6 @@ describe('High level API', function() {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Generate 1024-bit RSA/RSA key sync', function () {
|
|
||||||
var key = openpgp.generateKeyPair({numBits: 1024, userId: 'Test McTestington <test@example.com>', passphrase: 'hello world'});
|
|
||||||
expect(key).to.exist;
|
|
||||||
expect(key.publicKeyArmored).to.match(/^-----BEGIN PGP PUBLIC/);
|
|
||||||
expect(key.privateKeyArmored).to.match(/^-----BEGIN PGP PRIVATE/);
|
|
||||||
expect(key.key).to.be.an.instanceof(openpgp.key.Key);
|
|
||||||
});
|
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('Decrypt secret key', function() {
|
describe('Decrypt secret key', function() {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user