Check created time to be valid and discard milliseconds from date objects
This commit is contained in:
parent
6ca8bc2180
commit
071fc35f38
|
@ -24,13 +24,13 @@
|
||||||
* @module cleartext
|
* @module cleartext
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import util from './util.js';
|
||||||
import config from './config';
|
import config from './config';
|
||||||
import armor from './encoding/armor';
|
import armor from './encoding/armor';
|
||||||
import enums from './enums';
|
import enums from './enums';
|
||||||
import packet from './packet';
|
import packet from './packet';
|
||||||
import { Signature } from './signature';
|
import { Signature } from './signature';
|
||||||
import { createVerificationObjects, createSignaturePackets } from './message';
|
import { createVerificationObjects, createSignaturePackets } from './message';
|
||||||
import { getPreferredHashAlgo } from './key';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @class
|
* @class
|
||||||
|
@ -69,10 +69,10 @@ CleartextMessage.prototype.getSigningKeyIds = function() {
|
||||||
* Sign the cleartext message
|
* Sign the cleartext message
|
||||||
* @param {Array<module:key~Key>} privateKeys private keys with decrypted secret key data for signing
|
* @param {Array<module:key~Key>} privateKeys private keys with decrypted secret key data for signing
|
||||||
* @param {Signature} signature (optional) any existing detached signature
|
* @param {Signature} signature (optional) any existing detached signature
|
||||||
* @param {Date} date The creation time of the signature that should be created
|
* @param {Date} date (optional) The creation time of the signature that should be created
|
||||||
* @return {module:message~CleartextMessage} new cleartext message with signed content
|
* @return {module:message~CleartextMessage} new cleartext message with signed content
|
||||||
*/
|
*/
|
||||||
CleartextMessage.prototype.sign = async function(privateKeys, signature = null, date = new Date()) {
|
CleartextMessage.prototype.sign = async function(privateKeys, signature = null, date=new Date()) {
|
||||||
return new CleartextMessage(this.text, await this.signDetached(privateKeys, signature, date));
|
return new CleartextMessage(this.text, await this.signDetached(privateKeys, signature, date));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -80,10 +80,10 @@ CleartextMessage.prototype.sign = async function(privateKeys, signature = null,
|
||||||
* Sign the cleartext message
|
* Sign the cleartext message
|
||||||
* @param {Array<module:key~Key>} privateKeys private keys with decrypted secret key data for signing
|
* @param {Array<module:key~Key>} privateKeys private keys with decrypted secret key data for signing
|
||||||
* @param {Signature} signature (optional) any existing detached signature
|
* @param {Signature} signature (optional) any existing detached signature
|
||||||
* @param {Date} date The creation time of the signature that should be created
|
* @param {Date} date (optional) The creation time of the signature that should be created
|
||||||
* @return {module:signature~Signature} new detached signature of message content
|
* @return {module:signature~Signature} new detached signature of message content
|
||||||
*/
|
*/
|
||||||
CleartextMessage.prototype.signDetached = async function(privateKeys, signature = null, date = new Date()) {
|
CleartextMessage.prototype.signDetached = async function(privateKeys, signature=null, date=new Date()) {
|
||||||
const literalDataPacket = new packet.Literal();
|
const literalDataPacket = new packet.Literal();
|
||||||
literalDataPacket.setText(this.text);
|
literalDataPacket.setText(this.text);
|
||||||
|
|
||||||
|
@ -93,23 +93,25 @@ CleartextMessage.prototype.signDetached = async function(privateKeys, signature
|
||||||
/**
|
/**
|
||||||
* Verify signatures of cleartext signed message
|
* Verify signatures of cleartext signed message
|
||||||
* @param {Array<module:key~Key>} keys array of keys to verify signatures
|
* @param {Array<module:key~Key>} keys array of keys to verify signatures
|
||||||
|
* @param {Date} date (optional) Verify the signature against the given date, i.e. check signature creation time < date < expiration time
|
||||||
* @return {Array<{keyid: module:type/keyid, valid: Boolean}>} list of signer's keyid and validity of signature
|
* @return {Array<{keyid: module:type/keyid, valid: Boolean}>} list of signer's keyid and validity of signature
|
||||||
*/
|
*/
|
||||||
CleartextMessage.prototype.verify = function(keys) {
|
CleartextMessage.prototype.verify = function(keys, date=new Date()) {
|
||||||
return this.verifyDetached(this.signature, keys);
|
return this.verifyDetached(this.signature, keys, date);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Verify signatures of cleartext signed message
|
* Verify signatures of cleartext signed message
|
||||||
* @param {Array<module:key~Key>} keys array of keys to verify signatures
|
* @param {Array<module:key~Key>} keys array of keys to verify signatures
|
||||||
|
* @param {Date} date (optional) Verify the signature against the given date, i.e. check signature creation time < date < expiration time
|
||||||
* @return {Array<{keyid: module:type/keyid, valid: Boolean}>} list of signer's keyid and validity of signature
|
* @return {Array<{keyid: module:type/keyid, valid: Boolean}>} list of signer's keyid and validity of signature
|
||||||
*/
|
*/
|
||||||
CleartextMessage.prototype.verifyDetached = function(signature, keys) {
|
CleartextMessage.prototype.verifyDetached = function(signature, keys, date=new Date()) {
|
||||||
const signatureList = signature.packets;
|
const signatureList = signature.packets;
|
||||||
const literalDataPacket = new packet.Literal();
|
const literalDataPacket = new packet.Literal();
|
||||||
// we assume that cleartext signature is generated based on UTF8 cleartext
|
// we assume that cleartext signature is generated based on UTF8 cleartext
|
||||||
literalDataPacket.setText(this.text);
|
literalDataPacket.setText(this.text);
|
||||||
return createVerificationObjects(signatureList, [literalDataPacket], keys);
|
return createVerificationObjects(signatureList, [literalDataPacket], keys, date);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
90
src/key.js
90
src/key.js
|
@ -300,11 +300,11 @@ Key.prototype.armor = function() {
|
||||||
/**
|
/**
|
||||||
* Returns first key packet or key packet by given keyId that is available for signing or signature verification
|
* Returns first key packet or key packet by given keyId that is available for signing or signature verification
|
||||||
* @param {module:type/keyid} keyId, optional
|
* @param {module:type/keyid} keyId, optional
|
||||||
* @param {Date} date the current date
|
* @param {Date} date use the given date for verification instead of the current time
|
||||||
* @return {(module:packet/secret_subkey|module:packet/secret_key|null)} key packet or null if no signing key has been found
|
* @return {(module:packet/secret_subkey|module:packet/secret_key|null)} key packet or null if no signing key has been found
|
||||||
*/
|
*/
|
||||||
Key.prototype.getSigningKeyPacket = function (keyId = null, date = new Date()) {
|
Key.prototype.getSigningKeyPacket = function (keyId=null, date=new Date()) {
|
||||||
const primaryUser = this.getPrimaryUser();
|
const primaryUser = this.getPrimaryUser(date);
|
||||||
if (primaryUser && (!keyId || this.primaryKey.getKeyId().equals(keyId)) &&
|
if (primaryUser && (!keyId || this.primaryKey.getKeyId().equals(keyId)) &&
|
||||||
isValidSigningKeyPacket(this.primaryKey, primaryUser.selfCertificate, date)) {
|
isValidSigningKeyPacket(this.primaryKey, primaryUser.selfCertificate, date)) {
|
||||||
return this.primaryKey;
|
return this.primaryKey;
|
||||||
|
@ -323,7 +323,8 @@ Key.prototype.getSigningKeyPacket = function (keyId = null, date = new Date()) {
|
||||||
return null;
|
return null;
|
||||||
};
|
};
|
||||||
|
|
||||||
function isValidEncryptionKeyPacket(keyPacket, signature, date = new Date()) {
|
function isValidEncryptionKeyPacket(keyPacket, signature, date=new Date()) {
|
||||||
|
const normDate = util.normalizeDate(date);
|
||||||
return keyPacket.algorithm !== enums.read(enums.publicKey, enums.publicKey.dsa) &&
|
return keyPacket.algorithm !== enums.read(enums.publicKey, enums.publicKey.dsa) &&
|
||||||
keyPacket.algorithm !== enums.read(enums.publicKey, enums.publicKey.rsa_sign) &&
|
keyPacket.algorithm !== enums.read(enums.publicKey, enums.publicKey.rsa_sign) &&
|
||||||
keyPacket.algorithm !== enums.read(enums.publicKey, enums.publicKey.ecdsa) &&
|
keyPacket.algorithm !== enums.read(enums.publicKey, enums.publicKey.ecdsa) &&
|
||||||
|
@ -331,28 +332,19 @@ function isValidEncryptionKeyPacket(keyPacket, signature, date = new Date()) {
|
||||||
(!signature.keyFlags ||
|
(!signature.keyFlags ||
|
||||||
(signature.keyFlags[0] & enums.keyFlags.encrypt_communication) !== 0 ||
|
(signature.keyFlags[0] & enums.keyFlags.encrypt_communication) !== 0 ||
|
||||||
(signature.keyFlags[0] & enums.keyFlags.encrypt_storage) !== 0) &&
|
(signature.keyFlags[0] & enums.keyFlags.encrypt_storage) !== 0) &&
|
||||||
(!signature.isExpired(date) &&
|
(!signature.isExpired(normDate) &&
|
||||||
// check expiration time of V3 key packet
|
(normDate === null || (keyPacket.created <= normDate && normDate < getExpirationTime(keyPacket, signature, Infinity))));
|
||||||
!(keyPacket.version === 3 && keyPacket.expirationTimeV3 !== 0 &&
|
|
||||||
+date > (keyPacket.created.getTime() + keyPacket.expirationTimeV3*24*3600*1000)) &&
|
|
||||||
// check expiration time of V4 key packet
|
|
||||||
!(keyPacket.version === 4 && signature.keyNeverExpires === false &&
|
|
||||||
+date > (keyPacket.created.getTime() + signature.keyExpirationTime*1000)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function isValidSigningKeyPacket(keyPacket, signature, date = new Date()) {
|
function isValidSigningKeyPacket(keyPacket, signature, date=new Date()) {
|
||||||
|
const normDate = util.normalizeDate(date);
|
||||||
return keyPacket.algorithm !== enums.read(enums.publicKey, enums.publicKey.rsa_encrypt) &&
|
return keyPacket.algorithm !== enums.read(enums.publicKey, enums.publicKey.rsa_encrypt) &&
|
||||||
keyPacket.algorithm !== enums.read(enums.publicKey, enums.publicKey.elgamal) &&
|
keyPacket.algorithm !== enums.read(enums.publicKey, enums.publicKey.elgamal) &&
|
||||||
keyPacket.algorithm !== enums.read(enums.publicKey, enums.publicKey.ecdh) &&
|
keyPacket.algorithm !== enums.read(enums.publicKey, enums.publicKey.ecdh) &&
|
||||||
(!signature.keyFlags ||
|
(!signature.keyFlags ||
|
||||||
(signature.keyFlags[0] & enums.keyFlags.sign_data) !== 0) &&
|
(signature.keyFlags[0] & enums.keyFlags.sign_data) !== 0) &&
|
||||||
(!signature.isExpired(date) &&
|
(!signature.isExpired(normDate) &&
|
||||||
// check expiration time of V3 key packet
|
(normDate === null || (keyPacket.created <= normDate && normDate < getExpirationTime(keyPacket, signature, Infinity))));
|
||||||
!(keyPacket.version === 3 && keyPacket.expirationTimeV3 !== 0 &&
|
|
||||||
+date > (keyPacket.created.getTime() + keyPacket.expirationTimeV3*24*3600*1000)) &&
|
|
||||||
// check expiration time of V4 key packet
|
|
||||||
!(keyPacket.version === 4 && signature.keyNeverExpires === false &&
|
|
||||||
+date > (keyPacket.created.getTime() + signature.keyExpirationTime*1000)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -361,7 +353,7 @@ function isValidSigningKeyPacket(keyPacket, signature, date = new Date()) {
|
||||||
* @param {Date} date optional
|
* @param {Date} date optional
|
||||||
* @returns {(module:packet/public_subkey|module:packet/secret_subkey|module:packet/secret_key|module:packet/public_key|null)} key packet or null if no encryption key has been found
|
* @returns {(module:packet/public_subkey|module:packet/secret_subkey|module:packet/secret_key|module:packet/public_key|null)} key packet or null if no encryption key has been found
|
||||||
*/
|
*/
|
||||||
Key.prototype.getEncryptionKeyPacket = function(keyId, date = new Date()) {
|
Key.prototype.getEncryptionKeyPacket = function(keyId, date=new Date()) {
|
||||||
// V4: by convention subkeys are preferred for encryption service
|
// V4: by convention subkeys are preferred for encryption service
|
||||||
// V3: keys MUST NOT have subkeys
|
// V3: keys MUST NOT have subkeys
|
||||||
if (this.subKeys) {
|
if (this.subKeys) {
|
||||||
|
@ -376,7 +368,7 @@ Key.prototype.getEncryptionKeyPacket = function(keyId, date = new Date()) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// if no valid subkey for encryption, evaluate primary key
|
// if no valid subkey for encryption, evaluate primary key
|
||||||
const primaryUser = this.getPrimaryUser();
|
const primaryUser = this.getPrimaryUser(date);
|
||||||
if (primaryUser && (!keyId || this.primaryKey.getKeyId().equals(keyId)) &&
|
if (primaryUser && (!keyId || this.primaryKey.getKeyId().equals(keyId)) &&
|
||||||
isValidEncryptionKeyPacket(this.primaryKey, primaryUser.selfCertificate, date)) {
|
isValidEncryptionKeyPacket(this.primaryKey, primaryUser.selfCertificate, date)) {
|
||||||
return this.primaryKey;
|
return this.primaryKey;
|
||||||
|
@ -449,9 +441,10 @@ Key.prototype.decryptKeyPacket = function(keyIds, passphrase) {
|
||||||
/**
|
/**
|
||||||
* Verify primary key. Checks for revocation signatures, expiration time
|
* Verify primary key. Checks for revocation signatures, expiration time
|
||||||
* and valid self signature
|
* and valid self signature
|
||||||
|
* @param {Date} date (optional) use the given date for verification instead of the current time
|
||||||
* @return {module:enums.keyStatus} The status of the primary key
|
* @return {module:enums.keyStatus} The status of the primary key
|
||||||
*/
|
*/
|
||||||
Key.prototype.verifyPrimaryKey = async function() {
|
Key.prototype.verifyPrimaryKey = async function(date=new Date()) {
|
||||||
// TODO clarify OpenPGP's behavior given an expired revocation signature
|
// TODO clarify OpenPGP's behavior given an expired revocation signature
|
||||||
// check revocation signature
|
// check revocation signature
|
||||||
if (this.revocationSignature && !this.revocationSignature.isExpired() &&
|
if (this.revocationSignature && !this.revocationSignature.isExpired() &&
|
||||||
|
@ -460,8 +453,8 @@ Key.prototype.verifyPrimaryKey = async function() {
|
||||||
return enums.keyStatus.revoked;
|
return enums.keyStatus.revoked;
|
||||||
}
|
}
|
||||||
// check V3 expiration time
|
// check V3 expiration time
|
||||||
if (this.primaryKey.version === 3 && this.primaryKey.expirationTimeV3 !== 0 &&
|
if (date !== null && this.primaryKey.version === 3 && this.primaryKey.expirationTimeV3 !== 0 &&
|
||||||
Date.now() > (this.primaryKey.created.getTime() + this.primaryKey.expirationTimeV3*24*3600*1000)) {
|
util.normalizeDate(date) > (this.primaryKey.created.getTime() + this.primaryKey.expirationTimeV3*24*3600*1000)) {
|
||||||
return enums.keyStatus.expired;
|
return enums.keyStatus.expired;
|
||||||
}
|
}
|
||||||
// check for at least one self signature. Self signature of user ID not mandatory
|
// check for at least one self signature. Self signature of user ID not mandatory
|
||||||
|
@ -471,13 +464,13 @@ Key.prototype.verifyPrimaryKey = async function() {
|
||||||
}
|
}
|
||||||
// check for valid self signature
|
// check for valid self signature
|
||||||
await this.verifyPrimaryUser();
|
await this.verifyPrimaryUser();
|
||||||
const primaryUser = this.getPrimaryUser();
|
const primaryUser = this.getPrimaryUser(date);
|
||||||
if (!primaryUser) {
|
if (!primaryUser) {
|
||||||
return enums.keyStatus.invalid;
|
return enums.keyStatus.invalid;
|
||||||
}
|
}
|
||||||
// check V4 expiration time
|
// check V4 expiration time
|
||||||
if (this.primaryKey.version === 4 && primaryUser.selfCertificate.keyNeverExpires === false &&
|
if (date !== null && this.primaryKey.version === 4 && primaryUser.selfCertificate.keyNeverExpires === false &&
|
||||||
Date.now() > (this.primaryKey.created.getTime() + primaryUser.selfCertificate.keyExpirationTime*1000)) {
|
util.normalizeDate(date) > (this.primaryKey.created.getTime() + primaryUser.selfCertificate.keyExpirationTime*1000)) {
|
||||||
return enums.keyStatus.expired;
|
return enums.keyStatus.expired;
|
||||||
}
|
}
|
||||||
return enums.keyStatus.valid;
|
return enums.keyStatus.valid;
|
||||||
|
@ -501,7 +494,7 @@ Key.prototype.getExpirationTime = function() {
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
function getExpirationTime(keyPacket, selfCertificate) {
|
function getExpirationTime(keyPacket, selfCertificate, defaultValue=null) {
|
||||||
// check V3 expiration time
|
// check V3 expiration time
|
||||||
if (keyPacket.version === 3 && keyPacket.expirationTimeV3 !== 0) {
|
if (keyPacket.version === 3 && keyPacket.expirationTimeV3 !== 0) {
|
||||||
return new Date(keyPacket.created.getTime() + keyPacket.expirationTimeV3*24*3600*1000);
|
return new Date(keyPacket.created.getTime() + keyPacket.expirationTimeV3*24*3600*1000);
|
||||||
|
@ -510,16 +503,17 @@ function getExpirationTime(keyPacket, selfCertificate) {
|
||||||
if (keyPacket.version === 4 && selfCertificate.keyNeverExpires === false) {
|
if (keyPacket.version === 4 && selfCertificate.keyNeverExpires === false) {
|
||||||
return new Date(keyPacket.created.getTime() + selfCertificate.keyExpirationTime*1000);
|
return new Date(keyPacket.created.getTime() + selfCertificate.keyExpirationTime*1000);
|
||||||
}
|
}
|
||||||
return null;
|
return defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns primary user and most significant (latest valid) self signature
|
* Returns primary user and most significant (latest valid) self signature
|
||||||
* - if multiple users are marked as primary users returns the one with the latest self signature
|
* - if multiple users are marked as primary users returns the one with the latest self signature
|
||||||
* - if no primary user is found returns the user with the latest self signature
|
* - if no primary user is found returns the user with the latest self signature
|
||||||
|
* @param {Date} date use the given date for verification instead of the current time
|
||||||
* @return {{user: Array<module:packet/User>, selfCertificate: Array<module:packet/signature>}|null} The primary user and the self signature
|
* @return {{user: Array<module:packet/User>, selfCertificate: Array<module:packet/signature>}|null} The primary user and the self signature
|
||||||
*/
|
*/
|
||||||
Key.prototype.getPrimaryUser = function() {
|
Key.prototype.getPrimaryUser = function(date=new Date()) {
|
||||||
let primaryUsers = [];
|
let primaryUsers = [];
|
||||||
for (let i = 0; i < this.users.length; i++) {
|
for (let i = 0; i < this.users.length; i++) {
|
||||||
// here we only check the primary user ID, ignoring the primary user attribute
|
// here we only check the primary user ID, ignoring the primary user attribute
|
||||||
|
@ -530,7 +524,7 @@ Key.prototype.getPrimaryUser = function() {
|
||||||
// only consider already validated certificates
|
// only consider already validated certificates
|
||||||
if (!this.users[i].selfCertifications[j].verified ||
|
if (!this.users[i].selfCertifications[j].verified ||
|
||||||
this.users[i].selfCertifications[j].revoked ||
|
this.users[i].selfCertifications[j].revoked ||
|
||||||
(this.users[i].selfCertifications[j].isExpired())) {
|
this.users[i].selfCertifications[j].isExpired(date)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
primaryUsers.push({ index: i, user: this.users[i], selfCertificate: this.users[i].selfCertifications[j] });
|
primaryUsers.push({ index: i, user: this.users[i], selfCertificate: this.users[i].selfCertifications[j] });
|
||||||
|
@ -683,6 +677,7 @@ Key.prototype.signAllUsers = async function(privateKeys) {
|
||||||
* - if no arguments are given, verifies the self certificates;
|
* - if no arguments are given, verifies the self certificates;
|
||||||
* - otherwise, verifies all certificates signed with given keys.
|
* - otherwise, verifies all certificates signed with given keys.
|
||||||
* @param {Array<module:key~Key>} keys array of keys to verify certificate signatures
|
* @param {Array<module:key~Key>} keys array of keys to verify certificate signatures
|
||||||
|
* @param {Date} date (optional) use the given date for verification instead of the current time
|
||||||
* @return {Array<({keyid: module:type/keyid, valid: Boolean})>} list of signer's keyid and validity of signature
|
* @return {Array<({keyid: module:type/keyid, valid: Boolean})>} list of signer's keyid and validity of signature
|
||||||
*/
|
*/
|
||||||
Key.prototype.verifyPrimaryUser = async function(keys) {
|
Key.prototype.verifyPrimaryUser = async function(keys) {
|
||||||
|
@ -839,16 +834,17 @@ User.prototype.sign = async function(primaryKey, privateKeys) {
|
||||||
* @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
|
||||||
* @param {module:packet/signature} certificate A certificate of this user
|
* @param {module:packet/signature} certificate A certificate of this user
|
||||||
* @param {Array<module:key~Key>} keys array of keys to verify certificate signatures
|
* @param {Array<module:key~Key>} keys array of keys to verify certificate signatures
|
||||||
|
* @param {Date} date use the given date for verification instead of the current time
|
||||||
* @return {module:enums.keyStatus} status of the certificate
|
* @return {module:enums.keyStatus} status of the certificate
|
||||||
*/
|
*/
|
||||||
User.prototype.verifyCertificate = async function(primaryKey, certificate, keys) {
|
User.prototype.verifyCertificate = async function(primaryKey, certificate, keys, date=new Date()) {
|
||||||
const that = this;
|
const that = this;
|
||||||
const keyid = certificate.issuerKeyId;
|
const keyid = certificate.issuerKeyId;
|
||||||
const dataToVerify = { userid: this.userId || this.userAttribute, key: primaryKey };
|
const dataToVerify = { userid: this.userId || this.userAttribute, key: primaryKey };
|
||||||
const results = await Promise.all(keys.map(async function(key) {
|
const results = await Promise.all(keys.map(async function(key) {
|
||||||
if (!key.getKeyIds().some(id => id.equals(keyid))) { return; }
|
if (!key.getKeyIds().some(id => id.equals(keyid))) { return; }
|
||||||
await key.verifyPrimaryUser();
|
await key.verifyPrimaryUser();
|
||||||
const keyPacket = key.getSigningKeyPacket(keyid);
|
const keyPacket = key.getSigningKeyPacket(keyid, date);
|
||||||
if (certificate.revoked || await that.isRevoked(primaryKey, certificate, keyPacket)) {
|
if (certificate.revoked || await that.isRevoked(primaryKey, certificate, keyPacket)) {
|
||||||
return enums.keyStatus.revoked;
|
return enums.keyStatus.revoked;
|
||||||
}
|
}
|
||||||
|
@ -957,14 +953,15 @@ SubKey.prototype.toPacketlist = function() {
|
||||||
/**
|
/**
|
||||||
* Returns true if the subkey can be used for encryption
|
* Returns true if the subkey can be used for encryption
|
||||||
* @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
|
||||||
|
* @param {Date} date use the given date for verification instead of the current time
|
||||||
* @return {Boolean}
|
* @return {Boolean}
|
||||||
*/
|
*/
|
||||||
SubKey.prototype.isValidEncryptionKey = async function(primaryKey) {
|
SubKey.prototype.isValidEncryptionKey = async function(primaryKey, date=new Date()) {
|
||||||
if (await this.verify(primaryKey) !== enums.keyStatus.valid) {
|
if (await this.verify(primaryKey) !== enums.keyStatus.valid) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
for (let i = 0; i < this.bindingSignatures.length; i++) {
|
for (let i = 0; i < this.bindingSignatures.length; i++) {
|
||||||
if (isValidEncryptionKeyPacket(this.subKey, this.bindingSignatures[i])) {
|
if (isValidEncryptionKeyPacket(this.subKey, this.bindingSignatures[i], date)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -974,14 +971,15 @@ SubKey.prototype.isValidEncryptionKey = async function(primaryKey) {
|
||||||
/**
|
/**
|
||||||
* Returns true if the subkey can be used for signing of data
|
* Returns true if the subkey can be used for signing of data
|
||||||
* @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
|
||||||
|
* @param {Date} date use the given date for verification instead of the current time
|
||||||
* @return {Boolean}
|
* @return {Boolean}
|
||||||
*/
|
*/
|
||||||
SubKey.prototype.isValidSigningKey = async function(primaryKey) {
|
SubKey.prototype.isValidSigningKey = async function(primaryKey, date=new Date()) {
|
||||||
if (await this.verify(primaryKey) !== enums.keyStatus.valid) {
|
if (await this.verify(primaryKey) !== enums.keyStatus.valid) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
for (let i = 0; i < this.bindingSignatures.length; i++) {
|
for (let i = 0; i < this.bindingSignatures.length; i++) {
|
||||||
if (isValidSigningKeyPacket(this.subKey, this.bindingSignatures[i])) {
|
if (isValidSigningKeyPacket(this.subKey, this.bindingSignatures[i], date)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -992,9 +990,10 @@ SubKey.prototype.isValidSigningKey = async function(primaryKey) {
|
||||||
* Verify subkey. Checks for revocation signatures, expiration time
|
* Verify subkey. Checks for revocation signatures, expiration time
|
||||||
* and valid binding signature
|
* and valid binding 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
|
||||||
|
* @param {Date} date use the given date for verification instead of the current time
|
||||||
* @return {module:enums.keyStatus} The status of the subkey
|
* @return {module:enums.keyStatus} The status of the subkey
|
||||||
*/
|
*/
|
||||||
SubKey.prototype.verify = async function(primaryKey) {
|
SubKey.prototype.verify = async function(primaryKey, date=new Date()) {
|
||||||
const that = this;
|
const that = this;
|
||||||
// TODO clarify OpenPGP's behavior given an expired revocation signature
|
// TODO clarify OpenPGP's behavior given an expired revocation signature
|
||||||
// check subkey revocation signature
|
// check subkey revocation signature
|
||||||
|
@ -1004,15 +1003,15 @@ SubKey.prototype.verify = async function(primaryKey) {
|
||||||
return enums.keyStatus.revoked;
|
return enums.keyStatus.revoked;
|
||||||
}
|
}
|
||||||
// check V3 expiration time
|
// check V3 expiration time
|
||||||
if (this.subKey.version === 3 && this.subKey.expirationTimeV3 !== 0 &&
|
if (date !== null && this.subKey.version === 3 && this.subKey.expirationTimeV3 !== 0 &&
|
||||||
Date.now() > (this.subKey.created.getTime() + this.subKey.expirationTimeV3*24*3600*1000)) {
|
util.normalizeDate(date) > (this.subKey.created.getTime() + this.subKey.expirationTimeV3*24*3600*1000)) {
|
||||||
return enums.keyStatus.expired;
|
return enums.keyStatus.expired;
|
||||||
}
|
}
|
||||||
// check subkey binding signatures (at least one valid binding sig needed)
|
// check subkey binding signatures (at least one valid binding sig needed)
|
||||||
// TODO replace when Promise.some or Promise.any are implemented
|
// TODO replace when Promise.some or Promise.any are implemented
|
||||||
const results = [enums.keyStatus.invalid].concat(await Promise.all(this.bindingSignatures.map(async function(bindingSignature) {
|
const results = [enums.keyStatus.invalid].concat(await Promise.all(this.bindingSignatures.map(async function(bindingSignature) {
|
||||||
// check binding signature is not expired
|
// check binding signature is not expired
|
||||||
if (bindingSignature.isExpired()) {
|
if (bindingSignature.isExpired(date)) {
|
||||||
return enums.keyStatus.expired; // last expired binding signature
|
return enums.keyStatus.expired; // last expired binding signature
|
||||||
}
|
}
|
||||||
// check binding signature can verify
|
// check binding signature can verify
|
||||||
|
@ -1022,8 +1021,8 @@ SubKey.prototype.verify = async function(primaryKey) {
|
||||||
}
|
}
|
||||||
// check V4 expiration time
|
// check V4 expiration time
|
||||||
if (that.subKey.version === 4) {
|
if (that.subKey.version === 4) {
|
||||||
if (bindingSignature.keyNeverExpires === false &&
|
if (date !== null && bindingSignature.keyNeverExpires === false &&
|
||||||
Date.now() > (that.subKey.created.getTime() + bindingSignature.keyExpirationTime*1000)) {
|
util.normalizeDate(date) > (that.subKey.created.getTime() + bindingSignature.keyExpirationTime*1000)) {
|
||||||
return enums.keyStatus.expired; // last V4 expired binding signature
|
return enums.keyStatus.expired; // last V4 expired binding signature
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1291,7 +1290,7 @@ async function wrapKeyObject(secretKeyPacket, secretSubkeyPacket, options) {
|
||||||
const dataToSign = {};
|
const dataToSign = {};
|
||||||
dataToSign.userid = userIdPacket;
|
dataToSign.userid = userIdPacket;
|
||||||
dataToSign.key = secretKeyPacket;
|
dataToSign.key = secretKeyPacket;
|
||||||
const signaturePacket = new packet.Signature();
|
const signaturePacket = new packet.Signature(new Date(1000));
|
||||||
signaturePacket.signatureType = enums.signature.cert_generic;
|
signaturePacket.signatureType = enums.signature.cert_generic;
|
||||||
signaturePacket.publicKeyAlgorithm = options.keyType;
|
signaturePacket.publicKeyAlgorithm = options.keyType;
|
||||||
signaturePacket.hashAlgorithm = getPreferredHashAlgo(secretKeyPacket);
|
signaturePacket.hashAlgorithm = getPreferredHashAlgo(secretKeyPacket);
|
||||||
|
@ -1376,7 +1375,8 @@ export function getPreferredHashAlgo(key) {
|
||||||
hash_algo = crypto.hash.getHashByteLength(hash_algo) <= crypto.hash.getHashByteLength(pref_algo) ?
|
hash_algo = crypto.hash.getHashByteLength(hash_algo) <= crypto.hash.getHashByteLength(pref_algo) ?
|
||||||
pref_algo : hash_algo;
|
pref_algo : hash_algo;
|
||||||
}
|
}
|
||||||
key = key.getSigningKeyPacket();
|
// disable expiration checks
|
||||||
|
key = key.getSigningKeyPacket(undefined, null);
|
||||||
}
|
}
|
||||||
switch (Object.getPrototypeOf(key)) {
|
switch (Object.getPrototypeOf(key)) {
|
||||||
case packet.SecretKey.prototype:
|
case packet.SecretKey.prototype:
|
||||||
|
|
|
@ -239,10 +239,10 @@ Message.prototype.getText = function() {
|
||||||
* @param {Array<String>} passwords (optional) password(s) for message encryption
|
* @param {Array<String>} passwords (optional) password(s) for message encryption
|
||||||
* @param {Object} sessionKey (optional) session key in the form: { data:Uint8Array, algorithm:String }
|
* @param {Object} sessionKey (optional) session key in the form: { data:Uint8Array, algorithm:String }
|
||||||
* @param {Boolean} wildcard (optional) use a key ID of 0 instead of the public key IDs
|
* @param {Boolean} wildcard (optional) use a key ID of 0 instead of the public key IDs
|
||||||
* @param {Date} date (optional) the current date of encryption
|
* @param {Date} date (optional) override the creation date of the literal package
|
||||||
* @return {Message} new message with encrypted content
|
* @return {Message} new message with encrypted content
|
||||||
*/
|
*/
|
||||||
Message.prototype.encrypt = function(keys, passwords, sessionKey, wildcard = false, date = new Date()) {
|
Message.prototype.encrypt = function(keys, passwords, sessionKey, wildcard=false, date=new Date()) {
|
||||||
let symAlgo;
|
let symAlgo;
|
||||||
let msg;
|
let msg;
|
||||||
let symEncryptedPacket;
|
let symEncryptedPacket;
|
||||||
|
@ -297,10 +297,10 @@ Message.prototype.encrypt = function(keys, passwords, sessionKey, wildcard = fal
|
||||||
* @param {Array<Key>} publicKeys (optional) public key(s) for message encryption
|
* @param {Array<Key>} publicKeys (optional) public key(s) for message encryption
|
||||||
* @param {Array<String>} passwords (optional) for message encryption
|
* @param {Array<String>} passwords (optional) for message encryption
|
||||||
* @param {Boolean} wildcard (optional) use a key ID of 0 instead of the public key IDs
|
* @param {Boolean} wildcard (optional) use a key ID of 0 instead of the public key IDs
|
||||||
* @param {Date} date (optional) the date used to encrypt
|
* @param {Date} date (optional) override the creation date signature
|
||||||
* @return {Message} new message with encrypted content
|
* @return {Message} new message with encrypted content
|
||||||
*/
|
*/
|
||||||
export function encryptSessionKey(sessionKey, symAlgo, publicKeys, passwords, wildcard=false, date = new Date()) {
|
export function encryptSessionKey(sessionKey, symAlgo, publicKeys, passwords, wildcard=false, date=new Date()) {
|
||||||
const packetlist = new packet.List();
|
const packetlist = new packet.List();
|
||||||
|
|
||||||
return Promise.resolve().then(async () => {
|
return Promise.resolve().then(async () => {
|
||||||
|
@ -362,10 +362,10 @@ export function encryptSessionKey(sessionKey, symAlgo, publicKeys, passwords, wi
|
||||||
* Sign the message (the literal data packet of the message)
|
* Sign the message (the literal data packet of the message)
|
||||||
* @param {Array<module:key~Key>} privateKeys private keys with decrypted secret key data for signing
|
* @param {Array<module:key~Key>} privateKeys private keys with decrypted secret key data for signing
|
||||||
* @param {Signature} signature (optional) any existing detached signature to add to the message
|
* @param {Signature} signature (optional) any existing detached signature to add to the message
|
||||||
* @param {Date} date} (optional) the creation date of the signature used for creating a new signature
|
* @param {Date} date} (optional) override the creation time of the signature
|
||||||
* @return {module:message~Message} new message with signed content
|
* @return {module:message~Message} new message with signed content
|
||||||
*/
|
*/
|
||||||
Message.prototype.sign = async function(privateKeys=[], signature=null, date = new Date()) {
|
Message.prototype.sign = async function(privateKeys=[], signature=null, date=new Date()) {
|
||||||
const packetlist = new packet.List();
|
const packetlist = new packet.List();
|
||||||
|
|
||||||
const literalDataPacket = this.packets.findPacket(enums.packet.literal);
|
const literalDataPacket = this.packets.findPacket(enums.packet.literal);
|
||||||
|
@ -400,7 +400,7 @@ Message.prototype.sign = async function(privateKeys=[], signature=null, date = n
|
||||||
throw new Error('Need private key for signing');
|
throw new Error('Need private key for signing');
|
||||||
}
|
}
|
||||||
await privateKey.verifyPrimaryUser();
|
await privateKey.verifyPrimaryUser();
|
||||||
const signingKeyPacket = privateKey.getSigningKeyPacket(null, date);
|
const signingKeyPacket = privateKey.getSigningKeyPacket(undefined, date);
|
||||||
if (!signingKeyPacket) {
|
if (!signingKeyPacket) {
|
||||||
throw new Error('Could not find valid key packet for signing in key ' +
|
throw new Error('Could not find valid key packet for signing in key ' +
|
||||||
privateKey.primaryKey.getKeyId().toHex());
|
privateKey.primaryKey.getKeyId().toHex());
|
||||||
|
@ -448,10 +448,10 @@ Message.prototype.compress = function(compression) {
|
||||||
* Create a detached signature for the message (the literal data packet of the message)
|
* Create a detached signature for the message (the literal data packet of the message)
|
||||||
* @param {Array<module:key~Key>} privateKeys private keys with decrypted secret key data for signing
|
* @param {Array<module:key~Key>} privateKeys private keys with decrypted secret key data for signing
|
||||||
* @param {Signature} signature (optional) any existing detached signature
|
* @param {Signature} signature (optional) any existing detached signature
|
||||||
* @param {Date} date (optional) the creation date to sign the message with
|
* @param {Date} date (optional) override the creation time of the signature
|
||||||
* @return {module:signature~Signature} new detached signature of message content
|
* @return {module:signature~Signature} new detached signature of message content
|
||||||
*/
|
*/
|
||||||
Message.prototype.signDetached = async function(privateKeys=[], signature=null, date = new Date()) {
|
Message.prototype.signDetached = async function(privateKeys=[], signature=null, date=new Date()) {
|
||||||
const packetlist = new packet.List();
|
const packetlist = new packet.List();
|
||||||
|
|
||||||
const literalDataPacket = this.packets.findPacket(enums.packet.literal);
|
const literalDataPacket = this.packets.findPacket(enums.packet.literal);
|
||||||
|
@ -466,10 +466,10 @@ Message.prototype.signDetached = async function(privateKeys=[], signature=null,
|
||||||
* @param {module:packet/literal} literalDataPacket the literal data packet to sign
|
* @param {module:packet/literal} literalDataPacket the literal data packet to sign
|
||||||
* @param {Array<module:key~Key>} privateKeys private keys with decrypted secret key data for signing
|
* @param {Array<module:key~Key>} privateKeys private keys with decrypted secret key data for signing
|
||||||
* @param {Signature} signature (optional) any existing detached signature to append
|
* @param {Signature} signature (optional) any existing detached signature to append
|
||||||
* @param {Date} date (optional) the creation date to sign the message with
|
* @param {Date} date (optional) override the creationtime of the signature
|
||||||
* @return {module:packet/packetlist} list of signature packets
|
* @return {module:packet/packetlist} list of signature packets
|
||||||
*/
|
*/
|
||||||
export async function createSignaturePackets(literalDataPacket, privateKeys, signature=null, date = new Date()) {
|
export async function createSignaturePackets(literalDataPacket, privateKeys, signature=null, date=new Date()) {
|
||||||
const packetlist = new packet.List();
|
const packetlist = new packet.List();
|
||||||
|
|
||||||
const literalFormat = enums.write(enums.literal, literalDataPacket.format);
|
const literalFormat = enums.write(enums.literal, literalDataPacket.format);
|
||||||
|
@ -481,7 +481,7 @@ export async function createSignaturePackets(literalDataPacket, privateKeys, sig
|
||||||
throw new Error('Need private key for signing');
|
throw new Error('Need private key for signing');
|
||||||
}
|
}
|
||||||
await privateKey.verifyPrimaryUser();
|
await privateKey.verifyPrimaryUser();
|
||||||
const signingKeyPacket = privateKey.getSigningKeyPacket(null, date);
|
const signingKeyPacket = privateKey.getSigningKeyPacket(undefined, date);
|
||||||
if (!signingKeyPacket) {
|
if (!signingKeyPacket) {
|
||||||
throw new Error('Could not find valid key packet for signing in key ' + privateKey.primaryKey.getKeyId().toHex());
|
throw new Error('Could not find valid key packet for signing in key ' + privateKey.primaryKey.getKeyId().toHex());
|
||||||
}
|
}
|
||||||
|
@ -508,10 +508,10 @@ export async function createSignaturePackets(literalDataPacket, privateKeys, sig
|
||||||
/**
|
/**
|
||||||
* Verify message signatures
|
* Verify message signatures
|
||||||
* @param {Array<module:key~Key>} keys array of keys to verify signatures
|
* @param {Array<module:key~Key>} keys array of keys to verify signatures
|
||||||
* @param {Date} date the current date
|
* @param {Date} date (optional) Verify the signature against the given date, i.e. check signature creation time < date < expiration time
|
||||||
* @return {Array<({keyid: module:type/keyid, valid: Boolean})>} list of signer's keyid and validity of signature
|
* @return {Array<({keyid: module:type/keyid, valid: Boolean})>} list of signer's keyid and validity of signature
|
||||||
*/
|
*/
|
||||||
Message.prototype.verify = function(keys, date = new Date()) {
|
Message.prototype.verify = function(keys, date=new Date()) {
|
||||||
const msg = this.unwrapCompressed();
|
const msg = this.unwrapCompressed();
|
||||||
const literalDataList = msg.packets.filterByTag(enums.packet.literal);
|
const literalDataList = msg.packets.filterByTag(enums.packet.literal);
|
||||||
if (literalDataList.length !== 1) {
|
if (literalDataList.length !== 1) {
|
||||||
|
@ -525,10 +525,10 @@ Message.prototype.verify = function(keys, date = new Date()) {
|
||||||
* Verify detached message signature
|
* Verify detached message signature
|
||||||
* @param {Array<module:key~Key>} keys array of keys to verify signatures
|
* @param {Array<module:key~Key>} keys array of keys to verify signatures
|
||||||
* @param {Signature} signature
|
* @param {Signature} signature
|
||||||
* @param {Date} date the current date
|
* @param {Date} date Verify the signature against the given date, i.e. check signature creation time < date < expiration time
|
||||||
* @return {Array<({keyid: module:type/keyid, valid: Boolean})>} list of signer's keyid and validity of signature
|
* @return {Array<({keyid: module:type/keyid, valid: Boolean})>} list of signer's keyid and validity of signature
|
||||||
*/
|
*/
|
||||||
Message.prototype.verifyDetached = function(signature, keys, date = new Date()) {
|
Message.prototype.verifyDetached = function(signature, keys, date=new Date()) {
|
||||||
const msg = this.unwrapCompressed();
|
const msg = this.unwrapCompressed();
|
||||||
const literalDataList = msg.packets.filterByTag(enums.packet.literal);
|
const literalDataList = msg.packets.filterByTag(enums.packet.literal);
|
||||||
if (literalDataList.length !== 1) {
|
if (literalDataList.length !== 1) {
|
||||||
|
@ -543,10 +543,10 @@ Message.prototype.verifyDetached = function(signature, keys, date = new Date())
|
||||||
* @param {Array<module:packet/signature>} signatureList array of signature packets
|
* @param {Array<module:packet/signature>} signatureList array of signature packets
|
||||||
* @param {Array<module:packet/literal>} literalDataList array of literal data packets
|
* @param {Array<module:packet/literal>} literalDataList array of literal data packets
|
||||||
* @param {Array<module:key~Key>} keys array of keys to verify signatures
|
* @param {Array<module:key~Key>} keys array of keys to verify signatures
|
||||||
* @param {Date} date the current date
|
* @param {Date} date Verify the signature against the given date, i.e. check signature creation time < date < expiration time
|
||||||
* @return {Array<({keyid: module:type/keyid, valid: Boolean})>} list of signer's keyid and validity of signature
|
* @return {Array<({keyid: module:type/keyid, valid: Boolean})>} list of signer's keyid and validity of signature
|
||||||
*/
|
*/
|
||||||
export async function createVerificationObjects(signatureList, literalDataList, keys, date = new Date()) {
|
export async function createVerificationObjects(signatureList, literalDataList, keys, date=new Date()) {
|
||||||
return Promise.all(signatureList.map(async function(signature) {
|
return Promise.all(signatureList.map(async function(signature) {
|
||||||
let keyPacket = null;
|
let keyPacket = null;
|
||||||
await Promise.all(keys.map(async function(key) {
|
await Promise.all(keys.map(async function(key) {
|
||||||
|
@ -640,7 +640,7 @@ export function readSignedContent(content, detachedSignature) {
|
||||||
* @return {module:message~Message} new message object
|
* @return {module:message~Message} new message object
|
||||||
* @static
|
* @static
|
||||||
*/
|
*/
|
||||||
export function fromText(text, filename, date = new Date()) {
|
export function fromText(text, filename, date=new Date()) {
|
||||||
const literalDataPacket = new packet.Literal(date);
|
const literalDataPacket = new packet.Literal(date);
|
||||||
// text will be converted to UTF8
|
// text will be converted to UTF8
|
||||||
literalDataPacket.setText(text);
|
literalDataPacket.setText(text);
|
||||||
|
@ -660,7 +660,7 @@ export function fromText(text, filename, date = new Date()) {
|
||||||
* @return {module:message~Message} new message object
|
* @return {module:message~Message} new message object
|
||||||
* @static
|
* @static
|
||||||
*/
|
*/
|
||||||
export function fromBinary(bytes, filename, date = new Date()) {
|
export function fromBinary(bytes, filename, date=new Date()) {
|
||||||
if (!util.isUint8Array(bytes)) {
|
if (!util.isUint8Array(bytes)) {
|
||||||
throw new Error('Data must be in the form of a Uint8Array');
|
throw new Error('Data must be in the form of a Uint8Array');
|
||||||
}
|
}
|
||||||
|
|
|
@ -202,13 +202,13 @@ export function decryptKey({ privateKey, passphrase }) {
|
||||||
* @param {Signature} signature (optional) a detached signature to add to the encrypted message
|
* @param {Signature} signature (optional) a detached signature to add to the encrypted message
|
||||||
* @param {Boolean} returnSessionKey (optional) if the unencrypted session key should be added to returned object
|
* @param {Boolean} returnSessionKey (optional) if the unencrypted session key should be added to returned object
|
||||||
* @param {Boolean} wildcard (optional) use a key ID of 0 instead of the public key IDs
|
* @param {Boolean} wildcard (optional) use a key ID of 0 instead of the public key IDs
|
||||||
* @param {Date} date (optional) the date used to encrypt and sign the message
|
* @param {Date} date (optional) override the creation date of the message and the message signature
|
||||||
* @return {Promise<Object>} encrypted (and optionally signed message) in the form:
|
* @return {Promise<Object>} encrypted (and optionally signed message) in the form:
|
||||||
* {data: ASCII armored message if 'armor' is true,
|
* {data: ASCII armored message if 'armor' is true,
|
||||||
* message: full Message object if 'armor' is false, signature: detached signature if 'detached' is true}
|
* message: full Message object if 'armor' is false, signature: detached signature if 'detached' is true}
|
||||||
* @static
|
* @static
|
||||||
*/
|
*/
|
||||||
export function encrypt({ data, publicKeys, privateKeys, passwords, sessionKey, filename, compression = config.compression, armor = true, detached = false, signature = null, returnSessionKey = false, wildcard = false, date = new Date()}) {
|
export function encrypt({ data, publicKeys, privateKeys, passwords, sessionKey, filename, compression=config.compression, armor=true, detached=false, signature=null, returnSessionKey=false, wildcard=false, date=new Date()}) {
|
||||||
checkData(data); publicKeys = toArray(publicKeys); privateKeys = toArray(privateKeys); passwords = toArray(passwords);
|
checkData(data); publicKeys = toArray(publicKeys); privateKeys = toArray(privateKeys); passwords = toArray(passwords);
|
||||||
|
|
||||||
if (!nativeAEAD() && asyncProxy) { // use web worker if web crypto apis are not supported
|
if (!nativeAEAD() && asyncProxy) { // use web worker if web crypto apis are not supported
|
||||||
|
@ -254,7 +254,7 @@ export function encrypt({ data, publicKeys, privateKeys, passwords, sessionKey,
|
||||||
* @param {Key|Array<Key>} publicKeys (optional) array of public keys or single key, to verify signatures
|
* @param {Key|Array<Key>} publicKeys (optional) array of public keys or single key, to verify signatures
|
||||||
* @param {String} format (optional) return data format either as 'utf8' or 'binary'
|
* @param {String} format (optional) return data format either as 'utf8' or 'binary'
|
||||||
* @param {Signature} signature (optional) detached signature for verification
|
* @param {Signature} signature (optional) detached signature for verification
|
||||||
* @param {Date} date (optional) the current date
|
* @param {Date} date (optional) use the given date for verification instead of the current time
|
||||||
* @return {Promise<Object>} decrypted and verified message in the form:
|
* @return {Promise<Object>} decrypted and verified message in the form:
|
||||||
* { data:Uint8Array|String, filename:String, signatures:[{ keyid:String, valid:Boolean }] }
|
* { data:Uint8Array|String, filename:String, signatures:[{ keyid:String, valid:Boolean }] }
|
||||||
* @static
|
* @static
|
||||||
|
@ -293,14 +293,14 @@ export function decrypt({ message, privateKeys, passwords, sessionKeys, publicKe
|
||||||
* @param {Key|Array<Key>} privateKeys array of keys or single key with decrypted secret key data to sign cleartext
|
* @param {Key|Array<Key>} privateKeys array of keys or single key with decrypted secret key data to sign cleartext
|
||||||
* @param {Boolean} armor (optional) if the return value should be ascii armored or the message object
|
* @param {Boolean} armor (optional) if the return value should be ascii armored or the message object
|
||||||
* @param {Boolean} detached (optional) if the return value should contain a detached signature
|
* @param {Boolean} detached (optional) if the return value should contain a detached signature
|
||||||
* @param {Date} date (optional) the creation date used to sign the message
|
* @param {Date} date (optional) override the creation date signature
|
||||||
* @return {Promise<Object>} signed cleartext in the form:
|
* @return {Promise<Object>} signed cleartext in the form:
|
||||||
* {data: ASCII armored message if 'armor' is true,
|
* {data: ASCII armored message if 'armor' is true,
|
||||||
* message: full Message object if 'armor' is false, signature: detached signature if 'detached' is true}
|
* message: full Message object if 'armor' is false, signature: detached signature if 'detached' is true}
|
||||||
* @static
|
* @static
|
||||||
*/
|
*/
|
||||||
export function sign({
|
export function sign({
|
||||||
data, privateKeys, armor=true, detached=false, date = new Date()
|
data, privateKeys, armor=true, detached=false, date=new Date()
|
||||||
}) {
|
}) {
|
||||||
checkData(data);
|
checkData(data);
|
||||||
privateKeys = toArray(privateKeys);
|
privateKeys = toArray(privateKeys);
|
||||||
|
@ -335,12 +335,12 @@ export function sign({
|
||||||
* @param {Key|Array<Key>} publicKeys array of publicKeys or single key, to verify signatures
|
* @param {Key|Array<Key>} publicKeys array of publicKeys or single key, to verify signatures
|
||||||
* @param {CleartextMessage} message cleartext message object with signatures
|
* @param {CleartextMessage} message cleartext message object with signatures
|
||||||
* @param {Signature} signature (optional) detached signature for verification
|
* @param {Signature} signature (optional) detached signature for verification
|
||||||
* @param {Date} date
|
* @param {Date} date (optional) use the given date for verification instead of the current time
|
||||||
* @return {Promise<Object>} cleartext with status of verified signatures in the form of:
|
* @return {Promise<Object>} cleartext with status of verified signatures in the form of:
|
||||||
* { data:String, signatures: [{ keyid:String, valid:Boolean }] }
|
* { data:String, signatures: [{ keyid:String, valid:Boolean }] }
|
||||||
* @static
|
* @static
|
||||||
*/
|
*/
|
||||||
export function verify({ message, publicKeys, signature=null, date = new Date() }) {
|
export function verify({ message, publicKeys, signature=null, date=new Date() }) {
|
||||||
checkCleartextOrMessage(message);
|
checkCleartextOrMessage(message);
|
||||||
publicKeys = toArray(publicKeys);
|
publicKeys = toArray(publicKeys);
|
||||||
|
|
||||||
|
@ -351,7 +351,7 @@ export function verify({ message, publicKeys, signature=null, date = new Date()
|
||||||
return Promise.resolve().then(async function() {
|
return Promise.resolve().then(async function() {
|
||||||
const result = {};
|
const result = {};
|
||||||
result.data = CleartextMessage.prototype.isPrototypeOf(message) ? message.getText() : message.getLiteralData();
|
result.data = CleartextMessage.prototype.isPrototypeOf(message) ? message.getText() : message.getLiteralData();
|
||||||
result.signatures = signature ? await message.verifyDetached(signature, publicKeys, date) : await message.verify(publicKeys);
|
result.signatures = signature ? await message.verifyDetached(signature, publicKeys, date) : await message.verify(publicKeys, date);
|
||||||
return result;
|
return result;
|
||||||
}).catch(onError.bind(null, 'Error verifying cleartext signed message'));
|
}).catch(onError.bind(null, 'Error verifying cleartext signed message'));
|
||||||
}
|
}
|
||||||
|
@ -500,7 +500,7 @@ function toArray(param) {
|
||||||
* @param {Date} date the creation date of the package
|
* @param {Date} date the creation date of the package
|
||||||
* @return {Message} a message object
|
* @return {Message} a message object
|
||||||
*/
|
*/
|
||||||
function createMessage(data, filename, date = new Date()) {
|
function createMessage(data, filename, date=new Date()) {
|
||||||
let msg;
|
let msg;
|
||||||
if (util.isUint8Array(data)) {
|
if (util.isUint8Array(data)) {
|
||||||
msg = messageLib.fromBinary(data, filename, date);
|
msg = messageLib.fromBinary(data, filename, date);
|
||||||
|
|
|
@ -29,12 +29,13 @@ import util from '../util.js';
|
||||||
import enums from '../enums.js';
|
import enums from '../enums.js';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* @param {Date} date the creation date of the literal package
|
||||||
* @constructor
|
* @constructor
|
||||||
*/
|
*/
|
||||||
export default function Literal(date = new Date()) {
|
export default function Literal(date=new Date()) {
|
||||||
this.tag = enums.packet.literal;
|
this.tag = enums.packet.literal;
|
||||||
this.format = 'utf8'; // default format for literal data packets
|
this.format = 'utf8'; // default format for literal data packets
|
||||||
this.date = date;
|
this.date = util.normalizeDate(date);
|
||||||
this.data = new Uint8Array(0); // literal data representation
|
this.data = new Uint8Array(0); // literal data representation
|
||||||
this.filename = 'msg.txt';
|
this.filename = 'msg.txt';
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,7 +43,7 @@ export default function PublicKey() {
|
||||||
this.version = 4;
|
this.version = 4;
|
||||||
/** Key creation date.
|
/** Key creation date.
|
||||||
* @type {Date} */
|
* @type {Date} */
|
||||||
this.created = new Date();
|
this.created = util.normalizeDate();
|
||||||
/* Algorithm specific params */
|
/* Algorithm specific params */
|
||||||
this.params = [];
|
this.params = [];
|
||||||
// time in days (V3 only)
|
// time in days (V3 only)
|
||||||
|
|
|
@ -40,8 +40,9 @@ import type_keyid from '../type/keyid.js';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @constructor
|
* @constructor
|
||||||
|
* @param {Date} date the creation date of the signature
|
||||||
*/
|
*/
|
||||||
export default function Signature(date = new Date()) {
|
export default function Signature(date=new Date()) {
|
||||||
this.tag = enums.packet.signature;
|
this.tag = enums.packet.signature;
|
||||||
this.version = 4;
|
this.version = 4;
|
||||||
this.signatureType = null;
|
this.signatureType = null;
|
||||||
|
@ -52,7 +53,7 @@ export default function Signature(date = new Date()) {
|
||||||
this.unhashedSubpackets = null;
|
this.unhashedSubpackets = null;
|
||||||
this.signedHashValue = null;
|
this.signedHashValue = null;
|
||||||
|
|
||||||
this.created = date;
|
this.created = util.normalizeDate(date);
|
||||||
this.signatureExpirationTime = null;
|
this.signatureExpirationTime = null;
|
||||||
this.signatureNeverExpires = true;
|
this.signatureNeverExpires = true;
|
||||||
this.exportable = null;
|
this.exportable = null;
|
||||||
|
@ -661,11 +662,14 @@ Signature.prototype.verify = async function (key, data) {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Verifies signature expiration date
|
* Verifies signature expiration date
|
||||||
|
* @param {Date} date (optional) use the given date for verification instead of the current time
|
||||||
* @return {Boolean} true if expired
|
* @return {Boolean} true if expired
|
||||||
*/
|
*/
|
||||||
Signature.prototype.isExpired = function (date = new Date()) {
|
Signature.prototype.isExpired = function (date=new Date()) {
|
||||||
if (!this.signatureNeverExpires) {
|
if (!this.signatureNeverExpires && date !== null) {
|
||||||
return +date > (this.created.getTime() + this.signatureExpirationTime*1000);
|
const expirationTime = this.created.getTime() + this.signatureExpirationTime*1000;
|
||||||
|
const normDate = util.normalizeDate(date);
|
||||||
|
return !(this.created <= normDate && normDate < expirationTime);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
|
|
|
@ -100,17 +100,20 @@ export default {
|
||||||
|
|
||||||
readDate: function (bytes) {
|
readDate: function (bytes) {
|
||||||
const n = this.readNumber(bytes);
|
const n = this.readNumber(bytes);
|
||||||
const d = new Date();
|
const d = new Date(n * 1000);
|
||||||
d.setTime(n * 1000);
|
|
||||||
return d;
|
return d;
|
||||||
},
|
},
|
||||||
|
|
||||||
writeDate: function (time) {
|
writeDate: function (time) {
|
||||||
const numeric = Math.round(time.getTime() / 1000);
|
const numeric = Math.floor(time.getTime() / 1000);
|
||||||
|
|
||||||
return this.writeNumber(numeric, 4);
|
return this.writeNumber(numeric, 4);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
normalizeDate: function (time = Date.now()) {
|
||||||
|
return time === null ? time : new Date(Math.floor(+time / 1000) * 1000);
|
||||||
|
},
|
||||||
|
|
||||||
hexdump: function (str) {
|
hexdump: function (str) {
|
||||||
const r = [];
|
const r = [];
|
||||||
const e = str.length;
|
const e = str.length;
|
||||||
|
|
|
@ -214,38 +214,6 @@ t/ia1kMpSEiOVLlX5dfHZzhR3WNtBqU=
|
||||||
=C0fJ
|
=C0fJ
|
||||||
-----END PGP PRIVATE KEY BLOCK-----`;
|
-----END PGP PRIVATE KEY BLOCK-----`;
|
||||||
|
|
||||||
const pub_key_2000_2008 = `-----BEGIN PGP PUBLIC KEY BLOCK-----
|
|
||||||
|
|
||||||
xo0EOKg3aAEEALLlUS7z92VAc53Xa/y01jYCJz4L6TrLIp7t4dF/U+rB3R050yT7
|
|
||||||
QS8yLVn6LTH9xCPz217zUXtMKZV36qshZHqspz/pZDOD0VDSHVZArENiLMQjKJrR
|
|
||||||
k0S5h3sXUfrJzHfna3KZ6kC2HTmLq3UvEjmMTEUOr53zPwvl7Or7/oFlABEBAAHN
|
|
||||||
E3Rlc3QgPHRlc3RAZXhhbXBsZT7CrQQTAQoAFwUCOKg3aAIbLwMLCQcDFQoIAh4B
|
|
||||||
AheAAAoJEFzwINOIu4R09q8EAIqd3AAl3W0oacbyhLELNKATdR+TwMdQQBl2p8Po
|
|
||||||
8QxVJKw5NQzkq2RZzGqIbqCa2MqBP0ZC89OtYPLRXPyhE5p8iQHFy/zz4nN7Twgr
|
|
||||||
NXKYVQLAIxC7GMDy+FEKRZ0VNnvqYYM1/TPxu/ML6ojhnDPytEmU58kb2GgBx7ix
|
|
||||||
RNsZzo0EOKg3aAEEALOt5AUdDf7fz0DwOkIokGj4zeiFuphsTPwpRAS6c1o9xAzS
|
|
||||||
/C8hLFShhTKL4Z9znYkdaMHuFIs7AJ3P5tKlvG0/cZAl3u286lz0aTtQluHMCKNy
|
|
||||||
UyhuZ0K1VgZOj+HcDKo8jQ+aejcwjHDg02yPvfzrXHBjWAJMjglV4W+YPFYjABEB
|
|
||||||
AAHCwIMEGAEKAA8FAjioN2gFCQ8JnAACGy4AqAkQXPAg04i7hHSdIAQZAQoABgUC
|
|
||||||
OKg3aAAKCRDh8+Pj74TEoHURA/4+mbmGa/ZzTjzfrAxceOMIhfV+wGEk1J5Y1mWP
|
|
||||||
E85w+BvSQB3aFjVL9Wf1kOiB5iYMFRD8kePjYR11rYhhrH/vh0DBRNXYqcOx0FPx
|
|
||||||
Nv2WMedjcYzsmoQqL+7T27tl/Crdq5EMfxFb+FEdDTnx1+RKiiuk3mIJR/Ngl6Yz
|
|
||||||
hmYDs08LA/4+xDre4g+YMHj0zaxDBXUawFz5gH5oPeGCCxG/tQeHiC+vYYJy6RGU
|
|
||||||
cOL+k4Q79lNqjJK6febtvYziffVsSPWWSdkG0xkujS5bDDpikBATAUVeFVwA5hCo
|
|
||||||
5vYp8XWskYHrDXS2ald01abkk8A27pGppcjOS4xxFSqVhw0t/PpJQc6NBDioN2gB
|
|
||||||
BAC30PxDScc8m4HSi0AYRfETd8W9VfA4mBbX4A5G6Gr44kg+z1RAzTtvOnC6Hv7g
|
|
||||||
JBPg4JtqBBZmfyCUoV/gS9SZB63jSrlk1tBs9I5KmGxOOCrLMucsAl3NCLVuMqzL
|
|
||||||
Wm1zyOc6l83j3fRcKe2TrfEDf41Pk1HxlDMBL9rQyqv/uwARAQABwsCDBBgBCgAP
|
|
||||||
BQI4qDdoBQkPCZwAAhsuAKgJEFzwINOIu4R0nSAEGQEKAAYFAjioN2gACgkQJVG+
|
|
||||||
vfNJQKhK6gP+LB5qXTJKCduuqZm7VhFvPeOu4W0pyORo29zZI0owKZnD2ZKZrZhK
|
|
||||||
XZC/1+xKXi8aX4V2ygRth2P1tGFLJRqRiA3C20NVewdI4tQtEqWWSlfNFDz4EsbN
|
|
||||||
spyodQ4jPsKPk2R8pFjAwmpXLizPg2UyPKUJ/2GnNWjleP0UNyUXgD1MkgP+IkxX
|
|
||||||
TYgDF5/LrOlrq7ThWqFqQ/prQCBy7xxNLjpVKLDxGYbXVER6p0pkD6DXlaOgSB3i
|
|
||||||
32dQJnU96l44TlUyaUK/dJP7JPbVUOFq/awSxJiCxFxF6Oarc10qQ+OG5ESdJAjp
|
|
||||||
CMHGCzlbt/ia1kMpSEiOVLlX5dfHZzhR3WNtBqU=
|
|
||||||
=kwK1
|
|
||||||
-----END PGP PUBLIC KEY BLOCK-----`;
|
|
||||||
|
|
||||||
const priv_key_2038_2045 = `-----BEGIN PGP PRIVATE KEY BLOCK-----
|
const priv_key_2038_2045 = `-----BEGIN PGP PRIVATE KEY BLOCK-----
|
||||||
|
|
||||||
xcEYBH/oGU8BBACilkYen6vxr1LAhqWc0HaS+zMkjeND/P9ENePoNRVo3Bq8
|
xcEYBH/oGU8BBACilkYen6vxr1LAhqWc0HaS+zMkjeND/P9ENePoNRVo3Bq8
|
||||||
|
@ -302,37 +270,19 @@ J4wE4f3U5NnR+W6uranaXA2ghVyUsk0lJtnM400nA/45gAq9EBZUSL+DWdYZ
|
||||||
=WLIN
|
=WLIN
|
||||||
-----END PGP PRIVATE KEY BLOCK-----`;
|
-----END PGP PRIVATE KEY BLOCK-----`;
|
||||||
|
|
||||||
const pub_key_2038_2045 = `-----BEGIN PGP PUBLIC KEY BLOCK-----
|
const priv_key_expires_1337 = `-----BEGIN PGP PRIVATE KEY BLOCK-----
|
||||||
|
|
||||||
xo0Ef+gZTwEEAKKWRh6fq/GvUsCGpZzQdpL7MySN40P8/0Q14+g1FWjcGrwotpyr
|
xcA4BAAAAAEBAgCgONc0J8rfO6cJw5YTP38x1ze2tAYIO7EcmRCNYwMkXngb
|
||||||
WlAWK0lVxRrPoPmWTTC2KNJZv+5RKHohbqV1Vi+yMd1OkZiofe8smylhfMHNPqxe
|
0Qdzg34Q5RW0rNiR56VB6KElPUhePRPVklLFiIvHABEBAAEAAf9qabYMzsz/
|
||||||
qG35x5A+Lmkikv9fnbjRZ5pBC0PRqt5xUC2a2Cs3nAn/dKjyWWqZ/yrRABEBAAHN
|
/LeRVZSsTgTljmJTdzd2ambUbpi+vt8MXJsbaWh71vjoLMWSXajaKSPDjVU5
|
||||||
FmV4YW1wbGUgPHRlc3RAZXhhbXBsZT7CrQQTAQoAFwUCf+gZTwIbLwMLCQcDFQoI
|
waFNt9kLqwGGGLqpAQD5ZdMH2XzTq6GU9Ka69iZs6Pbnzwdz59Vc3i8hXlUj
|
||||||
Ah4BAheAAAoJEHSimBgePDrrKzoD/2e/hfwT+K59Ag8j4F5l74/hAGBdm0VhW8Vh
|
zQEApHargCTsrtvSrm+hK/pN51/BHAy9lxCAw9f2etx+AeMA/RGrijkFZtYt
|
||||||
j7PCjrmvV77gDtVyUAguzIMfw/Lf+y3y2J+JE8xGyhU/92bTc5e+D5f0JQ2aqHZk
|
jeWdv/usXL3mgHvEcJv63N5zcEvDX5X4W1bND3Rlc3QxIDxhQGIuY29tPsJ7
|
||||||
/IBREg3dNS7C+fZiNDvc8O4D+0WZH7Yhb3jhr0+DrP0rzs3aVxhlgH8rR7aMZsQ6
|
BBABCAAvBQIAAAABBQMAAAU5BgsJBwgDAgkQzcF99nGrkAkEFQgKAgMWAgEC
|
||||||
uuoM7mVDzo0Ef+gZTwEEAK0pLhDM5pDxWVfuVFssIdbWhClxlN9ZGhjGM27vf5QE
|
GQECGwMCHgEAABAlAfwPehmLZs+gOhOTTaSslqQ50bl/REjmv42Nyr1ZBlQS
|
||||||
0YAluhlv5BTtLU3pYtQYScJksNAFYmENtufWU+c4fv4HHSTGXsW5baw8Ix1vFasr
|
DECl1Qu4QyeXin29uEXWiekMpNlZVsEuc8icCw6ABhIZ
|
||||||
Aa9atZWBZklQVt3Bsxu9+jOYxGJDjkzyhpLOZgJSYFK36l8dATPF5t1eGy405i0n
|
=/7PI
|
||||||
ABEBAAHCwIMEGAEKAA8FAn/oGU8FCQ8JnAACGy4AqAkQdKKYGB48OuudIAQZAQoA
|
-----END PGP PRIVATE KEY BLOCK-----`;
|
||||||
BgUCf+gZTwAKCRDuSkIwkyAjaKEqA/9XS9AgN4nV9on6GsuK1ZpQpqcKAf4SZaF3
|
|
||||||
rDXqpYfM+LDpqaIl8LZKzK7EyW2pVNV9PwnYtMXwQ7A3KAu2audWxSawHNyvgez1
|
|
||||||
Ujl0J7TfKwJyVBrCDjZCJrr+joPU0To95jJivSrnCYC3l1ngoMIZycfaU6FhYwHd
|
|
||||||
2XJe2kbzc8JPA/9aCPIahfTEDEH/giKdtzlLbkri2UYGCJqcoNl0Maz6LVUI3NCo
|
|
||||||
3O77zi2v7gLtu+9hgfWa8dTxCOszDbNTknb8XXCK74FxwIBgr4gHlvK+xh38RI+8
|
|
||||||
eC2y0qONraQ/qACJ+UGh1/4smKasSlBi7hZOvNmOxqm4iQ5hve4uWsSlIs6NBH/o
|
|
||||||
GU8BBADDinuE+B31B2hCxsRcNiruHEF9Q65vWUC0w32a9ScsyiiESqhwIgs0L/Ey
|
|
||||||
ejnn4jAQVlmgfJJLUIggGjLXGBGF7Q7v4uzxH97JeC+OCFV2b0RIyUf37Sn3i/+B
|
|
||||||
/BLp250RbLfN5jOJAtVpnbBJSLDjpWzzC6YBXiUXMRrSdEEwWwARAQABwsCDBBgB
|
|
||||||
CgAPBQJ/6BlPBQkPCZwAAhsuAKgJEHSimBgePDrrnSAEGQEKAAYFAn/oGU8ACgkQ
|
|
||||||
KMGvjkoZ3acysgP9FoulZYO+rmQwjyYE7hZ97v/gdzWb6ScO+m8Jm30Q0J9uKNTK
|
|
||||||
wOlTOh6Nrb0q0t1U2apJ//SQV0zxmQmWf1a5pNR0KdhiD3J02+3hwLl5dSoYzkNz
|
|
||||||
A9Xzgg1cCbSDF/dgLH+x1ieMBOH91OTZ0flurq2p2lwNoIVclLJNJSbZzONNJwP+
|
|
||||||
OYAKvRAWVEi/g1nWGfv0YF6cOP+6cA26vxuJPuGFp/7bwlJ8ALAk6NsQ+qjfonGO
|
|
||||||
VsAU6YXQP9Dt1PvLo7pOtZZ/W9NbuPRaFW7sB6EtYFcko9kckYJXZcIOpffTCPHm
|
|
||||||
Jrh3+G2j19Lsnomz3YCU4wETLkMwxQPG3WzOeNLwX+U=
|
|
||||||
=yV+n
|
|
||||||
-----END PGP PUBLIC KEY BLOCK-----`;
|
|
||||||
|
|
||||||
const passphrase = 'hello world';
|
const passphrase = 'hello world';
|
||||||
const plaintext = 'short message\nnext line\n한국어/조선말';
|
const plaintext = 'short message\nnext line\n한국어/조선말';
|
||||||
|
@ -645,6 +595,8 @@ describe('OpenPGP.js public api tests', function() {
|
||||||
let publicKey_2000_2008;
|
let publicKey_2000_2008;
|
||||||
let privateKey_2038_2045;
|
let privateKey_2038_2045;
|
||||||
let publicKey_2038_2045;
|
let publicKey_2038_2045;
|
||||||
|
let privateKey_1337;
|
||||||
|
let publicKey_1337;
|
||||||
let privateKey;
|
let privateKey;
|
||||||
let publicKey;
|
let publicKey;
|
||||||
let zero_copyVal;
|
let zero_copyVal;
|
||||||
|
@ -658,18 +610,18 @@ describe('OpenPGP.js public api tests', function() {
|
||||||
privateKey = openpgp.key.readArmored(priv_key);
|
privateKey = openpgp.key.readArmored(priv_key);
|
||||||
expect(privateKey.keys).to.have.length(1);
|
expect(privateKey.keys).to.have.length(1);
|
||||||
expect(privateKey.err).to.not.exist;
|
expect(privateKey.err).to.not.exist;
|
||||||
publicKey_2000_2008 = openpgp.key.readArmored(pub_key_2000_2008);
|
|
||||||
expect(publicKey_2000_2008.keys).to.have.length(1);
|
|
||||||
expect(publicKey_2000_2008.err).to.not.exist;
|
|
||||||
privateKey_2000_2008 = openpgp.key.readArmored(priv_key_2000_2008);
|
privateKey_2000_2008 = openpgp.key.readArmored(priv_key_2000_2008);
|
||||||
expect(privateKey_2000_2008.keys).to.have.length(1);
|
expect(privateKey_2000_2008.keys).to.have.length(1);
|
||||||
expect(privateKey_2000_2008.err).to.not.exist;
|
expect(privateKey_2000_2008.err).to.not.exist;
|
||||||
publicKey_2038_2045 = openpgp.key.readArmored(pub_key_2038_2045);
|
publicKey_2000_2008 = { keys: [ privateKey_2000_2008.keys[0].toPublic() ] };
|
||||||
expect(publicKey_2038_2045.keys).to.have.length(1);
|
|
||||||
expect(publicKey_2038_2045.err).to.not.exist;
|
|
||||||
privateKey_2038_2045 = openpgp.key.readArmored(priv_key_2038_2045);
|
privateKey_2038_2045 = openpgp.key.readArmored(priv_key_2038_2045);
|
||||||
expect(privateKey_2038_2045.keys).to.have.length(1);
|
expect(privateKey_2038_2045.keys).to.have.length(1);
|
||||||
expect(privateKey_2038_2045.err).to.not.exist;
|
expect(privateKey_2038_2045.err).to.not.exist;
|
||||||
|
publicKey_2038_2045 = { keys: [ privateKey_2038_2045.keys[0].toPublic() ] };
|
||||||
|
privateKey_1337 = openpgp.key.readArmored(priv_key_expires_1337);
|
||||||
|
expect(privateKey_1337.keys).to.have.length(1);
|
||||||
|
expect(privateKey_1337.err).to.not.exist;
|
||||||
|
publicKey_1337 = { keys: [ privateKey_1337.keys[0].toPublic() ] };
|
||||||
zero_copyVal = openpgp.config.zero_copy;
|
zero_copyVal = openpgp.config.zero_copy;
|
||||||
use_nativeVal = openpgp.config.use_native;
|
use_nativeVal = openpgp.config.use_native;
|
||||||
aead_protectVal = openpgp.config.aead_protect;
|
aead_protectVal = openpgp.config.aead_protect;
|
||||||
|
@ -1539,7 +1491,7 @@ describe('OpenPGP.js public api tests', function() {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should sign and verify cleartext data and not armor with detached signatures', function () {
|
it('should sign and verify cleartext data and not armor with detached signatures', function () {
|
||||||
const start = Date.now();
|
const start = openpgp.util.normalizeDate();
|
||||||
const signOpt = {
|
const signOpt = {
|
||||||
data: plaintext,
|
data: plaintext,
|
||||||
privateKeys: privateKey.keys,
|
privateKeys: privateKey.keys,
|
||||||
|
@ -1555,301 +1507,182 @@ describe('OpenPGP.js public api tests', function() {
|
||||||
return openpgp.verify(verifyOpt);
|
return openpgp.verify(verifyOpt);
|
||||||
}).then(function (verified) {
|
}).then(function (verified) {
|
||||||
expect(verified.data).to.equal(plaintext);
|
expect(verified.data).to.equal(plaintext);
|
||||||
expect(+verified.signatures[0].signature.packets[0].created).to.be.lte(Date.now());
|
expect(+verified.signatures[0].signature.packets[0].created).to.be.lte(+openpgp.util.normalizeDate());
|
||||||
expect(+verified.signatures[0].signature.packets[0].created).to.be.gte(start);
|
expect(+verified.signatures[0].signature.packets[0].created).to.be.gte(+start);
|
||||||
expect(verified.signatures[0].valid).to.be.true;
|
expect(verified.signatures[0].valid).to.be.true;
|
||||||
expect(verified.signatures[0].keyid.toHex()).to.equal(privateKey.keys[0].getSigningKeyPacket().getKeyId().toHex());
|
expect(verified.signatures[0].keyid.toHex()).to.equal(privateKey.keys[0].getSigningKeyPacket().getKeyId().toHex());
|
||||||
expect(verified.signatures[0].signature.packets.length).to.equal(1);
|
expect(verified.signatures[0].signature.packets.length).to.equal(1);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should sign and verify cleartext data with a date in the past', function () {
|
it('should sign and verify cleartext data with a date in the past', function () {
|
||||||
const past = new Date(2005, 5, 5, 5, 5, 5, 0);
|
const past = new Date(2000);
|
||||||
const signOpt = {
|
const signOpt = {
|
||||||
data: plaintext,
|
data: plaintext,
|
||||||
privateKeys: privateKey_2000_2008.keys,
|
privateKeys: privateKey_1337.keys,
|
||||||
detached: true,
|
detached: true,
|
||||||
creationDate: past,
|
date: past,
|
||||||
armor: false
|
armor: false
|
||||||
};
|
};
|
||||||
const verifyOpt = {
|
const verifyOpt = {
|
||||||
publicKeys: publicKey_2000_2008.keys
|
publicKeys: publicKey_1337.keys,
|
||||||
};
|
date: past
|
||||||
return openpgp.sign(signOpt).then(function (signed) {
|
};
|
||||||
verifyOpt.message = new openpgp.cleartext.CleartextMessage(plaintext);
|
return openpgp.sign(signOpt).then(function (signed) {
|
||||||
verifyOpt.signature = signed.signature;
|
verifyOpt.message = new openpgp.cleartext.CleartextMessage(plaintext);
|
||||||
return openpgp.verify(verifyOpt);
|
verifyOpt.signature = signed.signature;
|
||||||
}).then(function (verified) {
|
return openpgp.verify(verifyOpt).then(function (verified) {
|
||||||
expect(+verified.signatures[0].signature.packets[0].created).to.equal(+past);
|
expect(+verified.signatures[0].signature.packets[0].created).to.equal(+past);
|
||||||
expect(verified.data).to.equal(plaintext);
|
expect(verified.data).to.equal(plaintext);
|
||||||
expect(verified.signatures[0].valid).to.be.true;
|
expect(verified.signatures[0].valid).to.be.true;
|
||||||
expect(signOpt.privateKeys[0].getSigningKeyPacket(verified.signatures[0].keyid, past))
|
expect(signOpt.privateKeys[0].getSigningKeyPacket(verified.signatures[0].keyid, past))
|
||||||
.to.be.not.a('null');
|
.to.be.not.null;
|
||||||
expect(verified.signatures[0].signature.packets.length).to.equal(1);
|
expect(verified.signatures[0].signature.packets.length).to.equal(1);
|
||||||
});
|
// now check with expiration checking disabled
|
||||||
});
|
verifyOpt.date = null;
|
||||||
|
|
||||||
|
|
||||||
it('should sign and verify binary data with a date in the future', function () {
|
|
||||||
const future = new Date(2040, 5, 5, 5, 5, 5, 0);
|
|
||||||
const data = new Uint8Array([3, 14, 15, 92, 65, 35, 59]);
|
|
||||||
const signOpt = {
|
|
||||||
data,
|
|
||||||
privateKeys: privateKey_2038_2045.keys,
|
|
||||||
detached: true,
|
|
||||||
creationDate: future,
|
|
||||||
armor: false
|
|
||||||
};
|
|
||||||
const verifyOpt = {
|
|
||||||
publicKeys: publicKey_2038_2045.keys
|
|
||||||
};
|
|
||||||
return openpgp.sign(signOpt).then(function (signed) {
|
|
||||||
verifyOpt.message = openpgp.message.fromBinary(data);
|
|
||||||
verifyOpt.signature = signed.signature;
|
|
||||||
return openpgp.verify(verifyOpt);
|
return openpgp.verify(verifyOpt);
|
||||||
}).then(function (verified) {
|
}).then(function (verified) {
|
||||||
expect(+verified.signatures[0].signature.packets[0].created).to.equal(+future);
|
|
||||||
expect(verified.data).to.equal(data);
|
|
||||||
expect(verified.signatures[0].valid).to.be.true;
|
|
||||||
expect(signOpt.privateKeys[0].getSigningKeyPacket(verified.signatures[0].keyid, future))
|
|
||||||
.to.be.not.a('null');
|
|
||||||
expect(verified.signatures[0].signature.packets.length).to.equal(1);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should encrypt and decrypt cleartext data with a date in the future', function () {
|
|
||||||
const future = new Date(2040, 5, 5, 5, 5, 5, 0);
|
|
||||||
const encryptOpt = {
|
|
||||||
data: plaintext,
|
|
||||||
publicKeys: publicKey_2038_2045.keys,
|
|
||||||
creationDate: future,
|
|
||||||
armor: false
|
|
||||||
};
|
|
||||||
const decryptOpt = {
|
|
||||||
privateKeys: privateKey_2038_2045.keys
|
|
||||||
};
|
|
||||||
|
|
||||||
return openpgp.encrypt(encryptOpt).then(function (encrypted) {
|
|
||||||
decryptOpt.message = encrypted.message;
|
|
||||||
return encrypted.message.decrypt(decryptOpt.privateKeys);
|
|
||||||
}).then(function (packets) {
|
|
||||||
const literals = packets.packets.filterByTag(openpgp.enums.packet.literal);
|
|
||||||
expect(literals.length).to.equal(1);
|
|
||||||
expect(+literals[0].date).to.equal(+future);
|
|
||||||
expect(packets.getText()).to.equal(plaintext);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
it('should encrypt and decrypt binary data with a date in the past', function () {
|
|
||||||
const past = new Date(2005, 5, 5, 5, 5, 5, 0);
|
|
||||||
const data = new Uint8Array([3, 14, 15, 92, 65, 35, 59]);
|
|
||||||
const encryptOpt = {
|
|
||||||
data,
|
|
||||||
publicKeys: publicKey_2000_2008.keys,
|
|
||||||
creationDate: past,
|
|
||||||
armor: false
|
|
||||||
};
|
|
||||||
const decryptOpt = {
|
|
||||||
privateKeys: privateKey_2000_2008.keys
|
|
||||||
};
|
|
||||||
|
|
||||||
return openpgp.encrypt(encryptOpt).then(function (encrypted) {
|
|
||||||
decryptOpt.message = encrypted.message;
|
|
||||||
return encrypted.message.decrypt(decryptOpt.privateKeys);
|
|
||||||
}).then(function (packets) {
|
|
||||||
const literals = packets.packets.filterByTag(openpgp.enums.packet.literal);
|
|
||||||
expect(literals.length).to.equal(1);
|
|
||||||
expect(+literals[0].date).to.equal(+past);
|
|
||||||
expect(packets.getLiteralData()).to.deep.equal(data);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should sign, encrypt and decrypt, verify cleartext data with a date in the past', function () {
|
|
||||||
const past = new Date(2005, 5, 5, 5, 5, 5, 0);
|
|
||||||
const encryptOpt = {
|
|
||||||
data: plaintext,
|
|
||||||
publicKeys: publicKey_2000_2008.keys,
|
|
||||||
privateKeys: privateKey_2000_2008.keys,
|
|
||||||
creationDate: past,
|
|
||||||
armor: false
|
|
||||||
};
|
|
||||||
|
|
||||||
return openpgp.encrypt(encryptOpt).then(function (encrypted) {
|
|
||||||
return encrypted.message.decrypt(encryptOpt.privateKeys);
|
|
||||||
}).then(function (packets) {
|
|
||||||
const literals = packets.packets.filterByTag(openpgp.enums.packet.literal);
|
|
||||||
expect(literals.length).to.equal(1);
|
|
||||||
expect(+literals[0].date).to.equal(+past);
|
|
||||||
expect(packets.getText()).to.equal(plaintext);
|
|
||||||
return packets.verify(encryptOpt.publicKeys);
|
|
||||||
}).then(function (signatures) {
|
|
||||||
expect(+signatures[0].signature.packets[0].created).to.equal(+past);
|
|
||||||
expect(signatures[0].valid).to.be.true;
|
|
||||||
expect(encryptOpt.privateKeys[0].getSigningKeyPacket(signatures[0].keyid, past))
|
|
||||||
.to.be.not.a('null');
|
|
||||||
expect(signatures[0].signature.packets.length).to.equal(1);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
it('should sign, encrypt and decrypt, verify binary data with a date in the future', function () {
|
|
||||||
const future = new Date(2040, 5, 5, 5, 5, 5, 0);
|
|
||||||
const data = new Uint8Array([3, 14, 15, 92, 65, 35, 59]);
|
|
||||||
const encryptOpt = {
|
|
||||||
data,
|
|
||||||
publicKeys: publicKey_2038_2045.keys,
|
|
||||||
privateKeys: privateKey_2038_2045.keys,
|
|
||||||
creationDate: future,
|
|
||||||
armor: false
|
|
||||||
};
|
|
||||||
|
|
||||||
return openpgp.encrypt(encryptOpt).then(function (encrypted) {
|
|
||||||
return encrypted.message.decrypt(encryptOpt.privateKeys);
|
|
||||||
}).then(function (packets) {
|
|
||||||
const literals = packets.packets.filterByTag(openpgp.enums.packet.literal);
|
|
||||||
expect(literals.length).to.equal(1);
|
|
||||||
expect(+literals[0].date).to.equal(+future);
|
|
||||||
expect(packets.getLiteralData()).to.deep.equal(data);
|
|
||||||
return packets.verify(encryptOpt.publicKeys);
|
|
||||||
}).then(function (signatures) {
|
|
||||||
expect(+signatures[0].signature.packets[0].created).to.equal(+future);
|
|
||||||
expect(signatures[0].valid).to.be.true;
|
|
||||||
expect(encryptOpt.privateKeys[0].getSigningKeyPacket(signatures[0].keyid, future))
|
|
||||||
.to.be.not.a('null');
|
|
||||||
expect(signatures[0].signature.packets.length).to.equal(1);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should sign and verify cleartext data with a date in the past', function () {
|
|
||||||
const past = new Date(2005, 5, 5, 5, 5, 5, 0);
|
|
||||||
const signOpt = {
|
|
||||||
data: plaintext,
|
|
||||||
privateKeys: privateKey_2000_2008.keys,
|
|
||||||
detached: true,
|
|
||||||
creationDate: past,
|
|
||||||
armor: false
|
|
||||||
};
|
|
||||||
const verifyOpt = {
|
|
||||||
publicKeys: publicKey_2000_2008.keys
|
|
||||||
};
|
|
||||||
return openpgp.sign(signOpt).then(function (signed) {
|
|
||||||
verifyOpt.message = new openpgp.cleartext.CleartextMessage(plaintext);
|
|
||||||
verifyOpt.signature = signed.signature;
|
|
||||||
return openpgp.verify(verifyOpt);
|
|
||||||
}).then(function (verified) {
|
|
||||||
expect(+verified.signatures[0].signature.packets[0].created).to.equal(+past);
|
expect(+verified.signatures[0].signature.packets[0].created).to.equal(+past);
|
||||||
expect(verified.data).to.equal(plaintext);
|
expect(verified.data).to.equal(plaintext);
|
||||||
expect(verified.signatures[0].valid).to.be.true;
|
expect(verified.signatures[0].valid).to.be.true;
|
||||||
expect(signOpt.privateKeys[0].getSigningKeyPacket(verified.signatures[0].keyid, past))
|
expect(signOpt.privateKeys[0].getSigningKeyPacket(verified.signatures[0].keyid, null))
|
||||||
.to.be.not.a('null');
|
.to.be.not.null;
|
||||||
expect(verified.signatures[0].signature.packets.length).to.equal(1);
|
expect(verified.signatures[0].signature.packets.length).to.equal(1);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
});
|
||||||
|
|
||||||
it('should encrypt and decrypt cleartext data with a date in the future', function () {
|
it('should sign and verify binary data with a date in the future', function () {
|
||||||
const future = new Date(2040, 5, 5, 5, 5, 5, 0);
|
const future = new Date(2040, 5, 5, 5, 5, 5, 0);
|
||||||
const encryptOpt = {
|
const data = new Uint8Array([3, 14, 15, 92, 65, 35, 59]);
|
||||||
data: plaintext,
|
const signOpt = {
|
||||||
publicKeys: publicKey_2038_2045.keys,
|
data,
|
||||||
creationDate: future,
|
privateKeys: privateKey_2038_2045.keys,
|
||||||
armor: false
|
detached: true,
|
||||||
};
|
date: future,
|
||||||
const decryptOpt = {
|
armor: false
|
||||||
privateKeys: privateKey_2038_2045.keys
|
};
|
||||||
};
|
const verifyOpt = {
|
||||||
|
publicKeys: publicKey_2038_2045.keys,
|
||||||
|
date: future
|
||||||
|
};
|
||||||
|
return openpgp.sign(signOpt).then(function (signed) {
|
||||||
|
verifyOpt.message = openpgp.message.fromBinary(data);
|
||||||
|
verifyOpt.signature = signed.signature;
|
||||||
|
return openpgp.verify(verifyOpt);
|
||||||
|
}).then(function (verified) {
|
||||||
|
expect(+verified.signatures[0].signature.packets[0].created).to.equal(+future);
|
||||||
|
expect(verified.data).to.equal(data);
|
||||||
|
expect(verified.signatures[0].valid).to.be.true;
|
||||||
|
expect(signOpt.privateKeys[0].getSigningKeyPacket(verified.signatures[0].keyid, future))
|
||||||
|
.to.be.not.null;
|
||||||
|
expect(verified.signatures[0].signature.packets.length).to.equal(1);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
return openpgp.encrypt(encryptOpt).then(function (encrypted) {
|
it('should encrypt and decrypt cleartext data with a date in the future', function () {
|
||||||
decryptOpt.message = encrypted.message;
|
const future = new Date(2040, 5, 5, 5, 5, 5, 0);
|
||||||
return encrypted.message.decrypt(decryptOpt.privateKeys);
|
const encryptOpt = {
|
||||||
}).then(function (packets) {
|
data: plaintext,
|
||||||
const literals = packets.packets.filterByTag(openpgp.enums.packet.literal);
|
publicKeys: publicKey_2038_2045.keys,
|
||||||
expect(literals.length).to.equal(1);
|
date: future,
|
||||||
expect(+literals[0].date).to.equal(+future);
|
armor: false
|
||||||
expect(packets.getText()).to.equal(plaintext);
|
};
|
||||||
});
|
const decryptOpt = {
|
||||||
});
|
privateKeys: privateKey_2038_2045.keys,
|
||||||
|
date: future
|
||||||
|
};
|
||||||
|
|
||||||
|
return openpgp.encrypt(encryptOpt).then(function (encrypted) {
|
||||||
|
decryptOpt.message = encrypted.message;
|
||||||
|
return encrypted.message.decrypt(decryptOpt.privateKeys);
|
||||||
|
}).then(function (packets) {
|
||||||
|
const literals = packets.packets.filterByTag(openpgp.enums.packet.literal);
|
||||||
|
expect(literals.length).to.equal(1);
|
||||||
|
expect(+literals[0].date).to.equal(+future);
|
||||||
|
expect(packets.getText()).to.equal(plaintext);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
it('should encrypt and decrypt binary data with a date in the past', function () {
|
it('should encrypt and decrypt binary data with a date in the past', function () {
|
||||||
const past = new Date(2005, 5, 5, 5, 5, 5, 0);
|
const past = new Date(2005, 5, 5, 5, 5, 5, 0);
|
||||||
const data = new Uint8Array([3, 14, 15, 92, 65, 35, 59]);
|
const data = new Uint8Array([3, 14, 15, 92, 65, 35, 59]);
|
||||||
const encryptOpt = {
|
const encryptOpt = {
|
||||||
data,
|
data,
|
||||||
publicKeys: publicKey_2000_2008.keys,
|
publicKeys: publicKey_2000_2008.keys,
|
||||||
creationDate: past,
|
date: past,
|
||||||
armor: false
|
armor: false
|
||||||
};
|
};
|
||||||
const decryptOpt = {
|
const decryptOpt = {
|
||||||
privateKeys: privateKey_2000_2008.keys
|
privateKeys: privateKey_2000_2008.keys,
|
||||||
};
|
date: past
|
||||||
|
};
|
||||||
|
|
||||||
return openpgp.encrypt(encryptOpt).then(function (encrypted) {
|
return openpgp.encrypt(encryptOpt).then(function (encrypted) {
|
||||||
decryptOpt.message = encrypted.message;
|
decryptOpt.message = encrypted.message;
|
||||||
return encrypted.message.decrypt(decryptOpt.privateKeys);
|
return encrypted.message.decrypt(decryptOpt.privateKeys);
|
||||||
}).then(function (packets) {
|
}).then(function (packets) {
|
||||||
const literals = packets.packets.filterByTag(openpgp.enums.packet.literal);
|
const literals = packets.packets.filterByTag(openpgp.enums.packet.literal);
|
||||||
expect(literals.length).to.equal(1);
|
expect(literals.length).to.equal(1);
|
||||||
expect(+literals[0].date).to.equal(+past);
|
expect(+literals[0].date).to.equal(+past);
|
||||||
expect(packets.getLiteralData()).to.deep.equal(data);
|
expect(packets.getLiteralData()).to.deep.equal(data);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should sign, encrypt and decrypt, verify cleartext data with a date in the past', function () {
|
it('should sign, encrypt and decrypt, verify cleartext data with a date in the past', function () {
|
||||||
const past = new Date(2005, 5, 5, 5, 5, 5, 0);
|
const past = new Date(2005, 5, 5, 5, 5, 5, 0);
|
||||||
const encryptOpt = {
|
const encryptOpt = {
|
||||||
data: plaintext,
|
data: plaintext,
|
||||||
publicKeys: publicKey_2000_2008.keys,
|
publicKeys: publicKey_2000_2008.keys,
|
||||||
privateKeys: privateKey_2000_2008.keys,
|
privateKeys: privateKey_2000_2008.keys,
|
||||||
creationDate: past,
|
date: past,
|
||||||
armor: false
|
armor: false
|
||||||
};
|
};
|
||||||
|
|
||||||
return openpgp.encrypt(encryptOpt).then(function (encrypted) {
|
return openpgp.encrypt(encryptOpt).then(function (encrypted) {
|
||||||
return encrypted.message.decrypt(encryptOpt.privateKeys);
|
return encrypted.message.decrypt(encryptOpt.privateKeys);
|
||||||
}).then(function (packets) {
|
}).then(function (packets) {
|
||||||
const literals = packets.packets.filterByTag(openpgp.enums.packet.literal);
|
const literals = packets.packets.filterByTag(openpgp.enums.packet.literal);
|
||||||
expect(literals.length).to.equal(1);
|
expect(literals.length).to.equal(1);
|
||||||
expect(+literals[0].date).to.equal(+past);
|
expect(+literals[0].date).to.equal(+past);
|
||||||
expect(packets.getText()).to.equal(plaintext);
|
expect(packets.getText()).to.equal(plaintext);
|
||||||
return packets.verify(encryptOpt.publicKeys);
|
return packets.verify(encryptOpt.publicKeys, past);
|
||||||
}).then(function (signatures) {
|
}).then(function (signatures) {
|
||||||
expect(+signatures[0].signature.packets[0].created).to.equal(+past);
|
expect(+signatures[0].signature.packets[0].created).to.equal(+past);
|
||||||
expect(signatures[0].valid).to.be.true;
|
expect(signatures[0].valid).to.be.true;
|
||||||
expect(encryptOpt.privateKeys[0].getSigningKeyPacket(signatures[0].keyid, past))
|
expect(encryptOpt.privateKeys[0].getSigningKeyPacket(signatures[0].keyid, past))
|
||||||
.to.be.not.a('null');
|
.to.be.not.null;
|
||||||
expect(signatures[0].signature.packets.length).to.equal(1);
|
expect(signatures[0].signature.packets.length).to.equal(1);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should sign, encrypt and decrypt, verify binary data with a date in the future', function () {
|
||||||
|
const future = new Date(2040, 5, 5, 5, 5, 5, 0);
|
||||||
|
const data = new Uint8Array([3, 14, 15, 92, 65, 35, 59]);
|
||||||
|
const encryptOpt = {
|
||||||
|
data,
|
||||||
|
publicKeys: publicKey_2038_2045.keys,
|
||||||
|
privateKeys: privateKey_2038_2045.keys,
|
||||||
|
date: future,
|
||||||
|
armor: false
|
||||||
|
};
|
||||||
|
|
||||||
it('should sign, encrypt and decrypt, verify binary data with a date in the future', function () {
|
return openpgp.encrypt(encryptOpt).then(function (encrypted) {
|
||||||
const future = new Date(2040, 5, 5, 5, 5, 5, 0);
|
return encrypted.message.decrypt(encryptOpt.privateKeys);
|
||||||
const data = new Uint8Array([3, 14, 15, 92, 65, 35, 59]);
|
}).then(function (packets) {
|
||||||
const encryptOpt = {
|
const literals = packets.packets.filterByTag(openpgp.enums.packet.literal);
|
||||||
data,
|
expect(literals.length).to.equal(1);
|
||||||
publicKeys: publicKey_2038_2045.keys,
|
expect(+literals[0].date).to.equal(+future);
|
||||||
privateKeys: privateKey_2038_2045.keys,
|
expect(packets.getLiteralData()).to.deep.equal(data);
|
||||||
creationDate: future,
|
return packets.verify(encryptOpt.publicKeys, future);
|
||||||
armor: false
|
}).then(function (signatures) {
|
||||||
};
|
expect(+signatures[0].signature.packets[0].created).to.equal(+future);
|
||||||
|
expect(signatures[0].valid).to.be.true;
|
||||||
return openpgp.encrypt(encryptOpt).then(function (encrypted) {
|
expect(encryptOpt.privateKeys[0].getSigningKeyPacket(signatures[0].keyid, future))
|
||||||
return encrypted.message.decrypt(encryptOpt.privateKeys);
|
.to.be.not.null;
|
||||||
}).then(function (packets) {
|
expect(signatures[0].signature.packets.length).to.equal(1);
|
||||||
const literals = packets.packets.filterByTag(openpgp.enums.packet.literal);
|
});
|
||||||
expect(literals.length).to.equal(1);
|
});
|
||||||
expect(+literals[0].date).to.equal(+future);
|
|
||||||
expect(packets.getLiteralData()).to.deep.equal(data);
|
|
||||||
return packets.verify(encryptOpt.publicKeys);
|
|
||||||
}).then(function (signatures) {
|
|
||||||
expect(+signatures[0].signature.packets[0].created).to.equal(+future);
|
|
||||||
expect(signatures[0].valid).to.be.true;
|
|
||||||
expect(encryptOpt.privateKeys[0].getSigningKeyPacket(signatures[0].keyid, future))
|
|
||||||
.to.be.not.a('null');
|
|
||||||
expect(signatures[0].signature.packets.length).to.equal(1);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('ELG / DSA encrypt, decrypt, sign, verify', function() {
|
describe('ELG / DSA encrypt, decrypt, sign, verify', function() {
|
||||||
|
@ -2072,6 +1905,7 @@ describe('OpenPGP.js public api tests', function() {
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
|
@ -642,8 +642,7 @@ describe("Signature", function() {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Verify test with expired verification public key and verify_expired_keys set to false', function() {
|
it('Verify test with expired verification public key', function() {
|
||||||
openpgp.config.verify_expired_keys = false;
|
|
||||||
const pubKey = openpgp.key.readArmored(pub_expired).keys[0];
|
const pubKey = openpgp.key.readArmored(pub_expired).keys[0];
|
||||||
const message = openpgp.message.readArmored(msg_sig_expired);
|
const message = openpgp.message.readArmored(msg_sig_expired);
|
||||||
return openpgp.verify({ publicKeys:[pubKey], message:message }).then(function(verified) {
|
return openpgp.verify({ publicKeys:[pubKey], message:message }).then(function(verified) {
|
||||||
|
@ -655,11 +654,10 @@ describe("Signature", function() {
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Verify test with expired verification public key and verify_expired_keys set to true', function() {
|
it('Verify test with expired verification public key and disable expiration checks using null date', function() {
|
||||||
openpgp.config.verify_expired_keys = true;
|
|
||||||
const pubKey = openpgp.key.readArmored(pub_expired).keys[0];
|
const pubKey = openpgp.key.readArmored(pub_expired).keys[0];
|
||||||
const message = openpgp.message.readArmored(msg_sig_expired);
|
const message = openpgp.message.readArmored(msg_sig_expired);
|
||||||
return openpgp.verify({ publicKeys:[pubKey], message:message }).then(function(verified) {
|
return openpgp.verify({ publicKeys:[pubKey], message:message, date: null }).then(function(verified) {
|
||||||
expect(verified).to.exist;
|
expect(verified).to.exist;
|
||||||
expect(verified.signatures).to.have.length(1);
|
expect(verified.signatures).to.have.length(1);
|
||||||
expect(verified.signatures[0].valid).to.be.true;
|
expect(verified.signatures[0].valid).to.be.true;
|
||||||
|
@ -668,8 +666,7 @@ describe("Signature", function() {
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Verify test with expired verification public key and verify_expired_keys set to false', function() {
|
it('Verify test with expired verification public key', function() {
|
||||||
openpgp.config.verify_expired_keys = false;
|
|
||||||
const pubKey = openpgp.key.readArmored(pub_expired).keys[0];
|
const pubKey = openpgp.key.readArmored(pub_expired).keys[0];
|
||||||
const message = openpgp.message.readArmored(msg_sig_expired);
|
const message = openpgp.message.readArmored(msg_sig_expired);
|
||||||
return openpgp.verify({ publicKeys:[pubKey], message:message }).then(function(verified) {
|
return openpgp.verify({ publicKeys:[pubKey], message:message }).then(function(verified) {
|
||||||
|
@ -681,11 +678,10 @@ describe("Signature", function() {
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Verify test with expired verification public key and verify_expired_keys set to true', function() {
|
it('Verify test with expired verification public key and disable expiration checks using null date', function() {
|
||||||
openpgp.config.verify_expired_keys = true;
|
|
||||||
const pubKey = openpgp.key.readArmored(pub_expired).keys[0];
|
const pubKey = openpgp.key.readArmored(pub_expired).keys[0];
|
||||||
const message = openpgp.message.readArmored(msg_sig_expired);
|
const message = openpgp.message.readArmored(msg_sig_expired);
|
||||||
return openpgp.verify({ publicKeys:[pubKey], message:message }).then(function(verified) {
|
return openpgp.verify({ publicKeys:[pubKey], message:message, date: null }).then(function(verified) {
|
||||||
expect(verified).to.exist;
|
expect(verified).to.exist;
|
||||||
expect(verified.signatures).to.have.length(1);
|
expect(verified.signatures).to.have.length(1);
|
||||||
expect(verified.signatures[0].valid).to.be.true;
|
expect(verified.signatures[0].valid).to.be.true;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user