#89 Use OpenPGP.js v5.1.0 (still in progress)

This commit is contained in:
the-djmaze 2022-01-27 16:00:52 +01:00
parent dfd255545a
commit ff7e41ad08
130 changed files with 1871 additions and 44411 deletions

View file

@ -67,16 +67,6 @@ export const
*/
staticLink = path => VERSION_PREFIX + 'static/' + path,
/**
* @returns {string}
*/
openPgpJs = () => staticLink('js/min/openpgp.min.js'),
/**
* @returns {string}
*/
openPgpWorkerJs = () => staticLink('js/min/openpgp.worker.min.js'),
/**
* @param {string} theme
* @returns {string}

View file

@ -102,6 +102,7 @@ export class MessageModel extends AbstractModel {
hasExternals: false,
pgpSigned: null,
pgpEncrypted: null,
isPgpEncrypted: false,
pgpSignedVerifyStatus: SignedVerifyStatus.None,
pgpSignedVerifyUser: '',
@ -181,6 +182,7 @@ export class MessageModel extends AbstractModel {
this.attachments(new AttachmentCollectionModel);
this.pgpSigned(null);
this.pgpEncrypted(null);
this.isPgpEncrypted(false);
this.pgpSignedVerifyStatus(SignedVerifyStatus.None);
this.pgpSignedVerifyUser('');

View file

@ -7,8 +7,8 @@ import Remote from 'Remote/User/Fetch';
import { showScreenPopup } from 'Knoin/Knoin';
import { AddOpenPgpKeyPopupView } from 'View/Popup/AddOpenPgpKey';
import { NewOpenPgpKeyPopupView } from 'View/Popup/NewOpenPgpKey';
import { OpenPgpImportPopupView } from 'View/Popup/OpenPgpImport';
import { OpenPgpGeneratePopupView } from 'View/Popup/OpenPgpGenerate';
import { ViewOpenPgpKeyPopupView } from 'View/Popup/ViewOpenPgpKey';
import { Capa } from 'Common/Enums';
@ -22,9 +22,7 @@ export class OpenPgpUserSettings /*extends AbstractViewSettings*/ {
this.openpgpkeysPrivate = PgpUserStore.openpgpPrivateKeys;
this.openPgpKeyForDeletion = ko.observable(null).deleteAccessHelper();
// this.canOpenPGP = !!PgpUserStore.openpgpKeyring;
this.canOpenPGP = Settings.capa(Capa.OpenPGP);
// this.canGnuPG = !!PgpUserStore.gnupgKeyring;
this.canGnuPG = Settings.capa(Capa.GnuPG);
this.canMailvelope = !!window.mailvelope;
@ -34,11 +32,11 @@ export class OpenPgpUserSettings /*extends AbstractViewSettings*/ {
}
addOpenPgpKey() {
showScreenPopup(AddOpenPgpKeyPopupView);
showScreenPopup(OpenPgpImportPopupView);
}
generateOpenPgpKey() {
showScreenPopup(NewOpenPgpKeyPopupView);
showScreenPopup(OpenPgpGeneratePopupView);
}
viewOpenPgpKey(openPgpKey) {

View file

@ -2,16 +2,16 @@ import ko from 'ko';
import { Capa } from 'Common/Enums';
import { doc, createElement, Settings } from 'Common/Globals';
import { openPgpJs, openPgpWorkerJs } from 'Common/Links';
import { staticLink } from 'Common/Links';
import { isArray, arrayLength } from 'Common/Utils';
import { delegateRunOnDestroy } from 'Common/UtilsUser';
import { showScreenPopup } from 'Knoin/Knoin';
//import { showScreenPopup } from 'Knoin/Knoin';
import { MessageOpenPgpPopupView } from 'View/Popup/MessageOpenPgp';
//import { MessageOpenPgpPopupView } from 'View/Popup/MessageOpenPgp';
import { EmailModel } from 'Model/Email';
import { OpenPgpKeyModel } from 'Model/OpenPgpKey';
//import { EmailModel } from 'Model/Email';
//import { OpenPgpKeyModel } from 'Model/OpenPgpKey';
import Remote from 'Remote/User/Fetch';
@ -19,6 +19,60 @@ const
findKeyByHex = (keys, hash) =>
keys.find(item => item && (hash === item.id || item.ids.includes(hash)));
/**
* OpenPGP.js v5 removed the localStorage (keyring)
* This should be compatible with the old OpenPGP.js v2
*/
const
publicKeysItem = 'openpgp-public-keys',
privateKeysItem = 'openpgp-private-keys',
storage = window.localStorage,
loadOpenPgpKeys = async itemname => {
let keys = [], key,
armoredKeys = JSON.parse(storage.getItem(itemname)),
i = arrayLength(armoredKeys);
if (i) {
while (i--) {
key = await openpgp.readKey({armoredKey:armoredKeys[i]});
if (!key.err) {
const aEmails = [];
if (key.users) {
key.users.forEach(user => {
if (user.userID.email) {
aEmails.push(user.userID.email);
}
});
}
keys.push({
id: key.getKeyID().toHex(),
fingerprint: key.getFingerprint(),
can_encrypt: !!key.getEncryptionKey(),
can_sign: !!key.getSigningKey(),
emails: aEmails,
armor: armoredKeys[i],
deleteAccess: ko.observable(false)
});
// key.getUserIDs()
// key.getPrimaryUser()
}
}
}
return keys;
/*
},
storeKeys = async (itemname, keys) => {
let armoredKeys = [], i = arrayLength(keys);
if (i) {
while (i--) {
armoredKeys.push(await keys[i].armor());
}
storage.setItem(itemname, JSON.stringify(armoredKeys));
} else {
storage.removeItem(itemname);
}
*/
};
export const PgpUserStore = new class {
constructor() {
/**
@ -29,7 +83,6 @@ export const PgpUserStore = new class {
this.gnupgKeys = ko.observableArray();
// OpenPGP.js
this.openpgpKeyring = null;
this.openpgpPublicKeys = ko.observableArray();
this.openpgpPrivateKeys = ko.observableArray();
@ -39,21 +92,12 @@ export const PgpUserStore = new class {
init() {
if (Settings.capa(Capa.OpenPGP) && window.crypto && crypto.getRandomValues) {
const script = createElement('script', {src:openPgpJs()});
script.onload = () => {
if (window.Worker) {
try {
openpgp.initWorker({ path: openPgpWorkerJs() });
} catch (e) {
console.error(e);
}
}
this.loadKeyrings();
};
const script = createElement('script', {src:staticLink('js/min/openpgp.min.js')});
script.onload = () => this.loadKeyrings();
script.onerror = () => {
this.loadKeyrings();
console.error(script.src);
}
};
doc.head.append(script);
} else {
this.loadKeyrings();
@ -82,8 +126,14 @@ export const PgpUserStore = new class {
}
if (openpgp) {
this.openpgpKeyring = new openpgp.Keyring();
this.reloadOpenPgpKeys();
loadOpenPgpKeys(publicKeysItem).then(keys => {
this.openpgpPublicKeys(keys || []);
console.log('openpgp.js public keys loaded');
});
loadOpenPgpKeys(privateKeysItem).then(keys => {
this.openpgpPrivateKeys(keys || [])
console.log('openpgp.js private keys loaded');
});
}
if (Settings.capa(Capa.GnuPG)) {
@ -101,69 +151,6 @@ export const PgpUserStore = new class {
}
}
reloadOpenPgpKeys() {
if (this.openpgpKeyring) {
const publicKeys = [],
privateKeys = [],
email = new EmailModel();
this.openpgpKeyring.getAllKeys().forEach(oItem => {
if (oItem && oItem.primaryKey) {
const aEmails = [],
aUsers = [],
primaryUser = oItem.getPrimaryUser(),
user =
primaryUser && primaryUser.user
? primaryUser.user.userId.userid
: oItem.users && oItem.users[0]
? oItem.users[0].userId.userid
: '';
if (oItem.users) {
oItem.users.forEach(item => {
if (item.userId) {
email.clear();
email.parse(item.userId.userid);
if (email.validate()) {
aEmails.push(email.email);
aUsers.push(item.userId.userid);
}
}
});
}
if (aEmails.length) {
(oItem.isPrivate() ? privateKeys : publicKeys).push(
new OpenPgpKeyModel(
oItem.primaryKey.getFingerprint(),
oItem.primaryKey
.getKeyId()
.toHex()
.toLowerCase(),
oItem.getKeyIds()
.map(item => (item && item.toHex ? item.toHex() : null))
.validUnique(),
aUsers,
aEmails,
oItem.isPrivate(),
oItem.armor(),
user
)
);
}
}
});
delegateRunOnDestroy(this.openpgpPublicKeys());
this.openpgpPublicKeys(publicKeys);
delegateRunOnDestroy(this.openpgpPrivateKeys());
this.openpgpPrivateKeys(privateKeys);
console.log('openpgp.js ready');
}
}
/**
* @returns {boolean}
*/
@ -186,6 +173,29 @@ export const PgpUserStore = new class {
}
}
/**
keyPair.privateKey
keyPair.publicKey
keyPair.revocationCertificate
keyPair.onServer
keyPair.inGnuPG
keyPair.uid.name
keyPair.uid.email
*/
storeKeyPair(keyPair, callback) {
// if (Settings.capa(Capa.GnuPG)) {
Remote.request('PgpStoreKeyPair',
(iError, oData) => {
if (oData && oData.Result) {
// this.gnupgKeyring = oData.Result;
}
callback && callback(iError, oData);
}, keyPair
);
// storeKeys(publicKeysItem);
// storeKeys(privateKeysItem);
}
/**
* Checks if verifying/encrypting a message is possible with given email addresses.
* Returns the first library that can.
@ -199,8 +209,8 @@ export const PgpUserStore = new class {
return 'gnupg';
}
length = this.openpgpKeyring && recipients.filter(email =>
this.openpgpKeyring.publicKeys.getForAddress(email).length
length = recipients.filter(email =>
this.openpgpPublicKeys().find(key => key.emails.includes(email))
).length;
if (openpgp && (!all || openpgp === count)) {
return 'openpgp';
@ -218,19 +228,29 @@ export const PgpUserStore = new class {
return false;
}
getGnuPGPrivateKeyFor(email, sign) {
let key = this.gnupgKeyring && this.gnupgKeyring[email];
if (key && key[sign?'can_sign':'can_decrypt']) {
return ['gnupg', key];
}
}
getOpenPGPPrivateKeyFor(email/*, sign*/) {
let key = this.openpgpPrivateKeys().find(key => key.emails.includes(email));
if (key && key.length) {
return ['openpgp', key[0]];
}
}
getOpenPGPPublicKeyFor(email/*, sign*/) {
return this.gnupgKeyring && this.openpgpKeyring.publicKeys.getForAddress(email);
}
/**
* Checks if signing a message is possible with given email address.
* Returns the first library that can.
*/
async hasPrivateKeyFor(email, sign) {
if (this.gnupgKeyring && this.gnupgKeyring[email] && this.gnupgKeyring[email][sign?'can_sign':'can_decrypt']) {
return 'gnupg';
}
if (this.openpgpKeyring && this.openpgpKeyring.privateKeys.getForAddress(email).length) {
return 'openpgp';
}
async getMailvelopePrivateKeyFor(email/*, sign*/) {
let keyring = this.mailvelopeKeyring;
if (keyring) {
/**
@ -238,7 +258,7 @@ export const PgpUserStore = new class {
*/
let keys = await keyring.validKeyForAddress([email]);
if (keys && keys[email] && await keyring.hasPrivateKey(keys[email].keys[0].fingerprint)) {
return 'mailvelope';
return ['mailvelope', keys[email].keys[0].fingerprint];
}
}
@ -249,16 +269,20 @@ export const PgpUserStore = new class {
* Checks if signing a message is possible with given email address.
* Returns the first library that can.
*/
async hasKeyForSigning(email) {
return await this.hasPrivateKeyFor(email, 1);
async getKeyForSigning(email) {
return this.getGnuPGPrivateKeyFor(email, 1)
|| this.getOpenPGPPrivateKeyFor(email, 1)
|| await this.getMailvelopePrivateKeyFor(email, 1);
}
/**
* Checks if decrypting a message is possible with given email address.
* Returns the first library that can.
*/
async hasKeyForDecrypting(email) {
return await this.hasPrivateKeyFor(email, 0);
async getKeyForDecrypting(email) {
return await this.getMailvelopePrivateKeyFor(email)
|| this.getGnuPGPrivateKeyFor(email)
|| this.getOpenPGPPrivateKeyFor(email);
}
/**
@ -289,10 +313,10 @@ export const PgpUserStore = new class {
if (items[0] || items[1]) {
openpgpKeyring.store();
}
// this.reloadOpenPgpKeys();
}
}
/*
decryptMessage(message, recipients, fCallback) {
if (message && message.getEncryptionKeyIds) {
// findPrivateKeysByEncryptionKeyIds
@ -352,6 +376,7 @@ export const PgpUserStore = new class {
return false;
}
*/
verifyMessage(message, fCallback) {
if (message && message.getSigningKeyIds) {

View file

@ -1,4 +1,4 @@
#V-PopupsViewOpenPgpKey, #V-PopupsNewOpenPgpKey {
#V-PopupsViewOpenPgpKey, #V-PopupsOpenPgpGenerate {
max-width: 570px;
}
@ -9,124 +9,7 @@
}
}
#V-PopupsComposeOpenPgp {
max-width: 800px;
.key-list {
background-color: #f9f9f9;
border-radius: 5px;
padding: 10px 15px;
&-wrp {
&:hover {
overflow: auto;
}
&:hover .key-list__item-name {
overflow: visible;
}
&.empty {
text-align: center;
padding-top: 10px;
color: #aaa;
font-size: 16px;
}
}
&__item {
color: #333;
white-space: nowrap;
padding-bottom: 4px;
display: flex;
&:last-child {
padding-bottom: 0;
}
&-delete {
cursor: pointer;
&.disabled {
cursor: not-allowed;
}
}
&-names {
color: #333;
width: 80%;
&.empty {
color: red;
}
}
&-name {
overflow: hidden;
text-overflow: ellipsis;
}
&-error {
color: red;
width: 80%;
}
&-hash {
color: #aaa;
width: 20%;
}
}
}
.key-actions {
margin-top: 10px;
min-height: 40px;
select option:nth-child(even) {
background-color: rgba(128, 128, 128, 0.1);
}
}
}
#V-PopupsMessageOpenPgp {
max-width: 700px;
.key-list {
margin-top: 5px;
overflow: hidden;
&__item {
color: #555;
cursor: pointer;
text-overflow: ellipsis;
white-space: nowrap;
&__radio {
padding: 3px 5px 0 0;
vertical-align: top;
}
&__name {
border-bottom: 1px solid transparent;
}
&__names {
display: inline-block;
&:hover .key-list__item__name {
border-bottom: 1px dashed #555;
}
}
}
}
}
#V-PopupsAddOpenPgpKey {
#V-PopupsOpenPgpImport {
max-width: 645px;
.inputKey {

View file

@ -1,40 +1,18 @@
V-Settings-OpenPgp {
#V-Settings-OpenPgp {
td * {
cursor: pointer;
}
td + td {
width: 1%;
}
table {
.open-pgp-key-img {
margin-right: 10px;
vertical-align: top;
}
.open-pgp-key-id, .open-pgp-key-user {
display: inline-block;
word-break: break-all;
box-sizing: border-box;
line-height: 22px;
cursor: default;
}
.open-pgp-key-user-address:first-child {
line-height: 30px;
margin-bottom: -4px;
}
.open-pgp-key-user {
white-space: nowrap;
}
.open-pgp-key-item {
.delete-open-pgp-key, .view-open-pgp-key {
cursor: pointer;
opacity: 0.7;
&:hover {
opacity: 0.9;
}
}
.delete-open-pgp-key:not(:hover) {
opacity: 0.7;
}
}

View file

@ -279,9 +279,9 @@ class ComposePopupView extends AbstractViewPopup {
currentIdentity: value => {
this.canPgpSign(false);
value && PgpUserStore.hasKeyForSigning(value.email()).then(result => {
value && PgpUserStore.getKeyForSigning(value.email()).then(result => {
console.log({canPgpSign:result});
this.canPgpSign(result)
this.canPgpSign(!!result)
});
},
@ -458,11 +458,10 @@ class ComposePopupView extends AbstractViewPopup {
if ('openpgp' == sign) {
let privateKey;
try {
const keys = PgpUserStore.openpgpKeyring.privateKeys.getForAddress(this.currentIdentity().email());
const keys = PgpUserStore.getOpenPGPPrivateKeyFor(this.currentIdentity().email());
if (keys[0]) {
keys[0].decrypt(window.prompt('Password', ''));
privateKey = keys[0];
cfg.privateKeys = [privateKey];
cfg.privateKey = privateKey = keys[0];
}
} catch (e) {
console.error(e);
@ -478,7 +477,7 @@ class ComposePopupView extends AbstractViewPopup {
// error 'sign and encrypt must be same engine';
} else if ('openpgp' == encrypt) {
this.allRecipients().forEach(recEmail => {
cfg.publicKeys = cfg.publicKeys.concat(PgpUserStore.openpgpKeyring.publicKeys.getForAddress(recEmail));
cfg.publicKeys = cfg.publicKeys.concat(PgpUserStore.getOpenPGPPublicKeyFor(recEmail));
});
pgpPromise = openpgp.encrypt(cfg);
} else if ('openpgp' == sign) {
@ -1502,7 +1501,8 @@ class ComposePopupView extends AbstractViewPopup {
allRecipients() {
const email = new EmailModel();
return [
// this.currentIdentity.email(),
// From/sender is also recipient (Sent mailbox)
this.currentIdentity().email(),
this.to(),
this.cc(),
this.bcc()

View file

@ -1,121 +0,0 @@
import ko from 'ko';
import { pString } from 'Common/Utils';
import { Scope } from 'Common/Enums';
import { decorateKoCommands } from 'Knoin/Knoin';
import { AbstractViewPopup } from 'Knoin/AbstractViews';
class MessageOpenPgpPopupView extends AbstractViewPopup {
constructor() {
super('MessageOpenPgp');
this.addObservables({
notification: '',
selectedKey: null,
password: '',
submitRequest: false
});
this.privateKeys = ko.observableArray();
this.resultCallback = null;
decorateKoCommands(this, {
doCommand: self => !self.submitRequest()
});
}
doCommand() {
this.submitRequest(true);
setTimeout(() => {
let privateKey = null;
try {
if (this.resultCallback && this.selectedKey()) {
const privateKeys = this.selectedKey().getNativeKeys();
privateKey = privateKeys && privateKeys[0] ? privateKeys[0] : null;
if (privateKey) {
try {
if (!privateKey.decrypt(pString(this.password()))) {
console.log('Error: Private key cannot be decrypted');
privateKey = null;
}
} catch (e) {
console.log(e);
privateKey = null;
}
} else {
console.log('Error: Private key cannot be found');
}
}
} catch (e) {
console.log(e);
privateKey = null;
}
this.submitRequest(false);
this.cancelCommand();
this.resultCallback(privateKey);
}, 100);
}
clearPopup() {
this.notification('');
this.password('');
this.selectedKey(false);
this.submitRequest(false);
this.resultCallback = null;
this.privateKeys([]);
}
onBuild(oDom) {
// shortcuts.add('tab', 'shift', Scope.MessageOpenPgp, () => {
shortcuts.add('tab', '', Scope.MessageOpenPgp, () => {
let btn = this.querySelector('.inputPassword');
if (btn.matches(':focus')) {
btn = this.querySelector('.buttonDo');
}
btn.focus();
return false;
});
const self = this;
oDom.addEventListener('click', event => {
const el = event.target.closestWithin('.key-list__item', oDom);
if (el) {
oDom.querySelectorAll('.key-list__item .key-list__item__radio').forEach(node =>
node.textContent = el === node ? '⦿' : '○'
);
self.selectedKey(ko.dataFor(el));
// this.querySelector('.inputPassword').focus();
}
});
}
onHideWithDelay() {
this.clearPopup();
}
onShow(fCallback, privateKeys) {
this.clearPopup();
this.resultCallback = fCallback;
this.privateKeys(privateKeys);
if (this.viewModelDom) {
const el = this.querySelector('.key-list__item');
el && el.click();
}
}
}
export { MessageOpenPgpPopupView, MessageOpenPgpPopupView as default };

View file

@ -1,105 +0,0 @@
import { pInt } from 'Common/Utils';
import { PgpUserStore } from 'Stores/User/Pgp';
import { IdentityUserStore } from 'Stores/User/Identity';
import { decorateKoCommands } from 'Knoin/Knoin';
import { AbstractViewPopup } from 'Knoin/AbstractViews';
class NewOpenPgpKeyPopupView extends AbstractViewPopup {
constructor() {
super('NewOpenPgpKey');
this.identities = IdentityUserStore;
this.addObservables({
email: '',
emailError: false,
name: '',
password: '',
keyBitLength: 4096,
submitRequest: false,
submitError: ''
});
this.email.subscribe(() => this.emailError(false));
decorateKoCommands(this, {
generateOpenPgpKeyCommand: 1
});
}
generateOpenPgpKeyCommand() {
const userId = {},
openpgpKeyring = PgpUserStore.openpgpKeyring;
this.emailError(!this.email().trim());
if (!openpgpKeyring || this.emailError()) {
return false;
}
userId.email = this.email();
if (this.name()) {
userId.name = this.name();
}
this.submitRequest(true);
this.submitError('');
setTimeout(() => {
try {
openpgp
.generateKey({
userIds: [userId],
numBits: pInt(this.keyBitLength()),
passphrase: this.password().trim()
})
.then((keyPair) => {
this.submitRequest(false);
if (keyPair && keyPair.privateKeyArmored) {
openpgpKeyring.privateKeys.importKey(keyPair.privateKeyArmored);
openpgpKeyring.publicKeys.importKey(keyPair.publicKeyArmored);
openpgpKeyring.store();
PgpUserStore.reloadOpenPgpKeys();
PgpUserStore.gnupgImportKey(keyPair.privateKeyArmored);
this.cancelCommand();
}
})
.catch((e) => {
this.submitRequest(false);
this.showError(e);
});
} catch (e) {
this.submitRequest(false);
this.showError(e);
}
}, 100);
return true;
}
showError(e) {
console.log(e);
if (e && e.message) {
this.submitError(e.message);
}
}
onShow() {
this.name(IdentityUserStore()[0].name());
this.password('');
this.email(IdentityUserStore()[0].email());
this.emailError(false);
this.keyBitLength(4096);
this.submitError('');
}
}
export { NewOpenPgpKeyPopupView, NewOpenPgpKeyPopupView as default };

View file

@ -0,0 +1,102 @@
//import { pInt } from 'Common/Utils';
import { PgpUserStore } from 'Stores/User/Pgp';
import { IdentityUserStore } from 'Stores/User/Identity';
import { decorateKoCommands } from 'Knoin/Knoin';
import { AbstractViewPopup } from 'Knoin/AbstractViews';
import { Capa } from 'Common/Enums';
import { Settings } from 'Common/Globals';
export class OpenPgpGeneratePopupView extends AbstractViewPopup {
constructor() {
super('OpenPgpGenerate');
this.identities = IdentityUserStore;
this.addObservables({
email: '',
emailError: false,
name: '',
password: '',
keyType: 'ECC',
submitRequest: false,
submitError: '',
saveGnuPG: true,
saveServer: true
});
this.canGnuPG = Settings.capa(Capa.GnuPG);
this.email.subscribe(() => this.emailError(false));
decorateKoCommands(this, {
generateOpenPgpKeyCommand: 1
});
}
generateOpenPgpKeyCommand() {
const type = this.keyType().toLowerCase(),
userId = {
name: this.name(),
email: this.email()
},
cfg = {
type: type,
userIDs: [userId],
passphrase: this.password().trim()
// format: 'armored' // output key format, defaults to 'armored' (other options: 'binary' or 'object')
}
/*
if ('ecc' === type) {
cfg.curve = 'curve25519';
} else {
cfg.rsaBits = pInt(this.keyBitLength());
}
*/
this.emailError(!this.email().trim());
if (this.emailError()) {
return false;
}
this.submitRequest(true);
this.submitError('');
openpgp.generateKey(cfg).then(keyPair => {
if (keyPair) {
keyPair.onServer = !!this.saveServer();
keyPair.inGnuPG = !!this.saveGnuPG();
keyPair.uid = userId;
PgpUserStore.storeKeyPair(keyPair, ()=>{
this.submitRequest(false);
this.cancelCommand();
});
}
})
.catch((e) => {
this.submitRequest(false);
this.showError(e);
});
return true;
}
showError(e) {
console.log(e);
if (e && e.message) {
this.submitError(e.message);
}
}
onShow() {
this.name(''/*IdentityUserStore()[0].name()*/);
this.password('');
this.email(''/*IdentityUserStore()[0].email()*/);
this.emailError(false);
this.submitError('');
}
}

View file

@ -6,9 +6,9 @@ import { AbstractViewPopup } from 'Knoin/AbstractViews';
import { Capa } from 'Common/Enums';
import { Settings } from 'Common/Globals';
class AddOpenPgpKeyPopupView extends AbstractViewPopup {
export class OpenPgpImportPopupView extends AbstractViewPopup {
constructor() {
super('AddOpenPgpKey');
super('OpenPgpImport');
this.addObservables({
key: '',
@ -16,11 +16,10 @@ class AddOpenPgpKeyPopupView extends AbstractViewPopup {
keyErrorMessage: '',
saveGnuPG: true,
saveOpenPGP: true
saveServer: true
});
this.canGnuPG = Settings.capa(Capa.GnuPG);
this.canOpenPGP = Settings.capa(Capa.OpenPGP);
this.key.subscribe(() => {
this.keyError(false);
@ -50,8 +49,7 @@ class AddOpenPgpKeyPopupView extends AbstractViewPopup {
count = 30,
done = false;
// eslint-disable-next-line max-len
const reg = /[-]{3,6}BEGIN[\s]PGP[\s](PRIVATE|PUBLIC)[\s]KEY[\s]BLOCK[-]{3,6}[\s\S]+?[-]{3,6}END[\s]PGP[\s](PRIVATE|PUBLIC)[\s]KEY[\s]BLOCK[-]{3,6}/gi,
keyring = PgpUserStore.openpgpKeyring;
const reg = /[-]{3,6}BEGIN[\s]PGP[\s](PRIVATE|PUBLIC)[\s]KEY[\s]BLOCK[-]{3,6}[\s\S]+?[-]{3,6}END[\s]PGP[\s](PRIVATE|PUBLIC)[\s]KEY[\s]BLOCK[-]{3,6}/gi;
do {
match = reg.exec(keyTrimmed);
@ -61,14 +59,15 @@ class AddOpenPgpKeyPopupView extends AbstractViewPopup {
if (this.saveGnuPG()) {
PgpUserStore.gnupgImportKey(this.key());
}
/*
if (this.canOpenPGP && this.saveOpenPGP()) {
if ('PRIVATE' === match[1]) {
err = keyring.privateKeys.importKey(match[0]);
err = PgpUserStore.openpgpKeyring.privateKeys.importKey(match[0]);
} else if ('PUBLIC' === match[1]) {
err = keyring.publicKeys.importKey(match[0]);
err = PgpUserStore.openpgpKeyring.publicKeys.importKey(match[0]);
}
}
*/
if (err) {
this.keyError(true);
this.keyErrorMessage(err && err[0] ? '' + err[0] : '');
@ -83,12 +82,6 @@ class AddOpenPgpKeyPopupView extends AbstractViewPopup {
}
} while (!done);
if (this.canOpenPGP && this.saveOpenPGP()) {
keyring.store();
}
// PgpUserStore.reloadOpenPgpKeys();
if (this.keyError()) {
return false;
}
@ -103,5 +96,3 @@ class AddOpenPgpKeyPopupView extends AbstractViewPopup {
this.keyErrorMessage('');
}
}
export { AddOpenPgpKeyPopupView, AddOpenPgpKeyPopupView as default };

View file

@ -182,7 +182,7 @@ export class MailMessageView extends AbstractViewRight {
pgpSigned: () => currentMessage() && !!currentMessage().pgpSigned(),
pgpEncrypted: () => currentMessage()
&& currentMessage().isPgpEncrypted(),
&& !!(currentMessage().pgpEncrypted() || currentMessage().isPgpEncrypted()),
pgpSupported: () => currentMessage() && PgpUserStore.isSupported(),
messageListOrViewLoading:
@ -625,7 +625,8 @@ export class MailMessageView extends AbstractViewRight {
}
pgpDecrypt(self) {
if (self.pgpEncrypted()) {
const pgpInfo = self.pgpEncrypted();
if (pgpInfo) {
const message = self.message();
if (window.mailvelope) {
/**
@ -657,10 +658,37 @@ export class MailMessageView extends AbstractViewRight {
});
}
/*
else {
// TODO: which key to decrypt, use pgpInfo.KeyIds
PgpUserStore.getKeyForDecrypting(message.email()).then(result => {
console.log({canPgpSign:result});
this.canPgpSign(!!result)
});
else if (window.openpgp) {
decryptMessage(message, recipients, fCallback)
}
else if (Settings.capa(Capa.GnuPG)) {
message.
let params = {
Folder: message.folder,
Uid: message.uid,
PartId: message.pgpEncrypted().PartId,
KeyId: '',
Passphrase: prompt("Passphrase", ''),
Data: '' // optional
}
rl.app.Remote.post('GnupgDecrypt', null, params)
.then(data => {
// TODO
console.dir(data);
})
.catch(error => {
// TODO
console.dir(error);
});
}
*/
}

View file

@ -151,7 +151,6 @@
"PGP_SIGNED_MESSAGE_DESC": "OpenPGP signed message",
"BUTTON_PGP_VERIFY": "click to verify",
"PGP_ENCRYPTED_MESSAGE_DESC": "OpenPGP encrypted message",
"BUTTON_PGP_DECRYPT": "click to decrypt",
"LINK_DOWNLOAD_AS_ZIP": "zip تنزيل كـ",
"SPAM_SCORE": "Spam Score",
"HAS_VIRUS_WARNING": "WARNING: virus detected"
@ -216,7 +215,6 @@
"ATTACHMENTS_UPLOAD_ERROR_DESC": "لم تنتهي عملية الإرفاق بعد",
"BUTTON_REQUEST_READ_RECEIPT": "اطلب اعلاماً بالقراءة",
"BUTTON_MARK_AS_IMPORTANT": "تحديده كـ هام",
"BUTTON_OPEN_PGP": "OpenPGP (Plain Text Only)",
"BUTTON_REQUEST_DSN": "اطلب اعلاماً بايصال البريد"
},
"POPUPS_ASK": {
@ -254,30 +252,16 @@
"DANGER_DESC_HTML_2": "في حال بدء العملية , فلا يمكن ايقافها او الغائها",
"TITLE_CLEARING_PROCESS": "...يتم دمج المجلد"
},
"POPUPS_IMPORT_OPEN_PGP_KEY": {
"TITLE_IMPORT_OPEN_PGP_KEY": "OpenPGP استيراد مفتاح",
"BUTTON_IMPORT_OPEN_PGP_KEY": "استيراد"
},
"POPUPS_VIEW_OPEN_PGP_KEY": {
"TITLE_VIEW_OPEN_PGP_KEY": "عرض OpenPGP key",
"BUTTON_SELECT": "تحديد"
},
"POPUPS_GENERATE_OPEN_PGP_KEYS": {
"TITLE_GENERATE_OPEN_PGP_KEYS": "OpenPGP توليد مفتاح",
"LABEL_KEY_BIT_LENGTH": "طول المفتاح",
"BUTTON_GENERATE_OPEN_PGP_KEYS": "قم بالتوليد"
},
"POPUPS_COMPOSE_OPEN_PGP": {
"TITLE_COMPOSE_OPEN_PGP": "OpenPGP Sign\/Encrypt",
"OPENPGP": {
"POPUP_IMPORT_TITLE": "OpenPGP استيراد مفتاح",
"POPUP_IMPORT_BUTTON": "استيراد",
"POPUP_VIEW_TITLE": "عرض OpenPGP key",
"POPUP_VIEW_BUTTON": "تحديد",
"POPUP_GENERATE_TITLE": "OpenPGP توليد مفتاح",
"POPUP_GENERATE_BUTTON": "قم بالتوليد",
"LABEL_KEY_TYPE": "Type",
"LABEL_SIGN": "تسجيل",
"LABEL_ENCRYPT": "تشفير",
"BUTTON_SIGN": "تسجيل",
"BUTTON_ENCRYPT": "تشفير",
"BUTTON_SIGN_AND_ENCRYPT": "سجل و قم بالتشفير"
},
"POPUPS_MESSAGE_OPEN_PGP": {
"TITLE_MESSAGE_OPEN_PGP": "OpenPGP فك تشفير",
"LABEL_KEY": "مفتاح خاص",
"BUTTON_DECRYPT": "فك تشفير"
},
"POPUPS_FILTER": {
@ -469,7 +453,6 @@
"BUTTON_GENERATE_OPEN_PGP_KEYS": "OpenPGP توليد مفتاح",
"TITLE_PRIVATE": "خاص",
"TITLE_PUBLIC": "عام",
"GENERATE_ONLY_HTTPS": "HTTPS فقط",
"LABEL_ALLOW_DRAFT_AUTOSAVE": "Automatically save draft"
},
"SHORTCUTS_HELP": {

View file

@ -151,7 +151,6 @@
"PGP_SIGNED_MESSAGE_DESC": "Подписано с OpenPGP",
"BUTTON_PGP_VERIFY": "кликни за проверка",
"PGP_ENCRYPTED_MESSAGE_DESC": "Шифровано с OpenPGP",
"BUTTON_PGP_DECRYPT": "кликни за проверка",
"LINK_DOWNLOAD_AS_ZIP": "Свали като ZIP файл",
"SPAM_SCORE": "Spam Score",
"HAS_VIRUS_WARNING": "WARNING: virus detected"
@ -216,7 +215,6 @@
"ATTACHMENTS_UPLOAD_ERROR_DESC": "Все още не са качени всички прикрепени файлове",
"BUTTON_REQUEST_READ_RECEIPT": "Поискайте разписка за прочитане на съобщението",
"BUTTON_MARK_AS_IMPORTANT": "Отбележи като важно",
"BUTTON_OPEN_PGP": "OpenPGP (Чист текст)",
"BUTTON_REQUEST_DSN": "Уведомяване при доставка"
},
"POPUPS_ASK": {
@ -254,30 +252,16 @@
"DANGER_DESC_HTML_2": "Веднъж започнат, този процес не може да бъде прекратен или отказан.",
"TITLE_CLEARING_PROCESS": "Прочистване на папката..."
},
"POPUPS_IMPORT_OPEN_PGP_KEY": {
"TITLE_IMPORT_OPEN_PGP_KEY": "Внасяне на OpenPGP ключ",
"BUTTON_IMPORT_OPEN_PGP_KEY": "Внеси"
},
"POPUPS_VIEW_OPEN_PGP_KEY": {
"TITLE_VIEW_OPEN_PGP_KEY": "Виж OpenPGP ключа",
"BUTTON_SELECT": "Избери"
},
"POPUPS_GENERATE_OPEN_PGP_KEYS": {
"TITLE_GENERATE_OPEN_PGP_KEYS": "Създаване на OpenPGP ключове",
"LABEL_KEY_BIT_LENGTH": "Дължина на ключа",
"BUTTON_GENERATE_OPEN_PGP_KEYS": "Създай"
},
"POPUPS_COMPOSE_OPEN_PGP": {
"TITLE_COMPOSE_OPEN_PGP": "Подпиши\/шифровай с OpenPGP",
"OPENPGP": {
"POPUP_IMPORT_TITLE": "Внасяне на OpenPGP ключ",
"POPUP_IMPORT_BUTTON": "Внеси",
"POPUP_VIEW_TITLE": "Виж OpenPGP ключа",
"POPUP_VIEW_BUTTON": "Избери",
"POPUP_GENERATE_TITLE": "Създаване на OpenPGP ключове",
"POPUP_GENERATE_BUTTON": "Създай",
"LABEL_KEY_TYPE": "Type",
"LABEL_SIGN": "Подпиши",
"LABEL_ENCRYPT": "Шифровай",
"BUTTON_SIGN": "Подпиши",
"BUTTON_ENCRYPT": "Шифровай",
"BUTTON_SIGN_AND_ENCRYPT": "Подпиши и шифровай"
},
"POPUPS_MESSAGE_OPEN_PGP": {
"TITLE_MESSAGE_OPEN_PGP": "Дешифриране с OpenPGP",
"LABEL_KEY": "Частен ключ",
"BUTTON_DECRYPT": "Дешифрирай"
},
"POPUPS_FILTER": {
@ -469,7 +453,6 @@
"BUTTON_GENERATE_OPEN_PGP_KEYS": "Генерирай OpenPGP ключ",
"TITLE_PRIVATE": "Частен",
"TITLE_PUBLIC": "Публичен",
"GENERATE_ONLY_HTTPS": "Само през HTTPS",
"LABEL_ALLOW_DRAFT_AUTOSAVE": "Автоматично запазване на чернова"
},
"SHORTCUTS_HELP": {

View file

@ -151,7 +151,6 @@
"PGP_SIGNED_MESSAGE_DESC": "Zpráva podepsaná OpenPGP",
"BUTTON_PGP_VERIFY": "klikněte pro ověření",
"PGP_ENCRYPTED_MESSAGE_DESC": "Zpráva šifrovaná OpenPGP",
"BUTTON_PGP_DECRYPT": "klikněte pro dešifraci",
"LINK_DOWNLOAD_AS_ZIP": "Stáhnout jako zip",
"SPAM_SCORE": "Spam Score",
"HAS_VIRUS_WARNING": "WARNING: virus detected"
@ -216,7 +215,6 @@
"ATTACHMENTS_UPLOAD_ERROR_DESC": "Některé přílohy ještě nebyly nahrány",
"BUTTON_REQUEST_READ_RECEIPT": "Vyžádat si potvrzení o přečtení",
"BUTTON_MARK_AS_IMPORTANT": "Označit jako důležité",
"BUTTON_OPEN_PGP": "OpenPGP (jen prostý text)",
"BUTTON_REQUEST_DSN": "Vyžádat si potvrzení o přijetí"
},
"POPUPS_ASK": {
@ -254,30 +252,16 @@
"DANGER_DESC_HTML_2": "Tento proces není možné přerušit.",
"TITLE_CLEARING_PROCESS": "Odstraňuje se složka..."
},
"POPUPS_IMPORT_OPEN_PGP_KEY": {
"TITLE_IMPORT_OPEN_PGP_KEY": "Import OpenPGP klíče",
"BUTTON_IMPORT_OPEN_PGP_KEY": "Import"
},
"POPUPS_VIEW_OPEN_PGP_KEY": {
"TITLE_VIEW_OPEN_PGP_KEY": "Zobrazit OpenPGP klíč",
"BUTTON_SELECT": "Vybrat"
},
"POPUPS_GENERATE_OPEN_PGP_KEYS": {
"TITLE_GENERATE_OPEN_PGP_KEYS": "Generovat OpenPGP klíče",
"LABEL_KEY_BIT_LENGTH": "Délka klíče",
"BUTTON_GENERATE_OPEN_PGP_KEYS": "Generovat"
},
"POPUPS_COMPOSE_OPEN_PGP": {
"TITLE_COMPOSE_OPEN_PGP": "OpenPGP Podpis\/Šifrování",
"OPENPGP": {
"POPUP_IMPORT_TITLE": "Import OpenPGP klíče",
"POPUP_IMPORT_BUTTON": "Import",
"POPUP_VIEW_TITLE": "Zobrazit OpenPGP klíč",
"POPUP_VIEW_BUTTON": "Vybrat",
"POPUP_GENERATE_TITLE": "Generovat OpenPGP klíče",
"POPUP_GENERATE_BUTTON": "Generovat",
"LABEL_KEY_TYPE": "Type",
"LABEL_SIGN": "Podpis",
"LABEL_ENCRYPT": "Šifrování",
"BUTTON_SIGN": "Podepsat",
"BUTTON_ENCRYPT": "Šifrovat",
"BUTTON_SIGN_AND_ENCRYPT": "Podepsat a šifrovat"
},
"POPUPS_MESSAGE_OPEN_PGP": {
"TITLE_MESSAGE_OPEN_PGP": "OpenPGP Dešifrování",
"LABEL_KEY": "Soukromý klíč",
"BUTTON_DECRYPT": "Dešifrovat"
},
"POPUPS_FILTER": {
@ -469,7 +453,6 @@
"BUTTON_GENERATE_OPEN_PGP_KEYS": "Generovat OpenPGP klíče",
"TITLE_PRIVATE": "Soukromý",
"TITLE_PUBLIC": "Veřejný",
"GENERATE_ONLY_HTTPS": "Pouze HTTPS",
"LABEL_ALLOW_DRAFT_AUTOSAVE": "Automaticky uložit koncept"
},
"SHORTCUTS_HELP": {

View file

@ -151,7 +151,6 @@
"PGP_SIGNED_MESSAGE_DESC": "OpenPGP signeret meddelelse",
"BUTTON_PGP_VERIFY": "tryk for at verificere",
"PGP_ENCRYPTED_MESSAGE_DESC": "OpenPGP krypteret meddelelse",
"BUTTON_PGP_DECRYPT": "tryk for at dekryptere",
"LINK_DOWNLOAD_AS_ZIP": "Hent som zip-fil",
"SPAM_SCORE": "Spam Score",
"HAS_VIRUS_WARNING": "WARNING: virus detected"
@ -216,7 +215,6 @@
"ATTACHMENTS_UPLOAD_ERROR_DESC": "Overførsel af vedhæftninger igang.",
"BUTTON_REQUEST_READ_RECEIPT": "Bed om kvittering for læsning",
"BUTTON_MARK_AS_IMPORTANT": "Markér som vigtig",
"BUTTON_OPEN_PGP": "OpenPGP (kun plain tekst)",
"BUTTON_REQUEST_DSN": "Bed om kvittering for modtagelse"
},
"POPUPS_ASK": {
@ -254,30 +252,16 @@
"DANGER_DESC_HTML_2": "Handlingen kan ikke afbrydes når den er startet.",
"TITLE_CLEARING_PROCESS": "Tømmer mappe..."
},
"POPUPS_IMPORT_OPEN_PGP_KEY": {
"TITLE_IMPORT_OPEN_PGP_KEY": "Importer OpenPGP nøgle",
"BUTTON_IMPORT_OPEN_PGP_KEY": "Importer"
},
"POPUPS_VIEW_OPEN_PGP_KEY": {
"TITLE_VIEW_OPEN_PGP_KEY": "Vis OpenPGP nøgle",
"BUTTON_SELECT": "Vælg"
},
"POPUPS_GENERATE_OPEN_PGP_KEYS": {
"TITLE_GENERATE_OPEN_PGP_KEYS": "Generér OpenPGP nøgler",
"LABEL_KEY_BIT_LENGTH": "Nøglelængde",
"BUTTON_GENERATE_OPEN_PGP_KEYS": "Generér"
},
"POPUPS_COMPOSE_OPEN_PGP": {
"TITLE_COMPOSE_OPEN_PGP": "OpenPGP signér\/krypter",
"OPENPGP": {
"POPUP_IMPORT_TITLE": "Importer OpenPGP nøgle",
"POPUP_IMPORT_BUTTON": "Importer",
"POPUP_VIEW_TITLE": "Vis OpenPGP nøgle",
"POPUP_VIEW_BUTTON": "Vælg",
"POPUP_GENERATE_TITLE": "Generér OpenPGP nøgler",
"POPUP_GENERATE_BUTTON": "Generér",
"LABEL_KEY_TYPE": "Type",
"LABEL_SIGN": "Signér",
"LABEL_ENCRYPT": "Krypter",
"BUTTON_SIGN": "Signér",
"BUTTON_ENCRYPT": "Krypter",
"BUTTON_SIGN_AND_ENCRYPT": "Signér og krypter"
},
"POPUPS_MESSAGE_OPEN_PGP": {
"TITLE_MESSAGE_OPEN_PGP": "OpenPGP dekrypter",
"LABEL_KEY": "Privat nøgle",
"BUTTON_DECRYPT": "Dekrypter"
},
"POPUPS_FILTER": {
@ -469,7 +453,6 @@
"BUTTON_GENERATE_OPEN_PGP_KEYS": "Generer OpenPGP nøgler",
"TITLE_PRIVATE": "Privat",
"TITLE_PUBLIC": "Offentlig",
"GENERATE_ONLY_HTTPS": "Kun HTTPS",
"LABEL_ALLOW_DRAFT_AUTOSAVE": "Gem kladde automatisk"
},
"SHORTCUTS_HELP": {

View file

@ -151,7 +151,6 @@
"PGP_SIGNED_MESSAGE_DESC": "OpenPGP-signierte Nachricht",
"BUTTON_PGP_VERIFY": "klicken, um zu überprüfen",
"PGP_ENCRYPTED_MESSAGE_DESC": "OpenPGP-verschlüsselte Nachricht",
"BUTTON_PGP_DECRYPT": "klicken, um zu entschlüsseln",
"LINK_DOWNLOAD_AS_ZIP": "Als ZIP-Datei herunterladen",
"SPAM_SCORE": "Spam-Score",
"HAS_VIRUS_WARNING": "WARNUNG: Virus erkannt"
@ -216,7 +215,6 @@
"ATTACHMENTS_UPLOAD_ERROR_DESC": "Es wurden noch nicht alle Anhänge hochgeladen.",
"BUTTON_REQUEST_READ_RECEIPT": "Empfangsbestätigung anfordern",
"BUTTON_MARK_AS_IMPORTANT": "Als Wichtig markieren",
"BUTTON_OPEN_PGP": "OpenPGP (nur bei unformatiertem Text)",
"BUTTON_REQUEST_DSN": "Übermittlungsstatus anfordern"
},
"POPUPS_ASK": {
@ -254,30 +252,16 @@
"DANGER_DESC_HTML_2": "Einmal begonnen, kann dieser Vorgang nicht mehr abgebrochen oder beendet werden.",
"TITLE_CLEARING_PROCESS": "Ordner wird gelöscht ..."
},
"POPUPS_IMPORT_OPEN_PGP_KEY": {
"TITLE_IMPORT_OPEN_PGP_KEY": "OpenPGP-Schlüssel importieren",
"BUTTON_IMPORT_OPEN_PGP_KEY": "Importieren"
},
"POPUPS_VIEW_OPEN_PGP_KEY": {
"TITLE_VIEW_OPEN_PGP_KEY": "OpenPGP-Schlüssel anzeigen",
"BUTTON_SELECT": "Auswählen"
},
"POPUPS_GENERATE_OPEN_PGP_KEYS": {
"TITLE_GENERATE_OPEN_PGP_KEYS": "OpenPGP-Schlüssel generieren",
"LABEL_KEY_BIT_LENGTH": "Schlüssellänge",
"BUTTON_GENERATE_OPEN_PGP_KEYS": "Generieren"
},
"POPUPS_COMPOSE_OPEN_PGP": {
"TITLE_COMPOSE_OPEN_PGP": "OpenPGP unterschreiben\/verschlüsseln",
"OPENPGP": {
"POPUP_IMPORT_TITLE": "OpenPGP-Schlüssel importieren",
"POPUP_IMPORT_BUTTON": "Importieren",
"POPUP_VIEW_TITLE": "OpenPGP-Schlüssel anzeigen",
"POPUP_VIEW_BUTTON": "Auswählen",
"POPUP_GENERATE_TITLE": "OpenPGP-Schlüssel generieren",
"POPUP_GENERATE_BUTTON": "Generieren",
"LABEL_KEY_TYPE": "Type",
"LABEL_SIGN": "Unterschrift",
"LABEL_ENCRYPT": "Verschlüsselung",
"BUTTON_SIGN": "Unterschreiben",
"BUTTON_ENCRYPT": "Verschlüsseln",
"BUTTON_SIGN_AND_ENCRYPT": "Unterschreiben und verschlüsseln"
},
"POPUPS_MESSAGE_OPEN_PGP": {
"TITLE_MESSAGE_OPEN_PGP": "OpenPGP Decrypt",
"LABEL_KEY": "Private Key",
"BUTTON_DECRYPT": "Decrypt"
},
"POPUPS_FILTER": {
@ -469,7 +453,6 @@
"BUTTON_GENERATE_OPEN_PGP_KEYS": "OpenPGP-Schlüssel generieren",
"TITLE_PRIVATE": "Privat",
"TITLE_PUBLIC": "Öffentlich",
"GENERATE_ONLY_HTTPS": "Nur HTTPS",
"LABEL_ALLOW_DRAFT_AUTOSAVE": "Automatically save draft"
},
"SHORTCUTS_HELP": {

View file

@ -151,7 +151,6 @@
"PGP_SIGNED_MESSAGE_DESC": "Μήνυμα υπογεγραμμένο με OpenPGP",
"BUTTON_PGP_VERIFY": "κάντε κλικ για έλεγχο",
"PGP_ENCRYPTED_MESSAGE_DESC": "Μήνυμα κωδικοποιημένο με OpenPGP",
"BUTTON_PGP_DECRYPT": "κάντε κλίκ για αποκωδικοποίηση",
"LINK_DOWNLOAD_AS_ZIP": "Μεταφόρτωση σαν zip",
"SPAM_SCORE": "Spam Score",
"HAS_VIRUS_WARNING": "WARNING: virus detected"
@ -216,7 +215,6 @@
"ATTACHMENTS_UPLOAD_ERROR_DESC": "Δεν έχουν μεταφορτωθεί ακόμη όλα τα συνημμένα.",
"BUTTON_REQUEST_READ_RECEIPT": "Ζητήστε αποδεικτικό ανάγνωσης",
"BUTTON_MARK_AS_IMPORTANT": "Σημειώστε το σαν σημαντικό",
"BUTTON_OPEN_PGP": "OpenPGP (Απλό κείμενο μόνο)",
"BUTTON_REQUEST_DSN": "Ζητήστε αποδεικτικό παράδοσης"
},
"POPUPS_ASK": {
@ -254,30 +252,16 @@
"DANGER_DESC_HTML_2": "Αφού ξεκινήσει, η διαδικασία δεν σταματά ή ακυρώνεται.",
"TITLE_CLEARING_PROCESS": "Διαγραφή όλων των μηνυμάτων στο φάκελο..."
},
"POPUPS_IMPORT_OPEN_PGP_KEY": {
"TITLE_IMPORT_OPEN_PGP_KEY": "Εισαγωγή κλειδιού OpenPGP",
"BUTTON_IMPORT_OPEN_PGP_KEY": "Εισαγωγή"
},
"POPUPS_VIEW_OPEN_PGP_KEY": {
"TITLE_VIEW_OPEN_PGP_KEY": "Προβολή κλειδιού OpenPGP",
"BUTTON_SELECT": "Επιλογή"
},
"POPUPS_GENERATE_OPEN_PGP_KEYS": {
"TITLE_GENERATE_OPEN_PGP_KEYS": "Δημιουργία κλειδιών OpenPGP",
"LABEL_KEY_BIT_LENGTH": "Μήκος κλειδιού",
"BUTTON_GENERATE_OPEN_PGP_KEYS": "Δημιουργία"
},
"POPUPS_COMPOSE_OPEN_PGP": {
"TITLE_COMPOSE_OPEN_PGP": "OpenPGP Υπογραφή\/Κρυπρογράφηση",
"OPENPGP": {
"POPUP_IMPORT_TITLE": "Εισαγωγή κλειδιού OpenPGP",
"POPUP_IMPORT_BUTTON": "Εισαγωγή",
"POPUP_VIEW_TITLE": "Προβολή κλειδιού OpenPGP",
"POPUP_VIEW_BUTTON": "Επιλογή",
"POPUP_GENERATE_TITLE": "Δημιουργία κλειδιών OpenPGP",
"POPUP_GENERATE_BUTTON": "Δημιουργία",
"LABEL_KEY_TYPE": "Type",
"LABEL_SIGN": "Υπογραφή",
"LABEL_ENCRYPT": "Κρυπτογράφηση",
"BUTTON_SIGN": "Υπογραφή",
"BUTTON_ENCRYPT": "Κρυπτογράφηση",
"BUTTON_SIGN_AND_ENCRYPT": "Υπογραφή και κρυπτογράφηση"
},
"POPUPS_MESSAGE_OPEN_PGP": {
"TITLE_MESSAGE_OPEN_PGP": "Αποκρυπτογράφηση OpenPGP",
"LABEL_KEY": "Προσωπικό κλειδί",
"BUTTON_DECRYPT": "Αποκρυπτογράφηση"
},
"POPUPS_FILTER": {
@ -469,7 +453,6 @@
"BUTTON_GENERATE_OPEN_PGP_KEYS": "Generate OpenPGP Keys",
"TITLE_PRIVATE": "Private",
"TITLE_PUBLIC": "Public",
"GENERATE_ONLY_HTTPS": "HTTPS only",
"LABEL_ALLOW_DRAFT_AUTOSAVE": "Automatically save draft"
},
"SHORTCUTS_HELP": {

View file

@ -151,7 +151,6 @@
"PGP_SIGNED_MESSAGE_DESC": "OpenPGP signed message",
"BUTTON_PGP_VERIFY": "click to verify",
"PGP_ENCRYPTED_MESSAGE_DESC": "OpenPGP encrypted message",
"BUTTON_PGP_DECRYPT": "click to decrypt",
"LINK_DOWNLOAD_AS_ZIP": "Download as zip",
"SPAM_SCORE": "Spam Score",
"HAS_VIRUS_WARNING": "WARNING: virus detected"
@ -216,7 +215,6 @@
"ATTACHMENTS_UPLOAD_ERROR_DESC": "Not all attachments have been uploaded yet.",
"BUTTON_REQUEST_READ_RECEIPT": "Request a read receipt",
"BUTTON_MARK_AS_IMPORTANT": "Mark as important",
"BUTTON_OPEN_PGP": "OpenPGP (Plain Text Only)",
"BUTTON_REQUEST_DSN": "Request a delivery receipt"
},
"POPUPS_ASK": {
@ -254,30 +252,16 @@
"DANGER_DESC_HTML_2": "Once started, the process cannot be aborted or cancelled.",
"TITLE_CLEARING_PROCESS": "Purging the folder..."
},
"POPUPS_IMPORT_OPEN_PGP_KEY": {
"TITLE_IMPORT_OPEN_PGP_KEY": "Import OpenPGP key",
"BUTTON_IMPORT_OPEN_PGP_KEY": "Import"
},
"POPUPS_VIEW_OPEN_PGP_KEY": {
"TITLE_VIEW_OPEN_PGP_KEY": "View OpenPGP key",
"BUTTON_SELECT": "Select"
},
"POPUPS_GENERATE_OPEN_PGP_KEYS": {
"TITLE_GENERATE_OPEN_PGP_KEYS": "Generate OpenPGP keys",
"LABEL_KEY_BIT_LENGTH": "Key length",
"BUTTON_GENERATE_OPEN_PGP_KEYS": "Generate"
},
"POPUPS_COMPOSE_OPEN_PGP": {
"TITLE_COMPOSE_OPEN_PGP": "OpenPGP Sign\/Encrypt",
"OPENPGP": {
"POPUP_IMPORT_TITLE": "Import OpenPGP key",
"POPUP_IMPORT_BUTTON": "Import",
"POPUP_VIEW_TITLE": "View OpenPGP key",
"POPUP_VIEW_BUTTON": "Select",
"POPUP_GENERATE_TITLE": "Generate OpenPGP key",
"POPUP_GENERATE_BUTTON": "Generate",
"LABEL_KEY_TYPE": "Type",
"LABEL_SIGN": "Sign",
"LABEL_ENCRYPT": "Encrypt",
"BUTTON_SIGN": "Sign",
"BUTTON_ENCRYPT": "Encrypt",
"BUTTON_SIGN_AND_ENCRYPT": "Sign and encrypt"
},
"POPUPS_MESSAGE_OPEN_PGP": {
"TITLE_MESSAGE_OPEN_PGP": "OpenPGP Decrypt",
"LABEL_KEY": "Private Key",
"BUTTON_DECRYPT": "Decrypt"
},
"POPUPS_FILTER": {
@ -469,7 +453,6 @@
"BUTTON_GENERATE_OPEN_PGP_KEYS": "Generate OpenPGP Keys",
"TITLE_PRIVATE": "Private",
"TITLE_PUBLIC": "Public",
"GENERATE_ONLY_HTTPS": "HTTPS only",
"LABEL_ALLOW_DRAFT_AUTOSAVE": "Automatically save draft"
},
"SHORTCUTS_HELP": {

View file

@ -151,7 +151,6 @@
"PGP_SIGNED_MESSAGE_DESC": "Mensaje firmado mediante OpenPGP",
"BUTTON_PGP_VERIFY": "click para verificar",
"PGP_ENCRYPTED_MESSAGE_DESC": "Mensaje cifrado mediante OpenPGP",
"BUTTON_PGP_DECRYPT": "click para desencriptar",
"LINK_DOWNLOAD_AS_ZIP": "Descargar todo (archivo ZIP)",
"SPAM_SCORE": "Puntuación de spam",
"HAS_VIRUS_WARNING": "ADVERTENCIA: virus detectado"
@ -216,7 +215,6 @@
"ATTACHMENTS_UPLOAD_ERROR_DESC": "No se han subido todos los archivos adjuntos.",
"BUTTON_REQUEST_READ_RECEIPT": "Solicitar confirmación de lectura",
"BUTTON_MARK_AS_IMPORTANT": "Marcar como importante",
"BUTTON_OPEN_PGP": "OpenPGP (solo texto plano)",
"BUTTON_REQUEST_DSN": "Solicitar una confirmación de entrega"
},
"POPUPS_ASK": {
@ -254,30 +252,16 @@
"DANGER_DESC_HTML_2": "Una vez comenzado el proceso no se puede abortar ni cancelar.",
"TITLE_CLEARING_PROCESS": "Purgando carpeta..."
},
"POPUPS_IMPORT_OPEN_PGP_KEY": {
"TITLE_IMPORT_OPEN_PGP_KEY": "Importar clave OpenPGP",
"BUTTON_IMPORT_OPEN_PGP_KEY": "Importar"
},
"POPUPS_VIEW_OPEN_PGP_KEY": {
"TITLE_VIEW_OPEN_PGP_KEY": "Ver clave OpenPGP",
"BUTTON_SELECT": "Seleccionar"
},
"POPUPS_GENERATE_OPEN_PGP_KEYS": {
"TITLE_GENERATE_OPEN_PGP_KEYS": "Generar clave OpenPGP",
"LABEL_KEY_BIT_LENGTH": "Longitud de la clave",
"BUTTON_GENERATE_OPEN_PGP_KEYS": "Generar"
},
"POPUPS_COMPOSE_OPEN_PGP": {
"TITLE_COMPOSE_OPEN_PGP": "Firmar\/Cifrar con OpenPGP",
"OPENPGP": {
"POPUP_IMPORT_TITLE": "Importar clave OpenPGP",
"POPUP_IMPORT_BUTTON": "Importar",
"POPUP_VIEW_TITLE": "Ver clave OpenPGP",
"POPUP_VIEW_BUTTON": "Seleccionar",
"POPUP_GENERATE_TITLE": "Generar clave OpenPGP",
"POPUP_GENERATE_BUTTON": "Generar",
"LABEL_KEY_TYPE": "Type",
"LABEL_SIGN": "Firmar",
"LABEL_ENCRYPT": "Encriptar",
"BUTTON_SIGN": "Firmar",
"BUTTON_ENCRYPT": "Encriptar",
"BUTTON_SIGN_AND_ENCRYPT": "Firmar y encriptar"
},
"POPUPS_MESSAGE_OPEN_PGP": {
"TITLE_MESSAGE_OPEN_PGP": "Descifrar OpenPGP",
"LABEL_KEY": "Clave privada",
"BUTTON_DECRYPT": "Descifrar"
},
"POPUPS_FILTER": {
@ -469,7 +453,6 @@
"BUTTON_GENERATE_OPEN_PGP_KEYS": "Generar llaves OpenPGP",
"TITLE_PRIVATE": "Privado",
"TITLE_PUBLIC": "Público",
"GENERATE_ONLY_HTTPS": "Solo HTTPS",
"LABEL_ALLOW_DRAFT_AUTOSAVE": "Automatically save draft"
},
"SHORTCUTS_HELP": {

View file

@ -151,7 +151,6 @@
"PGP_SIGNED_MESSAGE_DESC": "OpenPGP abil signeeritud kiri",
"BUTTON_PGP_VERIFY": "kliki verifitseerimiseks",
"PGP_ENCRYPTED_MESSAGE_DESC": "OpenPGP abil krüpteeritud kiri",
"BUTTON_PGP_DECRYPT": "kliki dekrüpteerimiseks",
"LINK_DOWNLOAD_AS_ZIP": "Laadi alla .zip failina",
"SPAM_SCORE": "Spam Score",
"HAS_VIRUS_WARNING": "WARNING: virus detected"
@ -216,7 +215,6 @@
"ATTACHMENTS_UPLOAD_ERROR_DESC": "Kõiki manuseid ei ole veel üles laetud.",
"BUTTON_REQUEST_READ_RECEIPT": "Palu lugemise kohta kinnitust",
"BUTTON_MARK_AS_IMPORTANT": "Tähista olulisena",
"BUTTON_OPEN_PGP": "OpenPGP (Vaid lihttekstina)",
"BUTTON_REQUEST_DSN": "Palu kättesaamise kohta kinnitust"
},
"POPUPS_ASK": {
@ -254,30 +252,16 @@
"DANGER_DESC_HTML_2": "Juba alustatud protsessi ei saa tühistada või katkestada.",
"TITLE_CLEARING_PROCESS": "Tühjendan kausta..."
},
"POPUPS_IMPORT_OPEN_PGP_KEY": {
"TITLE_IMPORT_OPEN_PGP_KEY": "Impordi OpenPGP võti",
"BUTTON_IMPORT_OPEN_PGP_KEY": "Impordi"
},
"POPUPS_VIEW_OPEN_PGP_KEY": {
"TITLE_VIEW_OPEN_PGP_KEY": "Vaata OpenPGP võtit",
"BUTTON_SELECT": "Vali"
},
"POPUPS_GENERATE_OPEN_PGP_KEYS": {
"TITLE_GENERATE_OPEN_PGP_KEYS": "Genereeri OpenPGP võtmed",
"LABEL_KEY_BIT_LENGTH": "Võtme pikkus",
"BUTTON_GENERATE_OPEN_PGP_KEYS": "Genereeri"
},
"POPUPS_COMPOSE_OPEN_PGP": {
"TITLE_COMPOSE_OPEN_PGP": "OpenPGP allkirjastamine\/krüpteerimine",
"OPENPGP": {
"POPUP_IMPORT_TITLE": "Impordi OpenPGP võti",
"POPUP_IMPORT_BUTTON": "Impordi",
"POPUP_VIEW_TITLE": "Vaata OpenPGP võtit",
"POPUP_VIEW_BUTTON": "Vali",
"POPUP_GENERATE_TITLE": "Genereeri OpenPGP võtmed",
"POPUP_GENERATE_BUTTON": "Genereeri",
"LABEL_KEY_TYPE": "Type",
"LABEL_SIGN": "Allkirjasta",
"LABEL_ENCRYPT": "Krüpteeri",
"BUTTON_SIGN": "Allkirjasta",
"BUTTON_ENCRYPT": "Krüpteeri",
"BUTTON_SIGN_AND_ENCRYPT": "Allkirjasta ja krüpteeri"
},
"POPUPS_MESSAGE_OPEN_PGP": {
"TITLE_MESSAGE_OPEN_PGP": "OpenPGP dekrüpteerimine",
"LABEL_KEY": "Privaatne võti ",
"BUTTON_DECRYPT": "Dekrüpteeri"
},
"POPUPS_FILTER": {
@ -469,7 +453,6 @@
"BUTTON_GENERATE_OPEN_PGP_KEYS": "Genereeri OpenPGP võti",
"TITLE_PRIVATE": "Privaatne",
"TITLE_PUBLIC": "Avalik",
"GENERATE_ONLY_HTTPS": "Ainult HTTPS",
"LABEL_ALLOW_DRAFT_AUTOSAVE": "Automatically save draft"
},
"SHORTCUTS_HELP": {

View file

@ -151,7 +151,6 @@
"PGP_SIGNED_MESSAGE_DESC": "پیام توسط OpenPGP امضاء شد",
"BUTTON_PGP_VERIFY": "برای بررسی کلیک کنید",
"PGP_ENCRYPTED_MESSAGE_DESC": "پیام توسط OpenPGP رمزنگاری شد",
"BUTTON_PGP_DECRYPT": "برای خارج شدن از حالت رمز کلیک کنید",
"LINK_DOWNLOAD_AS_ZIP": "دریافت با پسوند zip",
"SPAM_SCORE": "Spam Score",
"HAS_VIRUS_WARNING": "WARNING: virus detected"
@ -216,7 +215,6 @@
"ATTACHMENTS_UPLOAD_ERROR_DESC": "همه پیوست‌ها هنوز بارگذاری نشده است.",
"BUTTON_REQUEST_READ_RECEIPT": "درخواست دریافت رسید خواندن",
"BUTTON_MARK_AS_IMPORTANT": "علامت زدن به عنوان مهم",
"BUTTON_OPEN_PGP": "OpenPGP (فقط متن ساده)",
"BUTTON_REQUEST_DSN": "درخواست دریافت رسید تحویل درمقصد"
},
"POPUPS_ASK": {
@ -254,30 +252,16 @@
"DANGER_DESC_HTML_2": "زمانی که این عملیات شروع شود قابل لغو یا انصراف نیست.",
"TITLE_CLEARING_PROCESS": "خالی کردن شاخه..."
},
"POPUPS_IMPORT_OPEN_PGP_KEY": {
"TITLE_IMPORT_OPEN_PGP_KEY": "واردکردن کلید OpenPGP",
"BUTTON_IMPORT_OPEN_PGP_KEY": "وارد‌کردن"
},
"POPUPS_VIEW_OPEN_PGP_KEY": {
"TITLE_VIEW_OPEN_PGP_KEY": "مشاهده کلید OpenGPG",
"BUTTON_SELECT": "انتخاب"
},
"POPUPS_GENERATE_OPEN_PGP_KEYS": {
"TITLE_GENERATE_OPEN_PGP_KEYS": "تولید کلید‌های OpenPGP",
"LABEL_KEY_BIT_LENGTH": "طول کلید",
"BUTTON_GENERATE_OPEN_PGP_KEYS": "تولید"
},
"POPUPS_COMPOSE_OPEN_PGP": {
"TITLE_COMPOSE_OPEN_PGP": "امضاء\/رمزنگاری OpenPGP",
"OPENPGP": {
"POPUP_IMPORT_TITLE": "واردکردن کلید OpenPGP",
"POPUP_IMPORT_BUTTON": "وارد‌کردن",
"POPUP_VIEW_TITLE": "مشاهده کلید OpenGPG",
"POPUP_VIEW_BUTTON": "انتخاب",
"POPUP_GENERATE_TITLE": "تولید کلید‌های OpenPGP",
"POPUP_GENERATE_BUTTON": "تولید",
"LABEL_KEY_TYPE": "Type",
"LABEL_SIGN": "امضاء",
"LABEL_ENCRYPT": "رمزنگاری",
"BUTTON_SIGN": "امضاء",
"BUTTON_ENCRYPT": "رمزنگاری",
"BUTTON_SIGN_AND_ENCRYPT": "امضاء و رمزنگاری"
},
"POPUPS_MESSAGE_OPEN_PGP": {
"TITLE_MESSAGE_OPEN_PGP": "رمزگشایی OpenPGP",
"LABEL_KEY": "کلید خصوصی",
"BUTTON_DECRYPT": "رمزگشایی"
},
"POPUPS_FILTER": {
@ -469,7 +453,6 @@
"BUTTON_GENERATE_OPEN_PGP_KEYS": "تولید کلیدهای OpenPGP",
"TITLE_PRIVATE": "خصوصی",
"TITLE_PUBLIC": "عمومی",
"GENERATE_ONLY_HTTPS": "تنها HTTPS",
"LABEL_ALLOW_DRAFT_AUTOSAVE": "ذخیره خودکار پیش‌نویس"
},
"SHORTCUTS_HELP": {

View file

@ -151,7 +151,6 @@
"PGP_SIGNED_MESSAGE_DESC": "OpenPGP allekirjoitettu viesti",
"BUTTON_PGP_VERIFY": "klikkaa verifioidaksesi",
"PGP_ENCRYPTED_MESSAGE_DESC": "OpenPGP salattu visti",
"BUTTON_PGP_DECRYPT": "klikkaa avataksesi salaus",
"LINK_DOWNLOAD_AS_ZIP": "Lataa zip-tiedostona",
"SPAM_SCORE": "Spam Score",
"HAS_VIRUS_WARNING": "WARNING: virus detected"
@ -216,7 +215,6 @@
"ATTACHMENTS_UPLOAD_ERROR_DESC": "Kaikkia liitetiedostoja ei ole vielä ladattu.",
"BUTTON_REQUEST_READ_RECEIPT": "Pyydä kuittaus",
"BUTTON_MARK_AS_IMPORTANT": "Merkitse tärkeäksi",
"BUTTON_OPEN_PGP": "OpenPGP (pelkkä teksti)",
"BUTTON_REQUEST_DSN": "Pyydä toimituskuittaus"
},
"POPUPS_ASK": {
@ -254,30 +252,16 @@
"DANGER_DESC_HTML_2": "Tätä toimintoa ei voi peruuttaa.",
"TITLE_CLEARING_PROCESS": "Tyhjennetään kansiota..."
},
"POPUPS_IMPORT_OPEN_PGP_KEY": {
"TITLE_IMPORT_OPEN_PGP_KEY": "Tuo OpenPGP avain",
"BUTTON_IMPORT_OPEN_PGP_KEY": "Tuo"
},
"POPUPS_VIEW_OPEN_PGP_KEY": {
"TITLE_VIEW_OPEN_PGP_KEY": "Näytä OpenPGP avain",
"BUTTON_SELECT": "Valitse"
},
"POPUPS_GENERATE_OPEN_PGP_KEYS": {
"TITLE_GENERATE_OPEN_PGP_KEYS": "Luo OpenPGP avain",
"LABEL_KEY_BIT_LENGTH": "Avaimen pituus",
"BUTTON_GENERATE_OPEN_PGP_KEYS": "Generoi"
},
"POPUPS_COMPOSE_OPEN_PGP": {
"TITLE_COMPOSE_OPEN_PGP": "OpenPGP Allekirjoitus\/Salaus",
"OPENPGP": {
"POPUP_IMPORT_TITLE": "Tuo OpenPGP avain",
"POPUP_IMPORT_BUTTON": "Tuo",
"POPUP_VIEW_TITLE": "Näytä OpenPGP avain",
"POPUP_VIEW_BUTTON": "Valitse",
"POPUP_GENERATE_TITLE": "Luo OpenPGP avain",
"POPUP_GENERATE_BUTTON": "Generoi",
"LABEL_KEY_TYPE": "Type",
"LABEL_SIGN": "Allekirjoita",
"LABEL_ENCRYPT": "Salaa",
"BUTTON_SIGN": "Allekirjoita",
"BUTTON_ENCRYPT": "Salaa",
"BUTTON_SIGN_AND_ENCRYPT": "Allekirjoita ja salaa"
},
"POPUPS_MESSAGE_OPEN_PGP": {
"TITLE_MESSAGE_OPEN_PGP": "Pura OpenPGP",
"LABEL_KEY": "Yksityinen avain",
"BUTTON_DECRYPT": "Pura"
},
"POPUPS_FILTER": {
@ -469,7 +453,6 @@
"BUTTON_GENERATE_OPEN_PGP_KEYS": "Luo OpenPGP avain",
"TITLE_PRIVATE": "Yksityinen",
"TITLE_PUBLIC": "Julkinen",
"GENERATE_ONLY_HTTPS": "Vain HTTPS",
"LABEL_ALLOW_DRAFT_AUTOSAVE": "Automatically save draft"
},
"SHORTCUTS_HELP": {

View file

@ -151,7 +151,6 @@
"PGP_SIGNED_MESSAGE_DESC": "Message signé par OpenPGP",
"BUTTON_PGP_VERIFY": "cliquer pour vérifier",
"PGP_ENCRYPTED_MESSAGE_DESC": "Message chiffré par OpenPGP",
"BUTTON_PGP_DECRYPT": "cliquer pour déchiffrer",
"LINK_DOWNLOAD_AS_ZIP": "Télécharger le zip",
"SPAM_SCORE": "Score de spam",
"HAS_VIRUS_WARNING": "ATTENTION : virus détecté"
@ -216,7 +215,6 @@
"ATTACHMENTS_UPLOAD_ERROR_DESC": "Toutes les pièces jointes n'ont pas encore été téléchargées",
"BUTTON_REQUEST_READ_RECEIPT": "Demander une confirmation de lecture",
"BUTTON_MARK_AS_IMPORTANT": "Marquer comme important",
"BUTTON_OPEN_PGP": "OpenPGP (Texte non formaté uniquement)",
"BUTTON_REQUEST_DSN": "Demander un accusé de réception"
},
"POPUPS_ASK": {
@ -254,30 +252,16 @@
"DANGER_DESC_HTML_2": "Une fois lancé, le processus ne peut pas être interrompu ou annulé.",
"TITLE_CLEARING_PROCESS": "Purge du dossier..."
},
"POPUPS_IMPORT_OPEN_PGP_KEY": {
"TITLE_IMPORT_OPEN_PGP_KEY": "Importer la clef OpenPGP",
"BUTTON_IMPORT_OPEN_PGP_KEY": "Importer"
},
"POPUPS_VIEW_OPEN_PGP_KEY": {
"TITLE_VIEW_OPEN_PGP_KEY": "Voir la clef OpenPGP",
"BUTTON_SELECT": "Sélectionner"
},
"POPUPS_GENERATE_OPEN_PGP_KEYS": {
"TITLE_GENERATE_OPEN_PGP_KEYS": "Générer les clés OpenPGP",
"LABEL_KEY_BIT_LENGTH": "Longueur de la clé",
"BUTTON_GENERATE_OPEN_PGP_KEYS": "Générer"
},
"POPUPS_COMPOSE_OPEN_PGP": {
"TITLE_COMPOSE_OPEN_PGP": "Signer\/chiffrer avec OpenPGP",
"OPENPGP": {
"POPUP_IMPORT_TITLE": "Importer la clef OpenPGP",
"POPUP_IMPORT_BUTTON": "Importer",
"POPUP_VIEW_TITLE": "Voir la clef OpenPGP",
"POPUP_VIEW_BUTTON": "Sélectionner",
"POPUP_GENERATE_TITLE": "Générer les clés OpenPGP",
"POPUP_GENERATE_BUTTON": "Générer",
"LABEL_KEY_TYPE": "Type",
"LABEL_SIGN": "Signer",
"LABEL_ENCRYPT": "Chiffer",
"BUTTON_SIGN": "Signer",
"BUTTON_ENCRYPT": "Chiffrer",
"BUTTON_SIGN_AND_ENCRYPT": "Signer et chiffrer"
},
"POPUPS_MESSAGE_OPEN_PGP": {
"TITLE_MESSAGE_OPEN_PGP": "OpenPGP Decrypt",
"LABEL_KEY": "Clé Privée",
"BUTTON_DECRYPT": "Déchiffrer"
},
"POPUPS_FILTER": {
@ -469,7 +453,6 @@
"BUTTON_GENERATE_OPEN_PGP_KEYS": "Générer les clés OpenPGP",
"TITLE_PRIVATE": "Privée",
"TITLE_PUBLIC": "Publique",
"GENERATE_ONLY_HTTPS": "HTTPS seulement",
"LABEL_ALLOW_DRAFT_AUTOSAVE": "Brouillon sauvegardé automatiquement"
},
"SHORTCUTS_HELP": {

View file

@ -151,7 +151,6 @@
"PGP_SIGNED_MESSAGE_DESC": "OpenPGP aláírt üzenet",
"BUTTON_PGP_VERIFY": "kattints az ellenőrzéshez",
"PGP_ENCRYPTED_MESSAGE_DESC": "OpenPGP kódolt üzenet",
"BUTTON_PGP_DECRYPT": "kattints a visszafejtéshez",
"LINK_DOWNLOAD_AS_ZIP": "Letöltés zip fájlként",
"SPAM_SCORE": "Spam Score",
"HAS_VIRUS_WARNING": "FIGYELEM: vírust észleltünk"
@ -216,7 +215,6 @@
"ATTACHMENTS_UPLOAD_ERROR_DESC": "Még nem lett feltöltve minden melléklet.",
"BUTTON_REQUEST_READ_RECEIPT": "Olvasási visszaigazolás kérése",
"BUTTON_MARK_AS_IMPORTANT": "Megjelölés fontosként",
"BUTTON_OPEN_PGP": "OpenPGP (csak egyszerű szöveg)",
"BUTTON_REQUEST_DSN": "Továbbítási visszaigazolás kérés"
},
"POPUPS_ASK": {
@ -254,30 +252,16 @@
"DANGER_DESC_HTML_2": "Ha egyszer elindult, a folyamatot nem lehet megszakítani.",
"TITLE_CLEARING_PROCESS": "Mappa ürítés..."
},
"POPUPS_IMPORT_OPEN_PGP_KEY": {
"TITLE_IMPORT_OPEN_PGP_KEY": "OpenPGP kulcs importálás",
"BUTTON_IMPORT_OPEN_PGP_KEY": "Importálás"
},
"POPUPS_VIEW_OPEN_PGP_KEY": {
"TITLE_VIEW_OPEN_PGP_KEY": "OpenPGP kulcs megtekintés",
"BUTTON_SELECT": "Kiválasztás"
},
"POPUPS_GENERATE_OPEN_PGP_KEYS": {
"TITLE_GENERATE_OPEN_PGP_KEYS": "OpenPGP kulcs generálás",
"LABEL_KEY_BIT_LENGTH": "Kulcs hossz",
"BUTTON_GENERATE_OPEN_PGP_KEYS": "Generálás"
},
"POPUPS_COMPOSE_OPEN_PGP": {
"TITLE_COMPOSE_OPEN_PGP": "OpenPGP aláírás\/titkosítás",
"OPENPGP": {
"POPUP_IMPORT_TITLE": "OpenPGP kulcs importálás",
"POPUP_IMPORT_BUTTON": "Importálás",
"POPUP_VIEW_TITLE": "OpenPGP kulcs megtekintés",
"POPUP_VIEW_BUTTON": "Kiválasztás",
"POPUP_GENERATE_TITLE": "OpenPGP kulcs generálás",
"POPUP_GENERATE_BUTTON": "Generálás",
"LABEL_KEY_TYPE": "Type",
"LABEL_SIGN": "Aláírás",
"LABEL_ENCRYPT": "Titkosítás",
"BUTTON_SIGN": "Aláírás",
"BUTTON_ENCRYPT": "Titkosítás",
"BUTTON_SIGN_AND_ENCRYPT": "Aláírás és titkosítás"
},
"POPUPS_MESSAGE_OPEN_PGP": {
"TITLE_MESSAGE_OPEN_PGP": "OpenPGP visszafejtés",
"LABEL_KEY": "Privát kulcs",
"BUTTON_DECRYPT": "Visszafejtés"
},
"POPUPS_FILTER": {
@ -469,7 +453,6 @@
"BUTTON_GENERATE_OPEN_PGP_KEYS": "OpenPGP kulcs generálás",
"TITLE_PRIVATE": "Privát",
"TITLE_PUBLIC": "Publikus",
"GENERATE_ONLY_HTTPS": "csak HTTPS",
"LABEL_ALLOW_DRAFT_AUTOSAVE": "Piszkozat automatikus mentése"
},
"SHORTCUTS_HELP": {

View file

@ -151,7 +151,6 @@
"PGP_SIGNED_MESSAGE_DESC": "Pesan bertanda-tangan OpenPGP",
"BUTTON_PGP_VERIFY": "klik untuk verifikasi",
"PGP_ENCRYPTED_MESSAGE_DESC": "Pesan terenkripsi OpenPGP",
"BUTTON_PGP_DECRYPT": "klik untuk mendekripsi",
"LINK_DOWNLOAD_AS_ZIP": "Unduh sebagai berkas zip",
"SPAM_SCORE": "Spam Score",
"HAS_VIRUS_WARNING": "WARNING: virus detected"
@ -216,7 +215,6 @@
"ATTACHMENTS_UPLOAD_ERROR_DESC": "Belum semua lampiran terunggah.",
"BUTTON_REQUEST_READ_RECEIPT": "Minta pemberitahuan telah dibaca",
"BUTTON_MARK_AS_IMPORTANT": "Tandai sebagai pesan penting",
"BUTTON_OPEN_PGP": "OpenPGP (Teks Biasa)",
"BUTTON_REQUEST_DSN": "Minta pemberitahuan berhasil kirim"
},
"POPUPS_ASK": {
@ -254,30 +252,16 @@
"DANGER_DESC_HTML_2": "Begitu dimulai, proses tidak dapat dibatalkan atau ditunda.",
"TITLE_CLEARING_PROCESS": "Membersihkan folder..."
},
"POPUPS_IMPORT_OPEN_PGP_KEY": {
"TITLE_IMPORT_OPEN_PGP_KEY": "Impor kunci OpenPGP",
"BUTTON_IMPORT_OPEN_PGP_KEY": "Impor"
},
"POPUPS_VIEW_OPEN_PGP_KEY": {
"TITLE_VIEW_OPEN_PGP_KEY": "Tampikan kunci OpenPGP",
"BUTTON_SELECT": "Pilih"
},
"POPUPS_GENERATE_OPEN_PGP_KEYS": {
"TITLE_GENERATE_OPEN_PGP_KEYS": "Buat kunci OpenPGP",
"LABEL_KEY_BIT_LENGTH": "Panjang kunci",
"BUTTON_GENERATE_OPEN_PGP_KEYS": "Buat"
},
"POPUPS_COMPOSE_OPEN_PGP": {
"TITLE_COMPOSE_OPEN_PGP": "OpenPGP Tandatangan\/Enkripsi",
"OPENPGP": {
"POPUP_IMPORT_TITLE": "Impor kunci OpenPGP",
"POPUP_IMPORT_BUTTON": "Impor",
"POPUP_VIEW_TITLE": "Tampikan kunci OpenPGP",
"POPUP_VIEW_BUTTON": "Pilih",
"POPUP_GENERATE_TITLE": "Buat kunci OpenPGP",
"POPUP_GENERATE_BUTTON": "Buat",
"LABEL_KEY_TYPE": "Type",
"LABEL_SIGN": "Tandatangan",
"LABEL_ENCRYPT": "Enkripsi",
"BUTTON_SIGN": "Tandatangani",
"BUTTON_ENCRYPT": "Enkripsi",
"BUTTON_SIGN_AND_ENCRYPT": "Tandatangani dan Enkripsi"
},
"POPUPS_MESSAGE_OPEN_PGP": {
"TITLE_MESSAGE_OPEN_PGP": "OpenPGP Deksipsi",
"LABEL_KEY": "Private Key",
"BUTTON_DECRYPT": "Deskripsi"
},
"POPUPS_FILTER": {
@ -469,7 +453,6 @@
"BUTTON_GENERATE_OPEN_PGP_KEYS": "Buat kunci OpenPGP",
"TITLE_PRIVATE": "Pribadi",
"TITLE_PUBLIC": "Publik",
"GENERATE_ONLY_HTTPS": "Hanya HTTPS",
"LABEL_ALLOW_DRAFT_AUTOSAVE": "Simpan konsep otomatis"
},
"SHORTCUTS_HELP": {

View file

@ -151,7 +151,6 @@
"PGP_SIGNED_MESSAGE_DESC": "Skeyti undirritað með OpenPGP",
"BUTTON_PGP_VERIFY": "smelltu til að sannvotta",
"PGP_ENCRYPTED_MESSAGE_DESC": "Skeyti dulritað með OpenPGP",
"BUTTON_PGP_DECRYPT": "smelltu til að afkóða",
"LINK_DOWNLOAD_AS_ZIP": "Sækja sem .zip skrá",
"SPAM_SCORE": "Spam Score",
"HAS_VIRUS_WARNING": "WARNING: virus detected"
@ -216,7 +215,6 @@
"ATTACHMENTS_UPLOAD_ERROR_DESC": "Ekki er búið að senda inn öll viðhengi.",
"BUTTON_REQUEST_READ_RECEIPT": "Biðja um staðfestingu á lestri",
"BUTTON_MARK_AS_IMPORTANT": "Merkja sem mikilvægt",
"BUTTON_OPEN_PGP": "OpenPGP (einungis hreinn texti)",
"BUTTON_REQUEST_DSN": "Biðja um staðfestingu á afhendingu"
},
"POPUPS_ASK": {
@ -254,30 +252,16 @@
"DANGER_DESC_HTML_2": "Það er ekki hægt að hætta við aðgerðina eftir að búið er að keyra hana.",
"TITLE_CLEARING_PROCESS": "Tæmi möppu..."
},
"POPUPS_IMPORT_OPEN_PGP_KEY": {
"TITLE_IMPORT_OPEN_PGP_KEY": "Flytja inn OpenPGP-lykil",
"BUTTON_IMPORT_OPEN_PGP_KEY": "Flytja inn"
},
"POPUPS_VIEW_OPEN_PGP_KEY": {
"TITLE_VIEW_OPEN_PGP_KEY": "Skoða OpenPGP-lykil",
"BUTTON_SELECT": "Velja"
},
"POPUPS_GENERATE_OPEN_PGP_KEYS": {
"TITLE_GENERATE_OPEN_PGP_KEYS": "Búa til OpenPGP-lykla",
"LABEL_KEY_BIT_LENGTH": "Lengd lykils",
"BUTTON_GENERATE_OPEN_PGP_KEYS": "Útbúa"
},
"POPUPS_COMPOSE_OPEN_PGP": {
"TITLE_COMPOSE_OPEN_PGP": "Undirrita\/Dulrita OpenPGP",
"OPENPGP": {
"POPUP_IMPORT_TITLE": "Flytja inn OpenPGP-lykil",
"POPUP_IMPORT_BUTTON": "Flytja inn",
"POPUP_VIEW_TITLE": "Skoða OpenPGP-lykil",
"POPUP_VIEW_BUTTON": "Velja",
"POPUP_GENERATE_TITLE": "Búa til OpenPGP-lykla",
"POPUP_GENERATE_BUTTON": "Útbúa",
"LABEL_KEY_TYPE": "Type",
"LABEL_SIGN": "Undirrita",
"LABEL_ENCRYPT": "Dulrita",
"BUTTON_SIGN": "Undirrita",
"BUTTON_ENCRYPT": "Dulrita",
"BUTTON_SIGN_AND_ENCRYPT": "Undirrita og dulrita"
},
"POPUPS_MESSAGE_OPEN_PGP": {
"TITLE_MESSAGE_OPEN_PGP": "Afkóða OpenPGP",
"LABEL_KEY": "Einkalykill",
"BUTTON_DECRYPT": "Afkóða"
},
"POPUPS_FILTER": {
@ -469,7 +453,6 @@
"BUTTON_GENERATE_OPEN_PGP_KEYS": "Búa til OpenPGP-lykla",
"TITLE_PRIVATE": "Einkalykill",
"TITLE_PUBLIC": "Dreifilykill",
"GENERATE_ONLY_HTTPS": "Einungis HTTPS",
"LABEL_ALLOW_DRAFT_AUTOSAVE": "Vista drög sjálfkrafa"
},
"SHORTCUTS_HELP": {

View file

@ -151,7 +151,6 @@
"PGP_SIGNED_MESSAGE_DESC": "Messaggio firmato con OpenPGP",
"BUTTON_PGP_VERIFY": "clicca qui per verificarlo",
"PGP_ENCRYPTED_MESSAGE_DESC": "Messaggio cifrato con OpenPGP",
"BUTTON_PGP_DECRYPT": "clicca qui per decifrarlo",
"LINK_DOWNLOAD_AS_ZIP": "Scarica come archivio ZIP",
"SPAM_SCORE": "Spam Score",
"HAS_VIRUS_WARNING": "WARNING: virus detected"
@ -216,7 +215,6 @@
"ATTACHMENTS_UPLOAD_ERROR_DESC": "Non tutti gli allegati sono stati caricati al momento.",
"BUTTON_REQUEST_READ_RECEIPT": "Richiedi conferma di lettura",
"BUTTON_MARK_AS_IMPORTANT": "Marca come importante",
"BUTTON_OPEN_PGP": "OpenPGP (Solo testo semplice)",
"BUTTON_REQUEST_DSN": "Richiedi conferma del ricevimento"
},
"POPUPS_ASK": {
@ -254,30 +252,16 @@
"DANGER_DESC_HTML_2": "Una volta iniziato, il processo non può più essere annullato.",
"TITLE_CLEARING_PROCESS": "Eliminazione cartella..."
},
"POPUPS_IMPORT_OPEN_PGP_KEY": {
"TITLE_IMPORT_OPEN_PGP_KEY": "Importa chiave OpenPGP",
"BUTTON_IMPORT_OPEN_PGP_KEY": "Importa"
},
"POPUPS_VIEW_OPEN_PGP_KEY": {
"TITLE_VIEW_OPEN_PGP_KEY": "Visualizza chiave OpenPGP",
"BUTTON_SELECT": "Seleziona tutto"
},
"POPUPS_GENERATE_OPEN_PGP_KEYS": {
"TITLE_GENERATE_OPEN_PGP_KEYS": "Genera chiavi OpenPGP",
"LABEL_KEY_BIT_LENGTH": "Lunghezza della chiave",
"BUTTON_GENERATE_OPEN_PGP_KEYS": "Genera"
},
"POPUPS_COMPOSE_OPEN_PGP": {
"TITLE_COMPOSE_OPEN_PGP": "Firma\/Cifra con OpenPGP",
"OPENPGP": {
"POPUP_IMPORT_TITLE": "Importa chiave OpenPGP",
"POPUP_IMPORT_BUTTON": "Importa",
"POPUP_VIEW_TITLE": "Visualizza chiave OpenPGP",
"POPUP_VIEW_BUTTON": "Seleziona tutto",
"POPUP_GENERATE_TITLE": "Genera chiavi OpenPGP",
"POPUP_GENERATE_BUTTON": "Genera",
"LABEL_KEY_TYPE": "Type",
"LABEL_SIGN": "Firma",
"LABEL_ENCRYPT": "Cifra",
"BUTTON_SIGN": "Firma",
"BUTTON_ENCRYPT": "Cifra",
"BUTTON_SIGN_AND_ENCRYPT": "Firma e cifra"
},
"POPUPS_MESSAGE_OPEN_PGP": {
"TITLE_MESSAGE_OPEN_PGP": "OpenPGP Decrypt",
"LABEL_KEY": "Private Key",
"BUTTON_DECRYPT": "Decrypt"
},
"POPUPS_FILTER": {
@ -469,7 +453,6 @@
"BUTTON_GENERATE_OPEN_PGP_KEYS": "Genera chiave OpenPGP",
"TITLE_PRIVATE": "Privata",
"TITLE_PUBLIC": "Pubblica",
"GENERATE_ONLY_HTTPS": "solo tramite HTTPS",
"LABEL_ALLOW_DRAFT_AUTOSAVE": "Salva automaticamente la bozza"
},
"SHORTCUTS_HELP": {

View file

@ -151,7 +151,6 @@
"PGP_SIGNED_MESSAGE_DESC": "OpenPGP 署名済みメッセージ",
"BUTTON_PGP_VERIFY": "クリックして検証",
"PGP_ENCRYPTED_MESSAGE_DESC": "OpenPGP 暗号化メッセージ",
"BUTTON_PGP_DECRYPT": "クリックして復号化",
"LINK_DOWNLOAD_AS_ZIP": "Zip としてダウンロード",
"SPAM_SCORE": "Spam Score",
"HAS_VIRUS_WARNING": "WARNING: virus detected"
@ -216,7 +215,6 @@
"ATTACHMENTS_UPLOAD_ERROR_DESC": "すべての添付ファイルがアップロードされているわけではありません。",
"BUTTON_REQUEST_READ_RECEIPT": "開封確認を要求する",
"BUTTON_MARK_AS_IMPORTANT": "重要フラグをつける",
"BUTTON_OPEN_PGP": "OpenPGP (プレーンテキストのみ)",
"BUTTON_REQUEST_DSN": "配信確認を要求する"
},
"POPUPS_ASK": {
@ -254,30 +252,16 @@
"DANGER_DESC_HTML_2": "一度始めると、中止やキャンセルができません。",
"TITLE_CLEARING_PROCESS": "フォルダを消去しています..."
},
"POPUPS_IMPORT_OPEN_PGP_KEY": {
"TITLE_IMPORT_OPEN_PGP_KEY": "OpenPGP キーをインポート",
"BUTTON_IMPORT_OPEN_PGP_KEY": "インポート"
},
"POPUPS_VIEW_OPEN_PGP_KEY": {
"TITLE_VIEW_OPEN_PGP_KEY": "OpenPGP キーを表示",
"BUTTON_SELECT": "選択"
},
"POPUPS_GENERATE_OPEN_PGP_KEYS": {
"TITLE_GENERATE_OPEN_PGP_KEYS": "OpenPGP キーを生成",
"LABEL_KEY_BIT_LENGTH": "キーの長さ",
"BUTTON_GENERATE_OPEN_PGP_KEYS": "生成"
},
"POPUPS_COMPOSE_OPEN_PGP": {
"TITLE_COMPOSE_OPEN_PGP": "OpenPGP 署名\/暗号化",
"OPENPGP": {
"POPUP_IMPORT_TITLE": "OpenPGP キーをインポート",
"POPUP_IMPORT_BUTTON": "インポート",
"POPUP_VIEW_TITLE": "OpenPGP キーを表示",
"POPUP_VIEW_BUTTON": "選択",
"POPUP_GENERATE_TITLE": "OpenPGP キーを生成",
"POPUP_GENERATE_BUTTON": "生成",
"LABEL_KEY_TYPE": "Type",
"LABEL_SIGN": "署名",
"LABEL_ENCRYPT": "暗号化",
"BUTTON_SIGN": "署名",
"BUTTON_ENCRYPT": "暗号化",
"BUTTON_SIGN_AND_ENCRYPT": "署名と暗号化"
},
"POPUPS_MESSAGE_OPEN_PGP": {
"TITLE_MESSAGE_OPEN_PGP": "OpenPGP 復号化",
"LABEL_KEY": "秘密鍵",
"BUTTON_DECRYPT": "復号化"
},
"POPUPS_FILTER": {
@ -469,7 +453,6 @@
"BUTTON_GENERATE_OPEN_PGP_KEYS": "OpenPGP キーを生成",
"TITLE_PRIVATE": "プライベート",
"TITLE_PUBLIC": "パブリック",
"GENERATE_ONLY_HTTPS": "HTTPS only",
"LABEL_ALLOW_DRAFT_AUTOSAVE": "下書きを自動的に保存する"
},
"SHORTCUTS_HELP": {

View file

@ -151,7 +151,6 @@
"PGP_SIGNED_MESSAGE_DESC": "OpenPGP로 서명된 메세지입니다.",
"BUTTON_PGP_VERIFY": "인증하려면 클릭하세요",
"PGP_ENCRYPTED_MESSAGE_DESC": "OpenPGP로 암호화된 메세지입니다.",
"BUTTON_PGP_DECRYPT": "복호화하려면 클릭하세요",
"LINK_DOWNLOAD_AS_ZIP": ".zip 파일로 다운로드",
"SPAM_SCORE": "Spam Score",
"HAS_VIRUS_WARNING": "WARNING: virus detected"
@ -216,7 +215,6 @@
"ATTACHMENTS_UPLOAD_ERROR_DESC": "첨부파일이 아직 업로드되지 않았습니다.",
"BUTTON_REQUEST_READ_RECEIPT": "수신 확인 요청",
"BUTTON_MARK_AS_IMPORTANT": "중요 표시",
"BUTTON_OPEN_PGP": "OpenPGP (평문만)",
"BUTTON_REQUEST_DSN": "수신 확인 요청"
},
"POPUPS_ASK": {
@ -254,30 +252,16 @@
"DANGER_DESC_HTML_2": "작업이 시작되면 중지하거나 취소할 수 없습니다.",
"TITLE_CLEARING_PROCESS": "폴더를 비우는 중..."
},
"POPUPS_IMPORT_OPEN_PGP_KEY": {
"TITLE_IMPORT_OPEN_PGP_KEY": "OpenPGP 키 가져오기",
"BUTTON_IMPORT_OPEN_PGP_KEY": "가져오기"
},
"POPUPS_VIEW_OPEN_PGP_KEY": {
"TITLE_VIEW_OPEN_PGP_KEY": "OpenPGP 키 보기",
"BUTTON_SELECT": "선택"
},
"POPUPS_GENERATE_OPEN_PGP_KEYS": {
"TITLE_GENERATE_OPEN_PGP_KEYS": "OpenPGP 키 생성",
"LABEL_KEY_BIT_LENGTH": "키 길이",
"BUTTON_GENERATE_OPEN_PGP_KEYS": "생성"
},
"POPUPS_COMPOSE_OPEN_PGP": {
"TITLE_COMPOSE_OPEN_PGP": "OpenPGP 서명\/암호화",
"OPENPGP": {
"POPUP_IMPORT_TITLE": "OpenPGP 키 가져오기",
"POPUP_IMPORT_BUTTON": "가져오기",
"POPUP_VIEW_TITLE": "OpenPGP 키 보기",
"POPUP_VIEW_BUTTON": "선택",
"POPUP_GENERATE_TITLE": "OpenPGP 키 생성",
"POPUP_GENERATE_BUTTON": "생성",
"LABEL_KEY_TYPE": "Type",
"LABEL_SIGN": "로그인",
"LABEL_ENCRYPT": "암호화",
"BUTTON_SIGN": "로그인",
"BUTTON_ENCRYPT": "암호화",
"BUTTON_SIGN_AND_ENCRYPT": "서명 및 암호화"
},
"POPUPS_MESSAGE_OPEN_PGP": {
"TITLE_MESSAGE_OPEN_PGP": "OpenPGP 복호화",
"LABEL_KEY": "비공개 키",
"BUTTON_DECRYPT": "복호화"
},
"POPUPS_FILTER": {
@ -469,7 +453,6 @@
"BUTTON_GENERATE_OPEN_PGP_KEYS": "OpenPGP 키 생성",
"TITLE_PRIVATE": "비공개",
"TITLE_PUBLIC": "공개",
"GENERATE_ONLY_HTTPS": "HTTPS만",
"LABEL_ALLOW_DRAFT_AUTOSAVE": "작성 중인 메시지 자동 저장"
},
"SHORTCUTS_HELP": {

View file

@ -151,7 +151,6 @@
"PGP_SIGNED_MESSAGE_DESC": "OpenPGP pasirašytas pranešimas",
"BUTTON_PGP_VERIFY": "spustelkite patikrinimui",
"PGP_ENCRYPTED_MESSAGE_DESC": "OpenPGP šifruotas pranešimas",
"BUTTON_PGP_DECRYPT": "spustelkite iššifravimui",
"LINK_DOWNLOAD_AS_ZIP": "Atsisiųsti zip archyvą",
"SPAM_SCORE": "Spam Score",
"HAS_VIRUS_WARNING": "WARNING: virus detected"
@ -216,7 +215,6 @@
"ATTACHMENTS_UPLOAD_ERROR_DESC": "Dar ne visi priedai buvo įkelti",
"BUTTON_REQUEST_READ_RECEIPT": "Prašyti pranešti kada bus perskaitytas",
"BUTTON_MARK_AS_IMPORTANT": "Žymėti svarbiu",
"BUTTON_OPEN_PGP": "OpenPGP (Tik paprastas tekstas)",
"BUTTON_REQUEST_DSN": "Prašyti laiško gavimo pažymos"
},
"POPUPS_ASK": {
@ -254,30 +252,16 @@
"DANGER_DESC_HTML_2": "Pradėjus veiksmą, jis nebesustabdomas.",
"TITLE_CLEARING_PROCESS": "Valomas katalogas..."
},
"POPUPS_IMPORT_OPEN_PGP_KEY": {
"TITLE_IMPORT_OPEN_PGP_KEY": "Importuoti OpenPGP raktą",
"BUTTON_IMPORT_OPEN_PGP_KEY": "Importuoti"
},
"POPUPS_VIEW_OPEN_PGP_KEY": {
"TITLE_VIEW_OPEN_PGP_KEY": "Peržiūrėti OpenPGP raktą",
"BUTTON_SELECT": "Pasirinkti"
},
"POPUPS_GENERATE_OPEN_PGP_KEYS": {
"TITLE_GENERATE_OPEN_PGP_KEYS": "Sukurti OpenPGP raktą",
"LABEL_KEY_BIT_LENGTH": "Rakto ilgis",
"BUTTON_GENERATE_OPEN_PGP_KEYS": "Sukurti"
},
"POPUPS_COMPOSE_OPEN_PGP": {
"TITLE_COMPOSE_OPEN_PGP": "OpenPGP Parašas\/Šifravimas",
"OPENPGP": {
"POPUP_IMPORT_TITLE": "Importuoti OpenPGP raktą",
"POPUP_IMPORT_BUTTON": "Importuoti",
"POPUP_VIEW_TITLE": "Peržiūrėti OpenPGP raktą",
"POPUP_VIEW_BUTTON": "Pasirinkti",
"POPUP_GENERATE_TITLE": "Sukurti OpenPGP raktą",
"POPUP_GENERATE_BUTTON": "Sukurti",
"LABEL_KEY_TYPE": "Type",
"LABEL_SIGN": "Parašas",
"LABEL_ENCRYPT": "Šifravimas",
"BUTTON_SIGN": "Pasirašyti",
"BUTTON_ENCRYPT": "Šifruoti",
"BUTTON_SIGN_AND_ENCRYPT": "Pasirašyti ir šifruoti"
},
"POPUPS_MESSAGE_OPEN_PGP": {
"TITLE_MESSAGE_OPEN_PGP": "OpenPGP Decrypt",
"LABEL_KEY": "Private Key",
"BUTTON_DECRYPT": "Decrypt"
},
"POPUPS_FILTER": {
@ -469,7 +453,6 @@
"BUTTON_GENERATE_OPEN_PGP_KEYS": "Sukurti OpenPGP raktus",
"TITLE_PRIVATE": "Privatus",
"TITLE_PUBLIC": "Viešas",
"GENERATE_ONLY_HTTPS": "HTTPS only",
"LABEL_ALLOW_DRAFT_AUTOSAVE": "Automatically save draft"
},
"SHORTCUTS_HELP": {

View file

@ -151,7 +151,6 @@
"PGP_SIGNED_MESSAGE_DESC": "OpenPGP signed message",
"BUTTON_PGP_VERIFY": "click to verify",
"PGP_ENCRYPTED_MESSAGE_DESC": "OpenPGP encrypted message",
"BUTTON_PGP_DECRYPT": "click to decrypt",
"LINK_DOWNLOAD_AS_ZIP": "Download as zip",
"SPAM_SCORE": "Spam Score",
"HAS_VIRUS_WARNING": "WARNING: virus detected"
@ -216,7 +215,6 @@
"ATTACHMENTS_UPLOAD_ERROR_DESC": "Not all attachments have been uploaded yet",
"BUTTON_REQUEST_READ_RECEIPT": "Request a read receipt",
"BUTTON_MARK_AS_IMPORTANT": "Mark as important",
"BUTTON_OPEN_PGP": "OpenPGP (Plain Text Only)",
"BUTTON_REQUEST_DSN": "Request a delivery receipt"
},
"POPUPS_ASK": {
@ -254,30 +252,16 @@
"DANGER_DESC_HTML_2": "Šo procesu nevarēs apturēt.",
"TITLE_CLEARING_PROCESS": "Mape tiek iztīrīta..."
},
"POPUPS_IMPORT_OPEN_PGP_KEY": {
"TITLE_IMPORT_OPEN_PGP_KEY": "Import OpenPGP key",
"BUTTON_IMPORT_OPEN_PGP_KEY": "Import"
},
"POPUPS_VIEW_OPEN_PGP_KEY": {
"TITLE_VIEW_OPEN_PGP_KEY": "View OpenPGP key",
"BUTTON_SELECT": "Select"
},
"POPUPS_GENERATE_OPEN_PGP_KEYS": {
"TITLE_GENERATE_OPEN_PGP_KEYS": "Generate OpenPGP keys",
"LABEL_KEY_BIT_LENGTH": "Key length",
"BUTTON_GENERATE_OPEN_PGP_KEYS": "Generate"
},
"POPUPS_COMPOSE_OPEN_PGP": {
"TITLE_COMPOSE_OPEN_PGP": "OpenPGP Sign\/Encrypt",
"OPENPGP": {
"POPUP_IMPORT_TITLE": "Import OpenPGP key",
"POPUP_IMPORT_BUTTON": "Import",
"POPUP_VIEW_TITLE": "View OpenPGP key",
"POPUP_VIEW_BUTTON": "Select",
"POPUP_GENERATE_TITLE": "Generate OpenPGP keys",
"POPUP_GENERATE_BUTTON": "Generate",
"LABEL_KEY_TYPE": "Type",
"LABEL_SIGN": "Sign",
"LABEL_ENCRYPT": "Encrypt",
"BUTTON_SIGN": "Sign",
"BUTTON_ENCRYPT": "Encrypt",
"BUTTON_SIGN_AND_ENCRYPT": "Sign and encrypt"
},
"POPUPS_MESSAGE_OPEN_PGP": {
"TITLE_MESSAGE_OPEN_PGP": "OpenPGP Decrypt",
"LABEL_KEY": "Private Key",
"BUTTON_DECRYPT": "Decrypt"
},
"POPUPS_FILTER": {
@ -469,7 +453,6 @@
"BUTTON_GENERATE_OPEN_PGP_KEYS": "Generate OpenPGP Keys",
"TITLE_PRIVATE": "Private",
"TITLE_PUBLIC": "Public",
"GENERATE_ONLY_HTTPS": "HTTPS only",
"LABEL_ALLOW_DRAFT_AUTOSAVE": "Automatically save draft"
},
"SHORTCUTS_HELP": {

View file

@ -151,7 +151,6 @@
"PGP_SIGNED_MESSAGE_DESC": "OpenPGP-signert melding",
"BUTTON_PGP_VERIFY": "trykk for å bekrefte",
"PGP_ENCRYPTED_MESSAGE_DESC": "OpenPGP-kryptert melding",
"BUTTON_PGP_DECRYPT": "trykk for å dekryptere",
"LINK_DOWNLOAD_AS_ZIP": "Last ned som zip-fil",
"SPAM_SCORE": "Spam Score",
"HAS_VIRUS_WARNING": "WARNING: virus detected"
@ -216,7 +215,6 @@
"ATTACHMENTS_UPLOAD_ERROR_DESC": "Ett eller flere vedlegg er ikke blitt lastet opp enda",
"BUTTON_REQUEST_READ_RECEIPT": "Be om en bekreftelse fra mottaker på at meldinga er lest",
"BUTTON_MARK_AS_IMPORTANT": "Marker som viktig",
"BUTTON_OPEN_PGP": "OpenPGP (kun ren tekst)",
"BUTTON_REQUEST_DSN": "Be om leveringsbekreftelse"
},
"POPUPS_ASK": {
@ -254,30 +252,16 @@
"DANGER_DESC_HTML_2": "Hvis du går videre, blir meldingene slettet for godt.",
"TITLE_CLEARING_PROCESS": "Tømmer mappe …"
},
"POPUPS_IMPORT_OPEN_PGP_KEY": {
"TITLE_IMPORT_OPEN_PGP_KEY": "Importer OpenPGP-nøkkel",
"BUTTON_IMPORT_OPEN_PGP_KEY": "Importer"
},
"POPUPS_VIEW_OPEN_PGP_KEY": {
"TITLE_VIEW_OPEN_PGP_KEY": "Vis OpenPGP-nøkkel",
"BUTTON_SELECT": "Velg"
},
"POPUPS_GENERATE_OPEN_PGP_KEYS": {
"TITLE_GENERATE_OPEN_PGP_KEYS": "Lag OpenPGP-nøkler",
"LABEL_KEY_BIT_LENGTH": "Nøkkellengde",
"BUTTON_GENERATE_OPEN_PGP_KEYS": "Lag"
},
"POPUPS_COMPOSE_OPEN_PGP": {
"TITLE_COMPOSE_OPEN_PGP": "Signer\/krypter med OpenPGP",
"OPENPGP": {
"POPUP_IMPORT_TITLE": "Importer OpenPGP-nøkkel",
"POPUP_IMPORT_BUTTON": "Importer",
"POPUP_VIEW_TITLE": "Vis OpenPGP-nøkkel",
"POPUP_VIEW_BUTTON": "Velg",
"POPUP_GENERATE_TITLE": "Lag OpenPGP-nøkler",
"POPUP_GENERATE_BUTTON": "Lag",
"LABEL_KEY_TYPE": "Type",
"LABEL_SIGN": "Signer",
"LABEL_ENCRYPT": "Krypter",
"BUTTON_SIGN": "Signer",
"BUTTON_ENCRYPT": "Krypter",
"BUTTON_SIGN_AND_ENCRYPT": "Signer og krypter"
},
"POPUPS_MESSAGE_OPEN_PGP": {
"TITLE_MESSAGE_OPEN_PGP": "Dekrypter med OpenPGP",
"LABEL_KEY": "Privatnøkkel",
"BUTTON_DECRYPT": "Dekrypter"
},
"POPUPS_FILTER": {
@ -469,7 +453,6 @@
"BUTTON_GENERATE_OPEN_PGP_KEYS": "Lag OpenPGP-nøkler",
"TITLE_PRIVATE": "Privat",
"TITLE_PUBLIC": "Offentlig",
"GENERATE_ONLY_HTTPS": "Kun HTTPS",
"LABEL_ALLOW_DRAFT_AUTOSAVE": "Lagre utkast automatisk"
},
"SHORTCUTS_HELP": {

View file

@ -151,7 +151,6 @@
"PGP_SIGNED_MESSAGE_DESC": "OpenPGP ondertekend bericht",
"BUTTON_PGP_VERIFY": "klik om te verifiëren",
"PGP_ENCRYPTED_MESSAGE_DESC": "OpenPGP versleuteld bericht",
"BUTTON_PGP_DECRYPT": "klik om te ontsleutelen",
"LINK_DOWNLOAD_AS_ZIP": "Download als zip",
"SPAM_SCORE": "Spamscore",
"HAS_VIRUS_WARNING": "WAARSCHUWING: virus gedetecteerd"
@ -216,7 +215,6 @@
"ATTACHMENTS_UPLOAD_ERROR_DESC": "Toevoegen van bijlage(n) is nog niet gereed",
"BUTTON_REQUEST_READ_RECEIPT": "Leesbevestiging vragen",
"BUTTON_MARK_AS_IMPORTANT": "Markeer als belangrijk",
"BUTTON_OPEN_PGP": "OpenPGP (alleen bij Platte Tekst)",
"BUTTON_REQUEST_DSN": "Ontvangstbevestiging vragen"
},
"POPUPS_ASK": {
@ -254,30 +252,16 @@
"DANGER_DESC_HTML_2": "Eens in gang gezet kan het proces niet geannuleerd worden!",
"TITLE_CLEARING_PROCESS": "Folder aan het leegmaken..."
},
"POPUPS_IMPORT_OPEN_PGP_KEY": {
"TITLE_IMPORT_OPEN_PGP_KEY": "Importeer OpenPGP sleutel",
"BUTTON_IMPORT_OPEN_PGP_KEY": "Importeer"
},
"POPUPS_VIEW_OPEN_PGP_KEY": {
"TITLE_VIEW_OPEN_PGP_KEY": "Bekijk OpenPGP sleutel",
"BUTTON_SELECT": "Selecteer"
},
"POPUPS_GENERATE_OPEN_PGP_KEYS": {
"TITLE_GENERATE_OPEN_PGP_KEYS": "Genereer OpenPGP sleutels",
"LABEL_KEY_BIT_LENGTH": "Sleutel lengte",
"BUTTON_GENERATE_OPEN_PGP_KEYS": "Genereer"
},
"POPUPS_COMPOSE_OPEN_PGP": {
"TITLE_COMPOSE_OPEN_PGP": "OpenPGP ondertekenen\/versleutelen",
"OPENPGP": {
"POPUP_IMPORT_TITLE": "Importeer OpenPGP sleutel",
"POPUP_IMPORT_BUTTON": "Importeer",
"POPUP_VIEW_TITLE": "Bekijk OpenPGP sleutel",
"POPUP_VIEW_BUTTON": "Selecteer",
"POPUP_GENERATE_TITLE": "Genereer OpenPGP sleutels",
"POPUP_GENERATE_BUTTON": "Genereer",
"LABEL_KEY_TYPE": "Type",
"LABEL_SIGN": "Ondertekenen",
"LABEL_ENCRYPT": "Versleutelen",
"BUTTON_SIGN": "Ondertekenen",
"BUTTON_ENCRYPT": "Versleutelen",
"BUTTON_SIGN_AND_ENCRYPT": "Ondertekenen en versleutelen"
},
"POPUPS_MESSAGE_OPEN_PGP": {
"TITLE_MESSAGE_OPEN_PGP": "OpenPGP Decrypt",
"LABEL_KEY": "Privé sleutel",
"BUTTON_DECRYPT": "Decrypt"
},
"POPUPS_FILTER": {
@ -469,7 +453,6 @@
"BUTTON_GENERATE_OPEN_PGP_KEYS": "Genereer OpenPGP sleutels",
"TITLE_PRIVATE": "Privé sleutel",
"TITLE_PUBLIC": "Publieke sleutel",
"GENERATE_ONLY_HTTPS": "Alleen HTTPS",
"LABEL_ALLOW_DRAFT_AUTOSAVE": "Automatically save draft"
},
"SHORTCUTS_HELP": {

View file

@ -151,7 +151,6 @@
"PGP_SIGNED_MESSAGE_DESC": "Wiadomość podpisana OpenPGP",
"BUTTON_PGP_VERIFY": "kliknij aby zweryfikować",
"PGP_ENCRYPTED_MESSAGE_DESC": "Wiadomość zaszyfrowana OpenPGP",
"BUTTON_PGP_DECRYPT": "kliknij aby odszyfrować",
"LINK_DOWNLOAD_AS_ZIP": "Pobierz jako plik zip",
"SPAM_SCORE": "Spam Score",
"HAS_VIRUS_WARNING": "WARNING: virus detected"
@ -216,7 +215,6 @@
"ATTACHMENTS_UPLOAD_ERROR_DESC": "Jeszcze nie wszystkie załączniki zostały przesłane na serwer.",
"BUTTON_REQUEST_READ_RECEIPT": "Żądaj potwierdzenia przeczytania wiadomości",
"BUTTON_MARK_AS_IMPORTANT": "Oznacz jako ważną",
"BUTTON_OPEN_PGP": "OpenPGP (tylko wiadomości tekstowe)",
"BUTTON_REQUEST_DSN": "Żądaj potwierdzenia dostarczenia wiadomości"
},
"POPUPS_ASK": {
@ -254,30 +252,16 @@
"DANGER_DESC_HTML_2": "Po rozpoczęciu nie będzie możliwe przerwanie lub anulowanie zadania.",
"TITLE_CLEARING_PROCESS": "Trwa usuwanie wszystkich wiadomości z folderu..."
},
"POPUPS_IMPORT_OPEN_PGP_KEY": {
"TITLE_IMPORT_OPEN_PGP_KEY": "Importowanie klucza OpenPGP",
"BUTTON_IMPORT_OPEN_PGP_KEY": "Importuj"
},
"POPUPS_VIEW_OPEN_PGP_KEY": {
"TITLE_VIEW_OPEN_PGP_KEY": "Podgląd klucza OpenPGP",
"BUTTON_SELECT": "Zaznacz"
},
"POPUPS_GENERATE_OPEN_PGP_KEYS": {
"TITLE_GENERATE_OPEN_PGP_KEYS": "Generowanie klucza OpenPGP",
"LABEL_KEY_BIT_LENGTH": "Długość klucza",
"BUTTON_GENERATE_OPEN_PGP_KEYS": "Generuj"
},
"POPUPS_COMPOSE_OPEN_PGP": {
"TITLE_COMPOSE_OPEN_PGP": "Podpisywanie\/szyfrowanie OpenPGP",
"OPENPGP": {
"POPUP_IMPORT_TITLE": "Importowanie klucza OpenPGP",
"POPUP_IMPORT_BUTTON": "Importuj",
"POPUP_VIEW_TITLE": "Podgląd klucza OpenPGP",
"POPUP_VIEW_BUTTON": "Zaznacz",
"POPUP_GENERATE_TITLE": "Generowanie klucza OpenPGP",
"POPUP_GENERATE_BUTTON": "Generuj",
"LABEL_KEY_TYPE": "Type",
"LABEL_SIGN": "Podpisz",
"LABEL_ENCRYPT": "Zaszyfruj",
"BUTTON_SIGN": "Podpisz",
"BUTTON_ENCRYPT": "Zaszyfruj",
"BUTTON_SIGN_AND_ENCRYPT": "Podpisz i zaszyfruj"
},
"POPUPS_MESSAGE_OPEN_PGP": {
"TITLE_MESSAGE_OPEN_PGP": "Odszyfrowywanie OpenPGP",
"LABEL_KEY": "Klucz prywatny",
"BUTTON_DECRYPT": "Odszyfruj"
},
"POPUPS_FILTER": {
@ -469,7 +453,6 @@
"BUTTON_GENERATE_OPEN_PGP_KEYS": "Generuj klucz OpenPGP",
"TITLE_PRIVATE": "Prywatny",
"TITLE_PUBLIC": "Publiczny",
"GENERATE_ONLY_HTTPS": "Tylko HTTPS",
"LABEL_ALLOW_DRAFT_AUTOSAVE": "Automatycznie zapisuj szkic"
},
"SHORTCUTS_HELP": {

View file

@ -151,7 +151,6 @@
"PGP_SIGNED_MESSAGE_DESC": "Mensagem assinada com OpenPGP",
"BUTTON_PGP_VERIFY": "clique para verificar",
"PGP_ENCRYPTED_MESSAGE_DESC": "Mensagem criptografada com OpenPGP",
"BUTTON_PGP_DECRYPT": "clique para descriptografar",
"LINK_DOWNLOAD_AS_ZIP": "Baixar como zip",
"SPAM_SCORE": "Spam Score",
"HAS_VIRUS_WARNING": "WARNING: virus detected"
@ -216,7 +215,6 @@
"ATTACHMENTS_UPLOAD_ERROR_DESC": "Alguns anexos ainda não foram completamente enviados",
"BUTTON_REQUEST_READ_RECEIPT": "Pedir recibo de leitura",
"BUTTON_MARK_AS_IMPORTANT": "Marcar como importante",
"BUTTON_OPEN_PGP": "OpenPGP (Somente Texto)",
"BUTTON_REQUEST_DSN": "Pedir recibo de entrega"
},
"POPUPS_ASK": {
@ -254,30 +252,16 @@
"DANGER_DESC_HTML_2": "Uma vez iniciado, o processo não poderá ser interrompido ou cancelado.",
"TITLE_CLEARING_PROCESS": "Excluindo a pasta..."
},
"POPUPS_IMPORT_OPEN_PGP_KEY": {
"TITLE_IMPORT_OPEN_PGP_KEY": "Importar chave OpenPGP",
"BUTTON_IMPORT_OPEN_PGP_KEY": "Importar"
},
"POPUPS_VIEW_OPEN_PGP_KEY": {
"TITLE_VIEW_OPEN_PGP_KEY": "Ver chave OpenPGP",
"BUTTON_SELECT": "Selecionar"
},
"POPUPS_GENERATE_OPEN_PGP_KEYS": {
"TITLE_GENERATE_OPEN_PGP_KEYS": "Gerar chave OpenPGP",
"LABEL_KEY_BIT_LENGTH": "Tamanho da chave",
"BUTTON_GENERATE_OPEN_PGP_KEYS": "Gerar"
},
"POPUPS_COMPOSE_OPEN_PGP": {
"TITLE_COMPOSE_OPEN_PGP": "OpenPGP Assinar\/Criptografar",
"OPENPGP": {
"POPUP_IMPORT_TITLE": "Importar chave OpenPGP",
"POPUP_IMPORT_BUTTON": "Importar",
"POPUP_VIEW_TITLE": "Ver chave OpenPGP",
"POPUP_VIEW_BUTTON": "Selecionar",
"POPUP_GENERATE_TITLE": "Gerar chave OpenPGP",
"POPUP_GENERATE_BUTTON": "Gerar",
"LABEL_KEY_TYPE": "Type",
"LABEL_SIGN": "Assinar",
"LABEL_ENCRYPT": "Criptografar",
"BUTTON_SIGN": "Assinar",
"BUTTON_ENCRYPT": "Criptografar",
"BUTTON_SIGN_AND_ENCRYPT": "Assinar e criptografar"
},
"POPUPS_MESSAGE_OPEN_PGP": {
"TITLE_MESSAGE_OPEN_PGP": "OpenPGP Decrypt",
"LABEL_KEY": "Private Key",
"BUTTON_DECRYPT": "Decrypt"
},
"POPUPS_FILTER": {
@ -469,7 +453,6 @@
"BUTTON_GENERATE_OPEN_PGP_KEYS": "Gerar chave OpenPGP",
"TITLE_PRIVATE": "Privado",
"TITLE_PUBLIC": "Público",
"GENERATE_ONLY_HTTPS": "HTTPS only",
"LABEL_ALLOW_DRAFT_AUTOSAVE": "Salvar automaticamente rascunho"
},
"SHORTCUTS_HELP": {

View file

@ -151,7 +151,6 @@
"PGP_SIGNED_MESSAGE_DESC": "Mensagem assinada com OpenPGP",
"BUTTON_PGP_VERIFY": "clique para verificar",
"PGP_ENCRYPTED_MESSAGE_DESC": "Mensagem encriptada com OpenPGP",
"BUTTON_PGP_DECRYPT": "clique para desencriptar",
"LINK_DOWNLOAD_AS_ZIP": "Transferir em arquivo zip",
"SPAM_SCORE": "Spam Score",
"HAS_VIRUS_WARNING": "WARNING: virus detected"
@ -216,7 +215,6 @@
"ATTACHMENTS_UPLOAD_ERROR_DESC": "Ainda não foram carregados todos os anexos",
"BUTTON_REQUEST_READ_RECEIPT": "Pedir um recibo de leitura",
"BUTTON_MARK_AS_IMPORTANT": "Marcar como importante",
"BUTTON_OPEN_PGP": "OpenPGP (apenas texto simples)",
"BUTTON_REQUEST_DSN": "Pedir um recibo de entrega"
},
"POPUPS_ASK": {
@ -254,30 +252,16 @@
"DANGER_DESC_HTML_2": "Uma vez iniciado, o processo não pode ser interrompido ou cancelado.",
"TITLE_CLEARING_PROCESS": "A eliminar a pasta..."
},
"POPUPS_IMPORT_OPEN_PGP_KEY": {
"TITLE_IMPORT_OPEN_PGP_KEY": "Importar chave OpenPGP",
"BUTTON_IMPORT_OPEN_PGP_KEY": "Importar"
},
"POPUPS_VIEW_OPEN_PGP_KEY": {
"TITLE_VIEW_OPEN_PGP_KEY": "Ver chave OpenPGP",
"BUTTON_SELECT": "Escolher"
},
"POPUPS_GENERATE_OPEN_PGP_KEYS": {
"TITLE_GENERATE_OPEN_PGP_KEYS": "Gerar chaves OpenPGP",
"LABEL_KEY_BIT_LENGTH": "Comprimento da chave",
"BUTTON_GENERATE_OPEN_PGP_KEYS": "Gerar"
},
"POPUPS_COMPOSE_OPEN_PGP": {
"TITLE_COMPOSE_OPEN_PGP": "Assinar\/Encriptar com OpenPGP",
"OPENPGP": {
"POPUP_IMPORT_TITLE": "Importar chave OpenPGP",
"POPUP_IMPORT_BUTTON": "Importar",
"POPUP_VIEW_TITLE": "Ver chave OpenPGP",
"POPUP_VIEW_BUTTON": "Escolher",
"POPUP_GENERATE_TITLE": "Gerar chaves OpenPGP",
"POPUP_GENERATE_BUTTON": "Gerar",
"LABEL_KEY_TYPE": "Type",
"LABEL_SIGN": "Assinar",
"LABEL_ENCRYPT": "Encriptar",
"BUTTON_SIGN": "Assinar",
"BUTTON_ENCRYPT": "Encriptar",
"BUTTON_SIGN_AND_ENCRYPT": "Assinar e encriptar"
},
"POPUPS_MESSAGE_OPEN_PGP": {
"TITLE_MESSAGE_OPEN_PGP": "OpenPGP Decrypt",
"LABEL_KEY": "Private Key",
"BUTTON_DECRYPT": "Decrypt"
},
"POPUPS_FILTER": {
@ -469,7 +453,6 @@
"BUTTON_GENERATE_OPEN_PGP_KEYS": "Gerar chaves OpenPGP",
"TITLE_PRIVATE": "Privada",
"TITLE_PUBLIC": "Pública",
"GENERATE_ONLY_HTTPS": "Apenas HTTPS",
"LABEL_ALLOW_DRAFT_AUTOSAVE": "Automatically save draft"
},
"SHORTCUTS_HELP": {

View file

@ -151,7 +151,6 @@
"PGP_SIGNED_MESSAGE_DESC": "OpenPGP signed message",
"BUTTON_PGP_VERIFY": "click to verify",
"PGP_ENCRYPTED_MESSAGE_DESC": "OpenPGP encrypted message",
"BUTTON_PGP_DECRYPT": "click to decrypt",
"LINK_DOWNLOAD_AS_ZIP": "Download as zip",
"SPAM_SCORE": "Spam Score",
"HAS_VIRUS_WARNING": "WARNING: virus detected"
@ -216,7 +215,6 @@
"ATTACHMENTS_UPLOAD_ERROR_DESC": "Not all attachments have been uploaded yet",
"BUTTON_REQUEST_READ_RECEIPT": "Cere confirmare de citire",
"BUTTON_MARK_AS_IMPORTANT": "Mark as important",
"BUTTON_OPEN_PGP": "OpenPGP (Plain Text Only)",
"BUTTON_REQUEST_DSN": "Request a delivery receipt"
},
"POPUPS_ASK": {
@ -254,30 +252,16 @@
"DANGER_DESC_HTML_2": "După începerea procesului de curățare <strong style=\"color:red\">nu mai puteți<\/strong> anula procesul.",
"TITLE_CLEARING_PROCESS": "Curăț dosarul..."
},
"POPUPS_IMPORT_OPEN_PGP_KEY": {
"TITLE_IMPORT_OPEN_PGP_KEY": "Import OpenPGP key",
"BUTTON_IMPORT_OPEN_PGP_KEY": "Import"
},
"POPUPS_VIEW_OPEN_PGP_KEY": {
"TITLE_VIEW_OPEN_PGP_KEY": "View OpenPGP key",
"BUTTON_SELECT": "Select"
},
"POPUPS_GENERATE_OPEN_PGP_KEYS": {
"TITLE_GENERATE_OPEN_PGP_KEYS": "Generate OpenPGP keys",
"LABEL_KEY_BIT_LENGTH": "Key length",
"BUTTON_GENERATE_OPEN_PGP_KEYS": "Generate"
},
"POPUPS_COMPOSE_OPEN_PGP": {
"TITLE_COMPOSE_OPEN_PGP": "OpenPGP Sign\/Encrypt",
"OPENPGP": {
"POPUP_IMPORT_TITLE": "Import OpenPGP key",
"POPUP_IMPORT_BUTTON": "Import",
"POPUP_VIEW_TITLE": "View OpenPGP key",
"POPUP_VIEW_BUTTON": "Select",
"POPUP_GENERATE_TITLE": "Generate OpenPGP keys",
"POPUP_GENERATE_BUTTON": "Generate",
"LABEL_KEY_TYPE": "Type",
"LABEL_SIGN": "Sign",
"LABEL_ENCRYPT": "Encrypt",
"BUTTON_SIGN": "Sign",
"BUTTON_ENCRYPT": "Encrypt",
"BUTTON_SIGN_AND_ENCRYPT": "Sign and encrypt"
},
"POPUPS_MESSAGE_OPEN_PGP": {
"TITLE_MESSAGE_OPEN_PGP": "OpenPGP Decrypt",
"LABEL_KEY": "Private Key",
"BUTTON_DECRYPT": "Decrypt"
},
"POPUPS_FILTER": {
@ -469,7 +453,6 @@
"BUTTON_GENERATE_OPEN_PGP_KEYS": "Generate OpenPGP Keys",
"TITLE_PRIVATE": "Private",
"TITLE_PUBLIC": "Public",
"GENERATE_ONLY_HTTPS": "HTTPS only",
"LABEL_ALLOW_DRAFT_AUTOSAVE": "Salvează ciorna automat"
},
"SHORTCUTS_HELP": {

View file

@ -151,7 +151,6 @@
"PGP_SIGNED_MESSAGE_DESC": "OpenPGP подписанное сообщение",
"BUTTON_PGP_VERIFY": "нажмите, чтобы подтвердить",
"PGP_ENCRYPTED_MESSAGE_DESC": "OpenPGP шифрованное сообщение",
"BUTTON_PGP_DECRYPT": "нажмите, чтобы расшифровать",
"LINK_DOWNLOAD_AS_ZIP": "Сохранить как zip",
"SPAM_SCORE": "Spam Score",
"HAS_VIRUS_WARNING": "WARNING: virus detected"
@ -216,7 +215,6 @@
"ATTACHMENTS_UPLOAD_ERROR_DESC": "Не все прикреплённые файлы были загружены",
"BUTTON_REQUEST_READ_RECEIPT": "Запрос о прочтении письма",
"BUTTON_MARK_AS_IMPORTANT": "Отметить как важное",
"BUTTON_OPEN_PGP": "OpenPGP (только обычный текст)",
"BUTTON_REQUEST_DSN": "Запросить уведомление о доставке"
},
"POPUPS_ASK": {
@ -254,30 +252,16 @@
"DANGER_DESC_HTML_2": "После начала очистки, процесс <strong style=\"color:red\">нельзя<\/strong> будет остановить или отменить.",
"TITLE_CLEARING_PROCESS": "Очистка папки..."
},
"POPUPS_IMPORT_OPEN_PGP_KEY": {
"TITLE_IMPORT_OPEN_PGP_KEY": "Импорт OpenPGP ключа",
"BUTTON_IMPORT_OPEN_PGP_KEY": "Импорт"
},
"POPUPS_VIEW_OPEN_PGP_KEY": {
"TITLE_VIEW_OPEN_PGP_KEY": "Просмотр OpenPGP ключа",
"BUTTON_SELECT": "Выбрать"
},
"POPUPS_GENERATE_OPEN_PGP_KEYS": {
"TITLE_GENERATE_OPEN_PGP_KEYS": "Генерация OpenPGP ключа",
"LABEL_KEY_BIT_LENGTH": "Длина ключа",
"BUTTON_GENERATE_OPEN_PGP_KEYS": "Создать"
},
"POPUPS_COMPOSE_OPEN_PGP": {
"TITLE_COMPOSE_OPEN_PGP": "OpenPGP подпись и шифрование",
"OPENPGP": {
"POPUP_IMPORT_TITLE": "Импорт OpenPGP ключа",
"POPUP_IMPORT_BUTTON": "Импорт",
"POPUP_VIEW_TITLE": "Просмотр OpenPGP ключа",
"POPUP_VIEW_BUTTON": "Выбрать",
"POPUP_GENERATE_TITLE": "Генерация OpenPGP ключа",
"POPUP_GENERATE_BUTTON": "Создать",
"LABEL_KEY_TYPE": "Type",
"LABEL_SIGN": "Подпись",
"LABEL_ENCRYPT": "Шифрование",
"BUTTON_SIGN": "Подпись",
"BUTTON_ENCRYPT": "Шифрование",
"BUTTON_SIGN_AND_ENCRYPT": "Подпись и шифрование"
},
"POPUPS_MESSAGE_OPEN_PGP": {
"TITLE_MESSAGE_OPEN_PGP": "Расшифровать (OpenPGP)",
"LABEL_KEY": "Приватный ключ",
"BUTTON_DECRYPT": "Расшифровать"
},
"POPUPS_FILTER": {
@ -469,7 +453,6 @@
"BUTTON_GENERATE_OPEN_PGP_KEYS": "Новый OpenPGP ключ",
"TITLE_PRIVATE": "Приватный",
"TITLE_PUBLIC": "Публичный",
"GENERATE_ONLY_HTTPS": "HTTPS only",
"LABEL_ALLOW_DRAFT_AUTOSAVE": "Автоматически сохранять черновик"
},
"SHORTCUTS_HELP": {

View file

@ -151,7 +151,6 @@
"PGP_SIGNED_MESSAGE_DESC": "Správa podpísaná s OpenPGP",
"BUTTON_PGP_VERIFY": "kliknite pre overenie",
"PGP_ENCRYPTED_MESSAGE_DESC": "Správa šifrovaná s OpenPGP",
"BUTTON_PGP_DECRYPT": "kliknite pre dešifrovanie",
"LINK_DOWNLOAD_AS_ZIP": "Prevziať ako zip",
"SPAM_SCORE": "Spam Score",
"HAS_VIRUS_WARNING": "WARNING: virus detected"
@ -216,7 +215,6 @@
"ATTACHMENTS_UPLOAD_ERROR_DESC": "Nie všetky prílohy boli už nahraté na server.",
"BUTTON_REQUEST_READ_RECEIPT": "Vyžiadať potvrdenie o prečítaní",
"BUTTON_MARK_AS_IMPORTANT": "Označiť ako dôležité",
"BUTTON_OPEN_PGP": "Open PGP (iba text)",
"BUTTON_REQUEST_DSN": "Vyžiadať potvrdenie o doručení"
},
"POPUPS_ASK": {
@ -254,30 +252,16 @@
"DANGER_DESC_HTML_2": "Tento proces nie je možné prerušiť.",
"TITLE_CLEARING_PROCESS": "Odstraňujem priečinok..."
},
"POPUPS_IMPORT_OPEN_PGP_KEY": {
"TITLE_IMPORT_OPEN_PGP_KEY": "Importovať kľúč OpenPGP",
"BUTTON_IMPORT_OPEN_PGP_KEY": "Import"
},
"POPUPS_VIEW_OPEN_PGP_KEY": {
"TITLE_VIEW_OPEN_PGP_KEY": "Zobraziť kľúč OpenPGP",
"BUTTON_SELECT": "Vybrať"
},
"POPUPS_GENERATE_OPEN_PGP_KEYS": {
"TITLE_GENERATE_OPEN_PGP_KEYS": "Generate OpenPGP keys",
"LABEL_KEY_BIT_LENGTH": "Key length",
"BUTTON_GENERATE_OPEN_PGP_KEYS": "Generate"
},
"POPUPS_COMPOSE_OPEN_PGP": {
"TITLE_COMPOSE_OPEN_PGP": "OpenPGP Sign\/Encrypt",
"OPENPGP": {
"POPUP_IMPORT_TITLE": "Importovať kľúč OpenPGP",
"POPUP_IMPORT_BUTTON": "Import",
"POPUP_VIEW_TITLE": "Zobraziť kľúč OpenPGP",
"POPUP_VIEW_BUTTON": "Vybrať",
"POPUP_GENERATE_TITLE": "Generate OpenPGP keys",
"POPUP_GENERATE_BUTTON": "Generate",
"LABEL_KEY_TYPE": "Type",
"LABEL_SIGN": "Sign",
"LABEL_ENCRYPT": "Encrypt",
"BUTTON_SIGN": "Sign",
"BUTTON_ENCRYPT": "Encrypt",
"BUTTON_SIGN_AND_ENCRYPT": "Sign and encrypt"
},
"POPUPS_MESSAGE_OPEN_PGP": {
"TITLE_MESSAGE_OPEN_PGP": "OpenPGP Decrypt",
"LABEL_KEY": "Private Key",
"BUTTON_DECRYPT": "Decrypt"
},
"POPUPS_FILTER": {
@ -469,7 +453,6 @@
"BUTTON_GENERATE_OPEN_PGP_KEYS": "Generate OpenPGP Keys",
"TITLE_PRIVATE": "Private",
"TITLE_PUBLIC": "Public",
"GENERATE_ONLY_HTTPS": "HTTPS only",
"LABEL_ALLOW_DRAFT_AUTOSAVE": "Automaticky uložiť koncept."
},
"SHORTCUTS_HELP": {

View file

@ -151,7 +151,6 @@
"PGP_SIGNED_MESSAGE_DESC": "Sporočilo, podpisano z OpenPGP",
"BUTTON_PGP_VERIFY": "kliknite za overovitev",
"PGP_ENCRYPTED_MESSAGE_DESC": "Sporočilo, šifrirano z OpenPGP",
"BUTTON_PGP_DECRYPT": "kliknite za dešifriranje",
"LINK_DOWNLOAD_AS_ZIP": "Prenesi kot .zip datoteko",
"SPAM_SCORE": "Spam Score",
"HAS_VIRUS_WARNING": "WARNING: virus detected"
@ -216,7 +215,6 @@
"ATTACHMENTS_UPLOAD_ERROR_DESC": "Priloge še niso bile naložene v celoti.",
"BUTTON_REQUEST_READ_RECEIPT": "Zahtevaj potrdilo o branju",
"BUTTON_MARK_AS_IMPORTANT": "Označi kot pomembno",
"BUTTON_OPEN_PGP": "OpenPGP (Navadno besedilo)",
"BUTTON_REQUEST_DSN": "Zahtevaj potrdilo o dostavi"
},
"POPUPS_ASK": {
@ -254,30 +252,16 @@
"DANGER_DESC_HTML_2": "Tega postopka ne bo mogoče preklicati ali zaustaviti.",
"TITLE_CLEARING_PROCESS": "Čistim mapo."
},
"POPUPS_IMPORT_OPEN_PGP_KEY": {
"TITLE_IMPORT_OPEN_PGP_KEY": "Uvoz OpenPGP ključa",
"BUTTON_IMPORT_OPEN_PGP_KEY": "Uvozi"
},
"POPUPS_VIEW_OPEN_PGP_KEY": {
"TITLE_VIEW_OPEN_PGP_KEY": "Ogled OpenPGP ključa",
"BUTTON_SELECT": "Izberi"
},
"POPUPS_GENERATE_OPEN_PGP_KEYS": {
"TITLE_GENERATE_OPEN_PGP_KEYS": "Generiraj OpenPGP ključe",
"LABEL_KEY_BIT_LENGTH": "Dolžina ključa",
"BUTTON_GENERATE_OPEN_PGP_KEYS": "Generiraj"
},
"POPUPS_COMPOSE_OPEN_PGP": {
"TITLE_COMPOSE_OPEN_PGP": "OpenPGP podpis\/šifriranje",
"OPENPGP": {
"POPUP_IMPORT_TITLE": "Uvoz OpenPGP ključa",
"POPUP_IMPORT_BUTTON": "Uvozi",
"POPUP_VIEW_TITLE": "Ogled OpenPGP ključa",
"POPUP_VIEW_BUTTON": "Izberi",
"POPUP_GENERATE_TITLE": "Generiraj OpenPGP ključe",
"POPUP_GENERATE_BUTTON": "Generiraj",
"LABEL_KEY_TYPE": "Type",
"LABEL_SIGN": "Podpis",
"LABEL_ENCRYPT": "Šifriranje",
"BUTTON_SIGN": "Podpiši",
"BUTTON_ENCRYPT": "Šifriraj",
"BUTTON_SIGN_AND_ENCRYPT": "Podpiši in šifriraj"
},
"POPUPS_MESSAGE_OPEN_PGP": {
"TITLE_MESSAGE_OPEN_PGP": "OpenPGP dešifriranje",
"LABEL_KEY": "Zasebni ključ",
"BUTTON_DECRYPT": "Dešifriraj"
},
"POPUPS_FILTER": {
@ -469,7 +453,6 @@
"BUTTON_GENERATE_OPEN_PGP_KEYS": "Generiraj OpenPGP ključe",
"TITLE_PRIVATE": "Zasebni",
"TITLE_PUBLIC": "Javni",
"GENERATE_ONLY_HTTPS": "Samo HTTPS",
"LABEL_ALLOW_DRAFT_AUTOSAVE": "Samodejno shrani osnutek"
},
"SHORTCUTS_HELP": {

View file

@ -151,7 +151,6 @@
"PGP_SIGNED_MESSAGE_DESC": "OpenPGP-signerat meddelande",
"BUTTON_PGP_VERIFY": "klicka för att verifiera",
"PGP_ENCRYPTED_MESSAGE_DESC": "OpenPGP-krypterat meddelande",
"BUTTON_PGP_DECRYPT": "klicka för att dekryptera",
"LINK_DOWNLOAD_AS_ZIP": "Ladda ner som ZIP-fil",
"SPAM_SCORE": "Spam Score",
"HAS_VIRUS_WARNING": "VARNING: virus upptäckt"
@ -216,7 +215,6 @@
"ATTACHMENTS_UPLOAD_ERROR_DESC": "Alla bilagor är inte uppladddade än",
"BUTTON_REQUEST_READ_RECEIPT": "Begär mottagningskvitto",
"BUTTON_MARK_AS_IMPORTANT": "Markera som viktigt",
"BUTTON_OPEN_PGP": "OpenPGP (Endast enkel text)",
"BUTTON_REQUEST_DSN": "Begär ett leveranskvitto"
},
"POPUPS_ASK": {
@ -254,30 +252,16 @@
"DANGER_DESC_HTML_2": "När detta är startat kan det inte avbrytas.",
"TITLE_CLEARING_PROCESS": "Rensar mappen..."
},
"POPUPS_IMPORT_OPEN_PGP_KEY": {
"TITLE_IMPORT_OPEN_PGP_KEY": "Import av OpenPGP-nyckel",
"BUTTON_IMPORT_OPEN_PGP_KEY": "Importera"
},
"POPUPS_VIEW_OPEN_PGP_KEY": {
"TITLE_VIEW_OPEN_PGP_KEY": "Visa OpenPGP-nyckel",
"BUTTON_SELECT": "Välj"
},
"POPUPS_GENERATE_OPEN_PGP_KEYS": {
"TITLE_GENERATE_OPEN_PGP_KEYS": "Skapa OpenPGP-nycklar",
"LABEL_KEY_BIT_LENGTH": "Nyckellängd",
"BUTTON_GENERATE_OPEN_PGP_KEYS": "Skapa"
},
"POPUPS_COMPOSE_OPEN_PGP": {
"TITLE_COMPOSE_OPEN_PGP": "OpenPGP signera\/kryptera",
"OPENPGP": {
"POPUP_IMPORT_TITLE": "Import av OpenPGP-nyckel",
"POPUP_IMPORT_BUTTON": "Importera",
"POPUP_VIEW_TITLE": "Visa OpenPGP-nyckel",
"POPUP_VIEW_BUTTON": "Välj",
"POPUP_GENERATE_TITLE": "Skapa OpenPGP-nycklar",
"POPUP_GENERATE_BUTTON": "Skapa",
"LABEL_KEY_TYPE": "Type",
"LABEL_SIGN": "Signera",
"LABEL_ENCRYPT": "Kryptera",
"BUTTON_SIGN": "Singera",
"BUTTON_ENCRYPT": "Kryptera",
"BUTTON_SIGN_AND_ENCRYPT": "Signera och kryptera"
},
"POPUPS_MESSAGE_OPEN_PGP": {
"TITLE_MESSAGE_OPEN_PGP": "OpenPGP avkryptera",
"LABEL_KEY": "Privat Key",
"BUTTON_DECRYPT": "Avkryptera"
},
"POPUPS_FILTER": {
@ -469,7 +453,6 @@
"BUTTON_GENERATE_OPEN_PGP_KEYS": "Skapa OpenPGP-nycklar",
"TITLE_PRIVATE": "Privat",
"TITLE_PUBLIC": "Publik",
"GENERATE_ONLY_HTTPS": "Endast HTTPS",
"LABEL_ALLOW_DRAFT_AUTOSAVE": "Spara utkast automatiskt"
},
"SHORTCUTS_HELP": {

View file

@ -151,7 +151,6 @@
"PGP_SIGNED_MESSAGE_DESC": "OpenPGP imzalı mesaj",
"BUTTON_PGP_VERIFY": "onay için tıklayın",
"PGP_ENCRYPTED_MESSAGE_DESC": "OpenPGP şifreli mesaj",
"BUTTON_PGP_DECRYPT": "çözmek için tıklayın",
"LINK_DOWNLOAD_AS_ZIP": "Download as zip",
"SPAM_SCORE": "Spam Score",
"HAS_VIRUS_WARNING": "WARNING: virus detected"
@ -216,7 +215,6 @@
"ATTACHMENTS_UPLOAD_ERROR_DESC": "Not all attachments have been uploaded yet",
"BUTTON_REQUEST_READ_RECEIPT": "Okundu bilgisi iste",
"BUTTON_MARK_AS_IMPORTANT": "Mark as important",
"BUTTON_OPEN_PGP": "OpenPGP (Plain Text Only)",
"BUTTON_REQUEST_DSN": "Request a delivery receipt"
},
"POPUPS_ASK": {
@ -254,30 +252,16 @@
"DANGER_DESC_HTML_2": "Bu işlem bir kez başladıktan sonra, işlem durdurulamaz veya iptal edilemez.",
"TITLE_CLEARING_PROCESS": "Klasör temizleniyor..."
},
"POPUPS_IMPORT_OPEN_PGP_KEY": {
"TITLE_IMPORT_OPEN_PGP_KEY": "OpenPGP key'i içe aktar",
"BUTTON_IMPORT_OPEN_PGP_KEY": "İçe aktar"
},
"POPUPS_VIEW_OPEN_PGP_KEY": {
"TITLE_VIEW_OPEN_PGP_KEY": "OpenPGP key'i göster",
"BUTTON_SELECT": "Seç"
},
"POPUPS_GENERATE_OPEN_PGP_KEYS": {
"TITLE_GENERATE_OPEN_PGP_KEYS": "OpenPGP key'leri Oluştur",
"LABEL_KEY_BIT_LENGTH": "Key Uzunluğu",
"BUTTON_GENERATE_OPEN_PGP_KEYS": "Oluştur"
},
"POPUPS_COMPOSE_OPEN_PGP": {
"TITLE_COMPOSE_OPEN_PGP": "OpenPGP Giriş\/Şifrele",
"OPENPGP": {
"POPUP_IMPORT_TITLE": "OpenPGP key'i içe aktar",
"POPUP_IMPORT_BUTTON": "İçe aktar",
"POPUP_VIEW_TITLE": "OpenPGP key'i göster",
"POPUP_VIEW_BUTTON": "Seç",
"POPUP_GENERATE_TITLE": "OpenPGP key'leri Oluştur",
"POPUP_GENERATE_BUTTON": "Oluştur",
"LABEL_KEY_TYPE": "Type",
"LABEL_SIGN": "Giriş Yap",
"LABEL_ENCRYPT": "Şifrele",
"BUTTON_SIGN": "Giriş Yap",
"BUTTON_ENCRYPT": "Şifrele",
"BUTTON_SIGN_AND_ENCRYPT": "Giriş Yap and şifrele"
},
"POPUPS_MESSAGE_OPEN_PGP": {
"TITLE_MESSAGE_OPEN_PGP": "OpenPGP Decrypt",
"LABEL_KEY": "Private Key",
"BUTTON_DECRYPT": "Decrypt"
},
"POPUPS_FILTER": {
@ -469,7 +453,6 @@
"BUTTON_GENERATE_OPEN_PGP_KEYS": "OpenPGP Key Oluştur",
"TITLE_PRIVATE": "Private",
"TITLE_PUBLIC": "Public",
"GENERATE_ONLY_HTTPS": "HTTPS only",
"LABEL_ALLOW_DRAFT_AUTOSAVE": "Automatically save draft"
},
"SHORTCUTS_HELP": {

View file

@ -151,7 +151,6 @@
"PGP_SIGNED_MESSAGE_DESC": "OpenPGP підписане повідомлення",
"BUTTON_PGP_VERIFY": "натисніть, щоб підтвердити",
"PGP_ENCRYPTED_MESSAGE_DESC": "OpenPGP шифроване повідомлення",
"BUTTON_PGP_DECRYPT": "натисніть, щоб розшифрувати",
"LINK_DOWNLOAD_AS_ZIP": "Завантажити як zip",
"SPAM_SCORE": "Spam Score",
"HAS_VIRUS_WARNING": "WARNING: virus detected"
@ -216,7 +215,6 @@
"ATTACHMENTS_UPLOAD_ERROR_DESC": "Not all attachments have been uploaded yet",
"BUTTON_REQUEST_READ_RECEIPT": "Запит про прочитання листа",
"BUTTON_MARK_AS_IMPORTANT": "Mark as important",
"BUTTON_OPEN_PGP": "OpenPGP (Plain Text Only)",
"BUTTON_REQUEST_DSN": "Request a delivery receipt"
},
"POPUPS_ASK": {
@ -254,30 +252,16 @@
"DANGER_DESC_HTML_2": "Після початку очищення, процес <strong style=\"color:red\">неможливо<\/strong> буде зупинити чи відмінити.",
"TITLE_CLEARING_PROCESS": "Очищення теки..."
},
"POPUPS_IMPORT_OPEN_PGP_KEY": {
"TITLE_IMPORT_OPEN_PGP_KEY": "Імпорт OpenPGP ключа",
"BUTTON_IMPORT_OPEN_PGP_KEY": "Імпорт"
},
"POPUPS_VIEW_OPEN_PGP_KEY": {
"TITLE_VIEW_OPEN_PGP_KEY": "Перегляд OpenPGP ключа",
"BUTTON_SELECT": "Вибрати"
},
"POPUPS_GENERATE_OPEN_PGP_KEYS": {
"TITLE_GENERATE_OPEN_PGP_KEYS": "Генерація OpenPGP ключа",
"LABEL_KEY_BIT_LENGTH": "Довжина ключа",
"BUTTON_GENERATE_OPEN_PGP_KEYS": "Створити"
},
"POPUPS_COMPOSE_OPEN_PGP": {
"TITLE_COMPOSE_OPEN_PGP": "OpenPGP підпис і шифрування",
"OPENPGP": {
"POPUP_IMPORT_TITLE": "Імпорт OpenPGP ключа",
"POPUP_IMPORT_BUTTON": "Імпорт",
"POPUP_VIEW_TITLE": "Перегляд OpenPGP ключа",
"POPUP_VIEW_BUTTON": "Вибрати",
"POPUP_GENERATE_TITLE": "Генерація OpenPGP ключа",
"POPUP_GENERATE_BUTTON": "Створити",
"LABEL_KEY_TYPE": "Type",
"LABEL_SIGN": "Підпис",
"LABEL_ENCRYPT": "Шифрування",
"BUTTON_SIGN": "Підпис",
"BUTTON_ENCRYPT": "Шифрування",
"BUTTON_SIGN_AND_ENCRYPT": "Підпис и шифрування"
},
"POPUPS_MESSAGE_OPEN_PGP": {
"TITLE_MESSAGE_OPEN_PGP": "OpenPGP Decrypt",
"LABEL_KEY": "Private Key",
"BUTTON_DECRYPT": "Дешифрувати"
},
"POPUPS_FILTER": {
@ -469,7 +453,6 @@
"BUTTON_GENERATE_OPEN_PGP_KEYS": "Новий OpenPGP ключ",
"TITLE_PRIVATE": "Приватний",
"TITLE_PUBLIC": "Публічний",
"GENERATE_ONLY_HTTPS": "тільки HTTPS",
"LABEL_ALLOW_DRAFT_AUTOSAVE": "Automatically save draft"
},
"SHORTCUTS_HELP": {

View file

@ -151,7 +151,6 @@
"PGP_SIGNED_MESSAGE_DESC": "由 OpenPGP 签名",
"BUTTON_PGP_VERIFY": "点击验证",
"PGP_ENCRYPTED_MESSAGE_DESC": "由 OpenPGP 加密",
"BUTTON_PGP_DECRYPT": "点击解密",
"LINK_DOWNLOAD_AS_ZIP": "下载为zip压缩包",
"SPAM_SCORE": "垃圾邮件分数",
"HAS_VIRUS_WARNING": "警告:检测到病毒"
@ -216,7 +215,6 @@
"ATTACHMENTS_UPLOAD_ERROR_DESC": "还有附件正在上传。",
"BUTTON_REQUEST_READ_RECEIPT": "要求已读回执",
"BUTTON_MARK_AS_IMPORTANT": "标记为“重要”",
"BUTTON_OPEN_PGP": "OpenPGP (仅限纯文本)",
"BUTTON_REQUEST_DSN": "要求送达回执"
},
"POPUPS_ASK": {
@ -254,30 +252,16 @@
"DANGER_DESC_HTML_2": "一旦操作执行,将不可中断和撤销!",
"TITLE_CLEARING_PROCESS": "文件夹清理中..."
},
"POPUPS_IMPORT_OPEN_PGP_KEY": {
"TITLE_IMPORT_OPEN_PGP_KEY": "导入 OpenPGP 密钥",
"BUTTON_IMPORT_OPEN_PGP_KEY": "导入"
},
"POPUPS_VIEW_OPEN_PGP_KEY": {
"TITLE_VIEW_OPEN_PGP_KEY": "查看 OpenPGP 密钥",
"BUTTON_SELECT": "选择"
},
"POPUPS_GENERATE_OPEN_PGP_KEYS": {
"TITLE_GENERATE_OPEN_PGP_KEYS": "生成 OpenPGP 密钥",
"LABEL_KEY_BIT_LENGTH": "密钥长度",
"BUTTON_GENERATE_OPEN_PGP_KEYS": "生成"
},
"POPUPS_COMPOSE_OPEN_PGP": {
"TITLE_COMPOSE_OPEN_PGP": "OpenPGP 签名\/加密",
"OPENPGP": {
"POPUP_IMPORT_TITLE": "导入 OpenPGP 密钥",
"POPUP_IMPORT_BUTTON": "导入",
"POPUP_VIEW_TITLE": "查看 OpenPGP 密钥",
"POPUP_VIEW_BUTTON": "选择",
"POPUP_GENERATE_TITLE": "生成 OpenPGP 密钥",
"POPUP_GENERATE_BUTTON": "生成",
"LABEL_KEY_TYPE": "Type",
"LABEL_SIGN": "签名",
"LABEL_ENCRYPT": "加密",
"BUTTON_SIGN": "签名",
"BUTTON_ENCRYPT": "加密",
"BUTTON_SIGN_AND_ENCRYPT": "签名并加密"
},
"POPUPS_MESSAGE_OPEN_PGP": {
"TITLE_MESSAGE_OPEN_PGP": "OpenPGP 解密",
"LABEL_KEY": "私钥",
"BUTTON_DECRYPT": "解密"
},
"POPUPS_FILTER": {
@ -469,7 +453,6 @@
"BUTTON_GENERATE_OPEN_PGP_KEYS": "生成 OpenPGP 密钥",
"TITLE_PRIVATE": "私有",
"TITLE_PUBLIC": "公开",
"GENERATE_ONLY_HTTPS": "仅限HTTPS",
"LABEL_ALLOW_DRAFT_AUTOSAVE": "自动保存草稿"
},
"SHORTCUTS_HELP": {

View file

@ -151,7 +151,6 @@
"PGP_SIGNED_MESSAGE_DESC": "OpenPGP signed message",
"BUTTON_PGP_VERIFY": "click to verify",
"PGP_ENCRYPTED_MESSAGE_DESC": "OpenPGP encrypted message",
"BUTTON_PGP_DECRYPT": "click to decrypt",
"LINK_DOWNLOAD_AS_ZIP": "Download as zip",
"SPAM_SCORE": "Spam Score",
"HAS_VIRUS_WARNING": "WARNING: virus detected"
@ -216,7 +215,6 @@
"ATTACHMENTS_UPLOAD_ERROR_DESC": "Not all attachments have been uploaded yet",
"BUTTON_REQUEST_READ_RECEIPT": "Request a read receipt",
"BUTTON_MARK_AS_IMPORTANT": "Mark as important",
"BUTTON_OPEN_PGP": "OpenPGP (Plain Text Only)",
"BUTTON_REQUEST_DSN": "Request a delivery receipt"
},
"POPUPS_ASK": {
@ -254,30 +252,16 @@
"DANGER_DESC_HTML_2": "一旦操作執行,不可中斷和撤銷!",
"TITLE_CLEARING_PROCESS": "資料夾清理中..."
},
"POPUPS_IMPORT_OPEN_PGP_KEY": {
"TITLE_IMPORT_OPEN_PGP_KEY": "導入 OpenPGP 密鑰",
"BUTTON_IMPORT_OPEN_PGP_KEY": "導入"
},
"POPUPS_VIEW_OPEN_PGP_KEY": {
"TITLE_VIEW_OPEN_PGP_KEY": "查看 OpenPGP 密鑰",
"BUTTON_SELECT": "選擇"
},
"POPUPS_GENERATE_OPEN_PGP_KEYS": {
"TITLE_GENERATE_OPEN_PGP_KEYS": "生成 OpenPGP 密鑰",
"LABEL_KEY_BIT_LENGTH": "密鑰長度",
"BUTTON_GENERATE_OPEN_PGP_KEYS": "生成"
},
"POPUPS_COMPOSE_OPEN_PGP": {
"TITLE_COMPOSE_OPEN_PGP": "OpenPGP Sign\/Encrypt",
"OPENPGP": {
"POPUP_IMPORT_TITLE": "導入 OpenPGP 密鑰",
"POPUP_IMPORT_BUTTON": "導入",
"POPUP_VIEW_TITLE": "查看 OpenPGP 密鑰",
"POPUP_VIEW_BUTTON": "選擇",
"POPUP_GENERATE_TITLE": "生成 OpenPGP 密鑰",
"POPUP_GENERATE_BUTTON": "生成",
"LABEL_KEY_TYPE": "Type",
"LABEL_SIGN": "Sign",
"LABEL_ENCRYPT": "Encrypt",
"BUTTON_SIGN": "Sign",
"BUTTON_ENCRYPT": "Encrypt",
"BUTTON_SIGN_AND_ENCRYPT": "Sign and encrypt"
},
"POPUPS_MESSAGE_OPEN_PGP": {
"TITLE_MESSAGE_OPEN_PGP": "OpenPGP Decrypt",
"LABEL_KEY": "Private Key",
"BUTTON_DECRYPT": "Decrypt"
},
"POPUPS_FILTER": {
@ -469,7 +453,6 @@
"BUTTON_GENERATE_OPEN_PGP_KEYS": "生成 OpenPGP 密鑰",
"TITLE_PRIVATE": "私有",
"TITLE_PUBLIC": "公開",
"GENERATE_ONLY_HTTPS": "HTTPS only",
"LABEL_ALLOW_DRAFT_AUTOSAVE": "Automatically save draft"
},
"SHORTCUTS_HELP": {

View file

@ -323,7 +323,7 @@
<div class="openpgp-control encrypted" data-bind="visible: pgpEncrypted">
<i class="fontastic">🔒</i>
<span data-i18n="MESSAGE/PGP_ENCRYPTED_MESSAGE_DESC"></span>
<button data-bind="visible: pgpSupported, click: pgpDecrypt" data-i18n="MESSAGE/BUTTON_PGP_DECRYPT"></button>
<button data-bind="visible: pgpSupported, click: pgpDecrypt" data-i18n="OPENPGP/BUTTON_DECRYPT"></button>
</div>
<div class="openpgp-control signed" data-bind="visible: pgpSigned">
<i class="fontastic">✍️</i>

View file

@ -85,13 +85,13 @@
<li class="dividerbar" data-bind="click: togglePgpSign, css: {'disabled': !canPgpSign()}">
<a>
<i class="fontastic" data-bind="text: pgpSign() ? '✍' : '☐'"></i>
<span data-i18n="POPUPS_COMPOSE_OPEN_PGP/LABEL_SIGN"></span>
<span data-i18n="OPENPGP/LABEL_SIGN"></span>
</a>
</li>
<li data-bind="click: togglePgpEncrypt, css: {'disabled': !canPgpEncrypt()}">
<a>
<i class="fontastic" data-bind="text: pgpEncrypt() ? '🔒' : '☐'"></i>
<span data-i18n="POPUPS_COMPOSE_OPEN_PGP/LABEL_ENCRYPT"></span>
<span data-i18n="OPENPGP/LABEL_ENCRYPT"></span>
</a>
</li>
<!-- /ko -->

View file

@ -1,37 +0,0 @@
<header>
<a href="#" class="close" data-bind="command: cancelCommand">×</a>
<h3 data-i18n="POPUPS_MESSAGE_OPEN_PGP/TITLE_MESSAGE_OPEN_PGP"></h3>
</header>
<div class="modal-body">
<div class="form-horizontal">
<div class="alert" data-bind="visible: '' !== notification()">
<span data-bind="text: notification"></span>
</div>
<div class="control-group">
<label data-i18n="POPUPS_MESSAGE_OPEN_PGP/LABEL_KEY"></label>
<div class="key-list" data-bind="foreach: privateKeys" style="margin-top: 5px">
<div class="key-list__item">
<i class="key-list__item__radio fontastic"></i>
<div class="key-list__item__names" data-bind="foreach: users">
<div class="key-list__item__name">
<span data-bind="text: $data"></span>
&nbsp;
[<span data-bind="text: $parent.id"></span>]
</div>
</div>
</div>
</div>
</div>
<div class="control-group">
<label data-i18n="GLOBAL/PASSWORD"></label>
<input type="password" class="inputPassword input-xlarge" autofocus="" autocomplete="current-password" autocorrect="off" autocapitalize="off" spellcheck="false"
data-bind="textInput: password, onEnter: doCommand" />
</div>
</div>
</div>
<footer>
<button class="btn buttonDo" data-bind="command: doCommand">
<i class="fontastic" data-bind="css: {'icon-spinner': submitRequest()}">🔑</i>
<span data-i18n="POPUPS_MESSAGE_OPEN_PGP/BUTTON_DECRYPT"></span>
</button>
</footer>

View file

@ -1,6 +1,6 @@
<header>
<a href="#" class="close" data-bind="command: cancelCommand">×</a>
<h3 data-i18n="POPUPS_GENERATE_OPEN_PGP_KEYS/TITLE_GENERATE_OPEN_PGP_KEYS"></h3>
<h3 data-i18n="OPENPGP/POPUP_GENERATE_TITLE"></h3>
</header>
<form class="modal-body form-horizontal" autocomplete="off">
<div class="alert" data-bind="visible: '' !== submitError()">
@ -9,7 +9,14 @@
</div>
<div class="control-group" data-bind="css: {'error': emailError}">
<label data-i18n="GLOBAL/EMAIL"></label>
<select class="input-xlarge" data-bind="value: email, options: identities, optionsText: 'email', optionsValue: 'email'"></select>
<input type="text" class="input-xlarge"
autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"
list="emailaddresses" data-bind="value: email" />
<datalist id="emailaddresses">
<!-- ko foreach: identities -->
<option data-bind="attr:{value:email}"></option>
<!-- /ko -->
</datalist>
</div>
<div class="control-group">
<label data-i18n="GLOBAL/NAME"></label>
@ -24,13 +31,29 @@
data-bind="value: password" />
</div>
<div class="control-group">
<label data-i18n="POPUPS_GENERATE_OPEN_PGP_KEYS/LABEL_KEY_BIT_LENGTH"></label>
<select data-bind="value: keyBitLength, options: [2048, 4096]"></select>
<label data-i18n="OPENPGP/LABEL_KEY_TYPE"></label>
<select data-bind="value: keyType, options: ['ECC', 'RSA']"></select>
</div>
<div class="control-group">
<div data-bind="component: {
name: 'Checkbox',
params: {
label: 'Store on server',
value: saveServer
}
}"></div>
<div data-bind="visible: canGnuPG, component: {
name: 'Checkbox',
params: {
label: 'Store on server in GnuPG',
value: saveGnuPG
}
}"></div>
</div>
</form>
<footer>
<a class="btn buttonHenerateOpenPgpKey" data-bind="command: generateOpenPgpKeyCommand">
<a class="btn" data-bind="command: generateOpenPgpKeyCommand">
<i class="fontastic" data-bind="css: {'icon-spinner': submitRequest()}">🔑</i>
<span data-i18n="POPUPS_GENERATE_OPEN_PGP_KEYS/BUTTON_GENERATE_OPEN_PGP_KEYS"></span>
<span data-i18n="OPENPGP/POPUP_GENERATE_BUTTON"></span>
</a>
</footer>

View file

@ -1,6 +1,6 @@
<header>
<a href="#" class="close" data-bind="command: cancelCommand">×</a>
<h3 data-i18n="POPUPS_IMPORT_OPEN_PGP_KEY/TITLE_IMPORT_OPEN_PGP_KEY"></h3>
<h3 data-i18n="OPENPGP/POPUP_IMPORT_TITLE"></h3>
</header>
<div class="modal-body">
<div class="alert" data-bind="visible: keyError() && keyErrorMessage(), text: keyErrorMessage"></div>
@ -9,27 +9,27 @@
<textarea class="inputKey input-xxlarge" rows="14" autofocus="" autocomplete="off" data-bind="value: key"></textarea>
</div>
<div class="control-group">
<div data-bind="component: {
name: 'Checkbox',
params: {
label: 'Store on server',
value: saveServer
}
}"></div>
<div data-bind="visible: canGnuPG, component: {
name: 'Checkbox',
params: {
label: 'Store in GnuPG',
label: 'Store on server in GnuPG',
value: saveGnuPG
}
}"></div>
<div data-bind="visible: canOpenPGP, component: {
name: 'Checkbox',
params: {
label: 'Store in OpenPGP.js',
value: saveOpenPGP
}
}"></div>
</div>
</div>
</div>
<footer>
<a class="btn buttonAddAccount" data-bind="command: addOpenPgpKeyCommand">
<a class="btn" data-bind="command: addOpenPgpKeyCommand">
<i class="icon-list-add"></i>
&nbsp;&nbsp;
<span data-i18n="POPUPS_IMPORT_OPEN_PGP_KEY/BUTTON_IMPORT_OPEN_PGP_KEY"></span>
<span data-i18n="OPENPGP/POPUP_IMPORT_BUTTON"></span>
</a>
</footer>

View file

@ -1,6 +1,6 @@
<header class="g-ui-user-select-none">
<a href="#" class="close" data-bind="command: cancelCommand">×</a>
<h3 data-i18n="POPUPS_VIEW_OPEN_PGP_KEY/TITLE_VIEW_OPEN_PGP_KEY"></h3>
<h3 data-i18n="OPENPGP/POPUP_VIEW_TITLE"></h3>
</header>
<div class="modal-body">
<div class="form-horizontal">
@ -16,6 +16,6 @@
</a>
<a class="btn buttonClose" data-bind="click: selectKey">
<i class="fontastic">🔑</i>
<span data-i18n="POPUPS_VIEW_OPEN_PGP_KEY/BUTTON_SELECT"></span>
<span data-i18n="OPENPGP/POPUP_VIEW_BUTTON"></span>
</a>
</footer>

View file

@ -5,7 +5,7 @@
</button>
<!-- ko if: canOpenPGP || canGnuPG -->
&nbsp;&nbsp;
<div style="display: inline-block" data-i18n="[title]SETTINGS_OPEN_PGP/GENERATE_ONLY_HTTPS">
<div style="display: inline-block">
<button class="btn" data-bind="click: generateOpenPgpKey">
<i class="fontastic">🔑</i>
<span data-i18n="SETTINGS_OPEN_PGP/BUTTON_GENERATE_OPEN_PGP_KEYS"></span>
@ -30,15 +30,12 @@
<div class="legend">GnuPG</div>
<table class="table table-hover list-table">
<tbody data-bind="foreach: gnupgkeys, i18nUpdate: gnupgkeys">
<tr class="open-pgp-key-item">
<tr>
<td>
<span data-bind="visible: can_sign" class="fontastic" data-i18n="[title]SETTINGS_OPEN_PGP/TITLE_PRIVATE">✍/🔓</span>
<td>
<td>
<span data-bind="visible: can_encrypt" class="fontastic" data-i18n="[title]SETTINGS_OPEN_PGP/TITLE_PUBLIC">🔒</span>
</td>
<td>
<!-- ko text: email --><!-- /ko -->
<span data-bind="visible: can_sign" class="fontastic"></span>
<span data-bind="visible: can_encrypt" class="fontastic">🔒</span>
<span data-bind="visible: can_decrypt" class="fontastic">🔓</span>
<span class="open-pgp-key-user" data-bind="text: email"></span>
</td>
</tr>
</tbody>
@ -48,13 +45,14 @@
<!-- ko if: canOpenPGP -->
<div class="legend">OpenPGP.js</div>
<table class="table table-hover list-table">
<tbody><tr><th colspan="4" data-i18n="SETTINGS_OPEN_PGP/TITLE_PRIVATE">Private keys</th></tr></tbody>
<tbody data-bind="foreach: openpgpkeysPrivate, i18nUpdate: openpgpkeysPrivate">
<tr class="open-pgp-key-item">
<td>
<span class="open-pgp-key-img fontastic" data-i18n="[title]SETTINGS_OPEN_PGP/TITLE_PRIVATE">🔒</span>
<span class="open-pgp-key-user" data-bind="foreach: users">
<span class="open-pgp-key-user-address" data-bind="text: $data" style="display:inline-block"></span>
</span>
<tr>
<td data-bind="click: function (openPgpKey) { $root.viewOpenPgpKey(openPgpKey); }">
<span class="fontastic" data-i18n="[title]SETTINGS_OPEN_PGP/TITLE_PRIVATE">🔒</span>
<!-- ko foreach: emails -->
<span class="open-pgp-key-user" data-bind="text: $data"></span>
<!-- /ko -->
</td>
<td>
<a class="btn btn-small btn-small-small btn-danger button-confirm-delete" data-bind="css: {'delete-access': deleteAccess()}, click: function(openPgpKey) { $root.deleteOpenPgpKey(openPgpKey); }"
@ -63,17 +61,16 @@
<td>
<span class="delete-open-pgp-key fontastic" data-bind="visible: !deleteAccess(), click: function (openPgpKey) { $root.openPgpKeyForDeletion(openPgpKey); }">🗑</span>
</td>
<td class="view-open-pgp-key fontastic" data-bind="click: function (openPgpKey) { $root.viewOpenPgpKey(openPgpKey); }">👁</td>
</tr>
</tbody><tbody data-bind="foreach: openpgpkeysPublic, i18nUpdate: openpgpkeysPublic">
<tr class="open-pgp-key-item">
<td>
<span class="open-pgp-key-img fontastic" data-i18n="[title]SETTINGS_OPEN_PGP/TITLE_PUBLIC">🔑</span>
<span class="open-pgp-key-user" data-bind="foreach: users">
<div class="open-pgp-key-user-address">
<span data-bind="text: $data"></span> (<span class="open-pgp-key-id" data-bind="text: $parent.id"></span>)
</div>
</span>
</tbody>
<tbody><tr><th colspan="4" data-i18n="SETTINGS_OPEN_PGP/TITLE_PUBLIC">Public keys</th></tr></tbody>
<tbody data-bind="foreach: openpgpkeysPublic, i18nUpdate: openpgpkeysPublic">
<tr>
<td data-bind="click: function (openPgpKey) { $root.viewOpenPgpKey(openPgpKey); }">
<span class="fontastic" data-i18n="[title]SETTINGS_OPEN_PGP/TITLE_PUBLIC">🔑</span>
<!-- ko foreach: emails -->
<span class="open-pgp-key-user" data-bind="text: $data"></span>
<!-- /ko -->
</td>
<td>
<a class="btn btn-small btn-small-small btn-danger button-confirm-delete" data-bind="css: {'delete-access': deleteAccess()}, click: function(oOpenPGP) { $root.deleteOpenPgpKey(oOpenPGP); }"
@ -82,7 +79,6 @@
<td>
<span class="delete-open-pgp-key fontastic" data-bind="visible: !deleteAccess(), click: function (openPgpKey) { $root.openPgpKeyForDeletion(openPgpKey); }">🗑</span>
</td>
<td class="view-open-pgp-key fontastic" data-bind="click: function (openPgpKey) { $root.viewOpenPgpKey(openPgpKey); }">👁</td>
</tr>
</tbody>
</table>

View file

@ -37,17 +37,10 @@ const jsServiceWorker = () => {
// OpenPGP
const jsOpenPGP = () => {
return gulp
.src('vendors/openpgp-2.6.2/dist/openpgp.js')
.src('vendors/openpgp-5/openpgp.js')
.pipe(gulp.dest(config.paths.staticJS));
};
// OpenPGP Worker
const jsOpenPGPWorker = () => {
return gulp
.src('vendors/openpgp-2.6.2/dist/openpgp.worker.min.js')
.pipe(gulp.dest(config.paths.staticMinJS));
};
// libs
const jsLibs = () => {
const src = config.paths.js.libs.src;
@ -131,6 +124,6 @@ exports.jsLint = jsLint;
exports.js = gulp.series(
jsClean,
jsLint,
gulp.parallel(jsBoot, jsServiceWorker, jsOpenPGP, jsOpenPGPWorker, jsLibs, jsApp, jsAdmin),
gulp.parallel(jsBoot, jsServiceWorker, jsOpenPGP, jsLibs, jsApp, jsAdmin),
jsMin
);

View file

@ -1,165 +0,0 @@
GNU LESSER GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
This version of the GNU Lesser General Public License incorporates
the terms and conditions of version 3 of the GNU General Public
License, supplemented by the additional permissions listed below.
0. Additional Definitions.
As used herein, "this License" refers to version 3 of the GNU Lesser
General Public License, and the "GNU GPL" refers to version 3 of the GNU
General Public License.
"The Library" refers to a covered work governed by this License,
other than an Application or a Combined Work as defined below.
An "Application" is any work that makes use of an interface provided
by the Library, but which is not otherwise based on the Library.
Defining a subclass of a class defined by the Library is deemed a mode
of using an interface provided by the Library.
A "Combined Work" is a work produced by combining or linking an
Application with the Library. The particular version of the Library
with which the Combined Work was made is also called the "Linked
Version".
The "Minimal Corresponding Source" for a Combined Work means the
Corresponding Source for the Combined Work, excluding any source code
for portions of the Combined Work that, considered in isolation, are
based on the Application, and not on the Linked Version.
The "Corresponding Application Code" for a Combined Work means the
object code and/or source code for the Application, including any data
and utility programs needed for reproducing the Combined Work from the
Application, but excluding the System Libraries of the Combined Work.
1. Exception to Section 3 of the GNU GPL.
You may convey a covered work under sections 3 and 4 of this License
without being bound by section 3 of the GNU GPL.
2. Conveying Modified Versions.
If you modify a copy of the Library, and, in your modifications, a
facility refers to a function or data to be supplied by an Application
that uses the facility (other than as an argument passed when the
facility is invoked), then you may convey a copy of the modified
version:
a) under this License, provided that you make a good faith effort to
ensure that, in the event an Application does not supply the
function or data, the facility still operates, and performs
whatever part of its purpose remains meaningful, or
b) under the GNU GPL, with none of the additional permissions of
this License applicable to that copy.
3. Object Code Incorporating Material from Library Header Files.
The object code form of an Application may incorporate material from
a header file that is part of the Library. You may convey such object
code under terms of your choice, provided that, if the incorporated
material is not limited to numerical parameters, data structure
layouts and accessors, or small macros, inline functions and templates
(ten or fewer lines in length), you do both of the following:
a) Give prominent notice with each copy of the object code that the
Library is used in it and that the Library and its use are
covered by this License.
b) Accompany the object code with a copy of the GNU GPL and this license
document.
4. Combined Works.
You may convey a Combined Work under terms of your choice that,
taken together, effectively do not restrict modification of the
portions of the Library contained in the Combined Work and reverse
engineering for debugging such modifications, if you also do each of
the following:
a) Give prominent notice with each copy of the Combined Work that
the Library is used in it and that the Library and its use are
covered by this License.
b) Accompany the Combined Work with a copy of the GNU GPL and this license
document.
c) For a Combined Work that displays copyright notices during
execution, include the copyright notice for the Library among
these notices, as well as a reference directing the user to the
copies of the GNU GPL and this license document.
d) Do one of the following:
0) Convey the Minimal Corresponding Source under the terms of this
License, and the Corresponding Application Code in a form
suitable for, and under terms that permit, the user to
recombine or relink the Application with a modified version of
the Linked Version to produce a modified Combined Work, in the
manner specified by section 6 of the GNU GPL for conveying
Corresponding Source.
1) Use a suitable shared library mechanism for linking with the
Library. A suitable mechanism is one that (a) uses at run time
a copy of the Library already present on the user's computer
system, and (b) will operate properly with a modified version
of the Library that is interface-compatible with the Linked
Version.
e) Provide Installation Information, but only if you would otherwise
be required to provide such information under section 6 of the
GNU GPL, and only to the extent that such information is
necessary to install and execute a modified version of the
Combined Work produced by recombining or relinking the
Application with a modified version of the Linked Version. (If
you use option 4d0, the Installation Information must accompany
the Minimal Corresponding Source and Corresponding Application
Code. If you use option 4d1, you must provide the Installation
Information in the manner specified by section 6 of the GNU GPL
for conveying Corresponding Source.)
5. Combined Libraries.
You may place library facilities that are a work based on the
Library side by side in a single library together with other library
facilities that are not Applications and are not covered by this
License, and convey such a combined library under terms of your
choice, if you do both of the following:
a) Accompany the combined library with a copy of the same work based
on the Library, uncombined with any other library facilities,
conveyed under the terms of this License.
b) Give prominent notice with the combined library that part of it
is a work based on the Library, and explaining where to find the
accompanying uncombined form of the same work.
6. Revised Versions of the GNU Lesser General Public License.
The Free Software Foundation may publish revised and/or new versions
of the GNU Lesser General Public License from time to time. Such new
versions will be similar in spirit to the present version, but may
differ in detail to address new problems or concerns.
Each version is given a distinguishing version number. If the
Library as you received it specifies that a certain numbered version
of the GNU Lesser General Public License "or any later version"
applies to it, you have the option of following the terms and
conditions either of that published version or of any later version
published by the Free Software Foundation. If the Library as you
received it does not specify a version number of the GNU Lesser
General Public License, you may choose any version of the GNU Lesser
General Public License ever published by the Free Software Foundation.
If the Library as you received it specifies that a proxy can decide
whether future versions of the GNU Lesser General Public License shall
apply, that proxy's public statement of acceptance of any version is
permanent authorization for you to choose that version for the
Library.

View file

@ -1,277 +0,0 @@
OpenPGP.js [![Build Status](https://travis-ci.org/openpgpjs/openpgpjs.svg?branch=master)](https://travis-ci.org/openpgpjs/openpgpjs)
==========
[OpenPGP.js](http://openpgpjs.org/) is a Javascript implementation of the OpenPGP protocol. This is defined in [RFC 4880](http://tools.ietf.org/html/rfc4880).
[![Saucelabs Test Status](https://saucelabs.com/browser-matrix/openpgpjs.svg)](https://saucelabs.com/u/openpgpjs)
### Platform support
* OpenPGP.js v2.x is written in ES6 but is transpiled to ES5 using [Babel](https://babeljs.io/) to run in most environments. We support node.js v0.12+ and browsers that implement [window.crypto.getRandomValues](http://caniuse.com/#feat=getrandomvalues).
* The api uses ES6 promises which are available in [most modern browsers](http://caniuse.com/#feat=promises). If you need to support browsers that do not support Promises, fear not! There is a [polyfill](https://github.com/jakearchibald/es6-promise), which is included in our build. So no action required on your part!
* For the OpenPGP HTTP Key Server (HKP) client the new [fetch api](http://caniuse.com/#feat=fetch) is used. There is a polyfill for both [browsers](https://github.com/github/fetch) and [node.js](https://github.com/bitinn/node-fetch) runtimes. The node module is included as a dependency if you install via npm, but we do not include the browser polyfill in our build. So you'll need to include it in your app if you intend to use the HKP client.
### Performance
* Version 2.x of the library has been built from the ground up with Uint8Arrays. This allows for much better performance and memory usage than strings.
* If the user's browser supports [native WebCrypto](http://caniuse.com/#feat=cryptography) via the `window.crypto.subtle` api, this will be used. Under node.js the native [crypto module](https://nodejs.org/api/crypto.html#crypto_crypto) is used. This can be deactivated by setting `openpgp.config.use_native = false`.
* The library implements the [IETF proposal](https://tools.ietf.org/html/draft-ford-openpgp-format-00) for authenticated encryption [using native AES-GCM](https://github.com/openpgpjs/openpgpjs/pull/430). This makes symmetric encryption about 30x faster on supported platforms. Since the specification has not been finalized and other OpenPGP implementations haven't adopted it yet, the feature is currently behind a flag. You can activate it by setting `openpgp.config.aead_protect = true`. **Note: activating this setting can break compatibility with other OpenPGP implementations, so be careful if that's one of your requirements.**
* For environments that don't provide native crypto, the library falls back to [asm.js](http://caniuse.com/#feat=asmjs) implementations of AES, SHA-1, and SHA-256. We use [Rusha](https://github.com/srijs/rusha) and [asmCrypto Lite](https://github.com/openpgpjs/asmcrypto-lite) (a minimal subset of asmCrypto.js built specifically for OpenPGP.js).
### Getting started
#### Npm
npm install --save openpgp
#### Bower
bower install --save openpgp
Or just fetch a minified build under [dist](https://github.com/openpgpjs/openpgpjs/tree/master/dist).
### Examples
Here are some examples of how to use the v2.x api. For more elaborate examples and working code, please check out the [public api unit tests](https://github.com/openpgpjs/openpgpjs/blob/master/test/general/openpgp.js). If you're upgrading from v1.x it might help to check out the [documentation](https://github.com/openpgpjs/openpgpjs#documentation).
#### Set up
```js
var openpgp = require('openpgp'); // use as CommonJS, AMD, ES6 module or via window.openpgp
openpgp.initWorker({ path:'openpgp.worker.js' }) // set the relative web worker path
openpgp.config.aead_protect = true // activate fast AES-GCM mode (not yet OpenPGP standard)
```
#### Encrypt and decrypt *Uint8Array* data with a password
```js
var options, encrypted;
options = {
data: new Uint8Array([0x01, 0x01, 0x01]), // input as Uint8Array (or String)
passwords: ['secret stuff'], // multiple passwords possible
armor: false // don't ASCII armor (for Uint8Array output)
};
openpgp.encrypt(options).then(function(ciphertext) {
encrypted = ciphertext.message.packets.write(); // get raw encrypted packets as Uint8Array
});
```
```js
options = {
message: openpgp.message.read(encrypted), // parse encrypted bytes
password: 'secret stuff', // decrypt with password
format: 'binary' // output as Uint8Array
};
openpgp.decrypt(options).then(function(plaintext) {
return plaintext.data // Uint8Array([0x01, 0x01, 0x01])
});
```
#### Encrypt and decrypt *String* data with PGP keys
```js
var options, encrypted;
var pubkey = '-----BEGIN PGP PUBLIC KEY BLOCK ... END PGP PUBLIC KEY BLOCK-----';
var privkey = '-----BEGIN PGP PRIVATE KEY BLOCK ... END PGP PRIVATE KEY BLOCK-----'; //encrypted private key
var passphrase = 'secret passphrase'; //what the privKey is encrypted with
var privKeyObj = openpgp.key.readArmored(privkey).keys[0];
privKeyObj.decrypt(passphrase);
options = {
data: 'Hello, World!', // input as String (or Uint8Array)
publicKeys: openpgp.key.readArmored(pubkey).keys, // for encryption
privateKeys: privKeyObj // for signing (optional)
};
openpgp.encrypt(options).then(function(ciphertext) {
encrypted = ciphertext.data; // '-----BEGIN PGP MESSAGE ... END PGP MESSAGE-----'
});
```
```js
options = {
message: openpgp.message.readArmored(encrypted), // parse armored message
publicKeys: openpgp.key.readArmored(pubkey).keys, // for verification (optional)
privateKey: privKeyObj // for decryption
};
openpgp.decrypt(options).then(function(plaintext) {
return plaintext.data; // 'Hello, World!'
});
```
#### Generate new key pair
```js
var options = {
userIds: [{ name:'Jon Smith', email:'jon@example.com' }], // multiple user IDs
numBits: 4096, // RSA key size
passphrase: 'super long and hard to guess secret' // protects the private key
};
openpgp.generateKey(options).then(function(key) {
var privkey = key.privateKeyArmored; // '-----BEGIN PGP PRIVATE KEY BLOCK ... '
var pubkey = key.publicKeyArmored; // '-----BEGIN PGP PUBLIC KEY BLOCK ... '
});
```
#### Lookup public key on HKP server
```js
var hkp = new openpgp.HKP('https://pgp.mit.edu');
var options = {
query: 'alice@example.com'
};
hkp.lookup(options).then(function(key) {
var pubkey = openpgp.key.readArmored(key);
});
```
#### Upload public key to HKP server
```js
var hkp = new openpgp.HKP('https://pgp.mit.edu');
var pubkey = '-----BEGIN PGP PUBLIC KEY BLOCK ... END PGP PUBLIC KEY BLOCK-----';
hkp.upload(pubkey).then(function() { ... });
```
#### Sign and verify cleartext messages
```js
var options, cleartext, validity;
var pubkey = '-----BEGIN PGP PUBLIC KEY BLOCK ... END PGP PUBLIC KEY BLOCK-----';
var privkey = '-----BEGIN PGP PRIVATE KEY BLOCK ... END PGP PRIVATE KEY BLOCK-----'; //encrypted private key
var passphrase = 'secret passphrase'; //what the privKey is encrypted with
var privKeyObj = openpgp.key.readArmored(privkey).keys[0];
privKeyObj.decrypt(passphrase);
```
```js
options = {
data: 'Hello, World!', // input as String (or Uint8Array)
privateKeys: privKeyObj // for signing
};
openpgp.sign(options).then(function(signed) {
cleartext = signed.data; // '-----BEGIN PGP SIGNED MESSAGE ... END PGP SIGNATURE-----'
});
```
```js
options = {
message: openpgp.cleartext.readArmored(cleartext), // parse armored message
publicKeys: openpgp.key.readArmored(pubkey).keys // for verification
};
openpgp.verify(options).then(function(verified) {
validity = verified.signatures[0].valid; // true
if (validity) {
console.log('signed by key id ' + verified.signatures[0].keyid.toHex());
}
});
```
#### Create and verify *detached* signatures
```js
var options, cleartext, detachedSig, validity;
var pubkey = '-----BEGIN PGP PUBLIC KEY BLOCK ... END PGP PUBLIC KEY BLOCK-----';
var privkey = '-----BEGIN PGP PRIVATE KEY BLOCK ... END PGP PRIVATE KEY BLOCK-----'; //encrypted private key
var passphrase = 'secret passphrase'; //what the privKey is encrypted with
var privKeyObj = openpgp.key.readArmored(privkey).keys[0];
privKeyObj.decrypt(passphrase);
```
```js
options = {
data: 'Hello, World!', // input as String (or Uint8Array)
privateKeys: privKeyObj, // for signing
detached: true
};
openpgp.sign(options).then(function(signed) {
cleartext = signed.data;
detachedSig = signed.signature;
});
```
```js
options = {
message: openpgp.cleartext.readArmored(cleartext), // parse armored message
signature: openpgp.signature.readArmored(detachedSig), // parse detached signature
publicKeys: openpgp.key.readArmored(pubkey).keys // for verification
};
openpgp.verify(options).then(function(verified) {
validity = verified.signatures[0].valid; // true
if (validity) {
console.log('signed by key id ' + verified.signatures[0].keyid.toHex());
}
});
```
### Documentation
A jsdoc build of our code comments is available at [doc/index.html](http://openpgpjs.org/openpgpjs/doc/index.html). Public calls should generally be made through the OpenPGP object [doc/openpgp.html](http://openpgpjs.org/openpgpjs/doc/module-openpgp.html).
### Security Audit
To date the OpenPGP.js code base has undergone two complete security audits from [Cure53](https://cure53.de). The first audit's report has been published [here](https://github.com/openpgpjs/openpgpjs/wiki/Cure53-security-audit).
### Security recommendations
It should be noted that js crypto apps deployed via regular web hosting (a.k.a. [**host-based security**](https://www.schneier.com/blog/archives/2012/08/cryptocat.html)) provide users with less security than installable apps with auditable static versions. Installable apps can be deployed as a [Firefox](https://developer.mozilla.org/en-US/Marketplace/Options/Packaged_apps) or [Chrome](https://developer.chrome.com/apps/about_apps.html) packaged app. These apps are basically signed zip files and their runtimes typically enforce a strict [Content Security Policy (CSP)](http://www.html5rocks.com/en/tutorials/security/content-security-policy/) to protect users against [XSS](https://en.wikipedia.org/wiki/Cross-site_scripting). This [blogpost](https://tankredhase.com/2014/04/13/heartbleed-and-javascript-crypto/) explains the trust model of the web quite well.
It is also recommended to set a strong passphrase that protects the user's private key on disk.
### Development
To create your own build of the library, just run the following command after cloning the git repo. This will download all dependencies, run the tests and create a minified bundle under `dist/openpgp.min.js` to use in your project:
npm install && npm test
### How do I get involved?
You want to help, great! Go ahead and fork our repo, make your changes and send us a pull request.
### License
GNU Lesser General Public License (3.0 or any later version). Please take a look at the [LICENSE](LICENSE) file for more information.
### Resources
Below is a collection of resources, many of these were projects that were in someway a precursor to the current OpenPGP.js project. If you'd like to add your link here, please do so in a pull request or email to the list.
* [http://www.hanewin.net/encrypt/](http://www.hanewin.net/encrypt/)
* [https://github.com/seancolyer/gmail-crypt](https://github.com/seancolyer/gmail-crypt)
* [https://github.com/mete0r/jspg](https://github.com/mete0r/jspg)
* [http://fitblip.pub/JSPGP-Stuffs/](http://fitblip.pub/JSPGP-Stuffs/)
* [http://qooxdoo.org/contrib/project/crypto](http://qooxdoo.org/contrib/project/crypto)
* [https://github.com/GPGTools/Mobile/wiki/Introduction](https://github.com/GPGTools/Mobile/wiki/Introduction)
* [http://gpg4browsers.recurity.com/](http://gpg4browsers.recurity.com/)
* [https://github.com/gmontalvoriv/mailock](https://github.com/gmontalvoriv/mailock)

File diff suppressed because one or more lines are too long

View file

@ -1,99 +0,0 @@
// GPG4Browsers - An OpenPGP implementation in javascript
// Copyright (C) 2011 Recurity Labs GmbH
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// 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,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
self.window={};
importScripts('openpgp.js');
var openpgp = window.openpgp;
var MIN_SIZE_RANDOM_BUFFER = 40000;
var MAX_SIZE_RANDOM_BUFFER = 60000;
openpgp.crypto.random.randomBuffer.init(MAX_SIZE_RANDOM_BUFFER);
/**
* Handle messages from the main window.
* @param {Object} event Contains event type and data
*/
self.onmessage = event => {
var msg = event.data || {};
switch (msg.event) {
case 'configure':
configure(msg.config);
break;
case 'seed-random':
seedRandom(msg.buf);
break;
default:
delegate(msg.id, msg.event, msg.options || {});
}
};
/**
* Set config from main context to worker context.
* @param {Object} config The openpgp configuration
*/
function configure(config) {
for (var i in config) {
openpgp.config[i] = config[i];
}
}
/**
* Seed the library with entropy gathered window.crypto.getRandomValues
* as this api is only avalible in the main window.
* @param {ArrayBuffer} buffer Some random bytes
*/
function seedRandom(buffer) {
if (!(buffer instanceof Uint8Array)) {
buffer = new Uint8Array(buffer);
}
openpgp.crypto.random.randomBuffer.set(buffer);
}
/**
* Generic proxy function that handles all commands from the public api.
* @param {String} method The public api function to be delegated to the worker thread
* @param {Object} options The api function's options
*/
function delegate(id, method, options) {
if (typeof openpgp[method] !== 'function') {
response({ id:id, event:'method-return', err:'Unknown Worker Event' });
return;
}
// parse cloned packets
options = openpgp.packet.clone.parseClonedPackets(options, method);
openpgp[method](options).then(function(data) {
// clone packets (for web worker structured cloning algorithm)
response({ id:id, event:'method-return', data:openpgp.packet.clone.clonePackets(data) });
}).catch(function(e) {
response({ id:id, event:'method-return', err:e.message, stack:e.stack });
});
}
/**
* Respond to the main window.
* @param {Object} event Contains event type and data
*/
function response(event) {
if (openpgp.crypto.random.randomBuffer.size < MIN_SIZE_RANDOM_BUFFER) {
self.postMessage({event: 'request-seed'});
}
self.postMessage(event, openpgp.util.getTransferables.call(openpgp.util, event.data));
}

View file

@ -1 +0,0 @@
self.window={};importScripts("openpgp.min.js");var openpgp=window.openpgp,MIN_SIZE_RANDOM_BUFFER=4e4,MAX_SIZE_RANDOM_BUFFER=6e4;function configure(e){for(var n in e)openpgp.config[n]=e[n]}function seedRandom(e){e instanceof Uint8Array||(e=new Uint8Array(e)),openpgp.crypto.random.randomBuffer.set(e)}function delegate(e,n,o){"function"==typeof openpgp[n]?(o=openpgp.packet.clone.parseClonedPackets(o,n),openpgp[n](o).then((function(n){response({id:e,event:"method-return",data:openpgp.packet.clone.clonePackets(n)})})).catch((function(n){response({id:e,event:"method-return",err:n.message,stack:n.stack})}))):response({id:e,event:"method-return",err:"Unknown Worker Event"})}function response(e){openpgp.crypto.random.randomBuffer.size<MIN_SIZE_RANDOM_BUFFER&&self.postMessage({event:"request-seed"}),self.postMessage(e,openpgp.util.getTransferables.call(openpgp.util,e.data))}openpgp.crypto.random.randomBuffer.init(MAX_SIZE_RANDOM_BUFFER),self.onmessage=e=>{var n=e.data||{};switch(n.event){case"configure":configure(n.config);break;case"seed-random":seedRandom(n.buf);break;default:delegate(n.id,n.event,n.options||{})}};

View file

@ -1,56 +0,0 @@
/*
npm install rollup rollup-plugin-includepaths rollup-plugin-babel rollup-plugin-external-globals rollup-plugin-html rollup-plugin-terser
rollup -c
*/
import includePaths from 'rollup-plugin-includepaths';
import { terser } from "rollup-plugin-terser";
//import resolve from '@rollup/plugin-node-resolve';
//import replace from '@rollup/plugin-replace';
//import commonjs from '@rollup/plugin-commonjs';
let includePathOptions = {
include: {},
paths: ['src'],
external: [],
extensions: ['.js']
};
let terserConfig = {
output: {
comments: false
},
keep_classnames: true, // Required for AbstractModel and AbstractCollectionModel
compress:{
ecma: 6,
drop_console: true
/*
,hoist_props: false
,keep_fargs: false
,toplevel: true
,unsafe_arrows: true // Issue with knockoutjs
,unsafe_methods: true
,unsafe_proto: true
*/
}
// ,mangle: {reserved:['SendMessage']}
};
export default [{
input: 'src/index.js',
output: [
{file: 'dist/snappymail/openpgp.js', format: 'iife'}, // format: 'es'
{file: 'dist/snappymail/openpgp.min.js', format: 'iife', plugins: [terser(terserConfig)], }
],
plugins: [
includePaths(includePathOptions)
// ,commonjs()
/*
replace({
'OpenPGP.js VERSION': `OpenPGP.js ${pkg.version}`,
'require(': 'void(',
delimiters: ['', '']
})
*/
]
}];

File diff suppressed because it is too large Load diff

View file

@ -1,235 +0,0 @@
// GPG4Browsers - An OpenPGP implementation in javascript
// Copyright (C) 2011 Recurity Labs GmbH
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// 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,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
/**
* @requires config
* @requires encoding/armor
* @requires enums
* @requires packet
* @module cleartext
*/
'use strict';
import config from './config';
import packet from './packet';
import enums from './enums.js';
import armor from './encoding/armor.js';
import * as sigModule from './signature.js';
/**
* @class
* @classdesc Class that represents an OpenPGP cleartext signed message.
* See {@link http://tools.ietf.org/html/rfc4880#section-7}
* @param {String} text The cleartext of the signed message
* @param {module:signature} signature The detached signature or an empty signature if message not yet signed
*/
export function CleartextMessage(text, signature) {
if (!(this instanceof CleartextMessage)) {
return new CleartextMessage(text, signature);
}
// normalize EOL to canonical form <CR><LF>
this.text = text.replace(/\r/g, '').replace(/[\t ]+\n/g, "\n").replace(/\n/g,"\r\n");
if (signature && !(signature instanceof sigModule.Signature)) {
throw new Error('Invalid signature input');
}
this.signature = signature || new sigModule.Signature(new packet.List());
}
/**
* Returns the key IDs of the keys that signed the cleartext message
* @return {Array<module:type/keyid>} array of keyid objects
*/
CleartextMessage.prototype.getSigningKeyIds = function() {
var keyIds = [];
var signatureList = this.signature.packets;
signatureList.forEach(function(packet) {
keyIds.push(packet.issuerKeyId);
});
return keyIds;
};
/**
* Sign the cleartext message
* @param {Array<module:key~Key>} privateKeys private keys with decrypted secret key data for signing
* @return {module:message~CleartextMessage} new cleartext message with signed content
*/
CleartextMessage.prototype.sign = function(privateKeys) {
return new CleartextMessage(this.text, this.signDetached(privateKeys));
};
/**
* Sign the cleartext message
* @param {Array<module:key~Key>} privateKeys private keys with decrypted secret key data for signing
* @return {module:signature~Signature} new detached signature of message content
*/
CleartextMessage.prototype.signDetached = function(privateKeys) {
var packetlist = new packet.List();
var literalDataPacket = new packet.Literal();
literalDataPacket.setText(this.text);
for (var i = 0; i < privateKeys.length; i++) {
if (privateKeys[i].isPublic()) {
throw new Error('Need private key for signing');
}
var signaturePacket = new packet.Signature();
signaturePacket.signatureType = enums.signature.text;
signaturePacket.hashAlgorithm = config.prefer_hash_algorithm;
var signingKeyPacket = privateKeys[i].getSigningKeyPacket();
signaturePacket.publicKeyAlgorithm = signingKeyPacket.algorithm;
if (!signingKeyPacket.isDecrypted) {
throw new Error('Private key is not decrypted.');
}
signaturePacket.sign(signingKeyPacket, literalDataPacket);
packetlist.push(signaturePacket);
}
return new sigModule.Signature(packetlist);
};
/**
* Verify signatures of cleartext signed message
* @param {Array<module:key~Key>} keys array of keys to verify signatures
* @return {Array<{keyid: module:type/keyid, valid: Boolean}>} list of signer's keyid and validity of signature
*/
CleartextMessage.prototype.verify = function(keys) {
return this.verifyDetached(this.signature, keys);
};
/**
* Verify signatures of cleartext signed message
* @param {Array<module:key~Key>} keys array of keys to verify signatures
* @return {Array<{keyid: module:type/keyid, valid: Boolean}>} list of signer's keyid and validity of signature
*/
CleartextMessage.prototype.verifyDetached = function(signature, keys) {
var result = [];
var signatureList = signature.packets;
var literalDataPacket = new packet.Literal();
// we assume that cleartext signature is generated based on UTF8 cleartext
literalDataPacket.setText(this.text);
for (var i = 0; i < signatureList.length; i++) {
var keyPacket = null;
for (var j = 0; j < keys.length; j++) {
keyPacket = keys[j].getSigningKeyPacket(signatureList[i].issuerKeyId);
if (keyPacket) {
break;
}
}
var verifiedSig = {};
if (keyPacket) {
verifiedSig.keyid = signatureList[i].issuerKeyId;
verifiedSig.valid = signatureList[i].verify(keyPacket, literalDataPacket);
} else {
verifiedSig.keyid = signatureList[i].issuerKeyId;
verifiedSig.valid = null;
}
var packetlist = new packet.List();
packetlist.push(signatureList[i]);
verifiedSig.signature = new sigModule.Signature(packetlist);
result.push(verifiedSig);
}
return result;
};
/**
* Get cleartext
* @return {String} cleartext of message
*/
CleartextMessage.prototype.getText = function() {
// normalize end of line to \n
return this.text.replace(/\r\n/g,"\n");
};
/**
* Returns ASCII armored text of cleartext signed message
* @return {String} ASCII armor
*/
CleartextMessage.prototype.armor = function() {
var body = {
hash: enums.read(enums.hash, config.prefer_hash_algorithm).toUpperCase(),
text: this.text,
data: this.signature.packets.write()
};
return armor.encode(enums.armor.signed, body);
};
/**
* reads an OpenPGP cleartext signed message and returns a CleartextMessage object
* @param {String} armoredText text to be parsed
* @return {module:cleartext~CleartextMessage} new cleartext message object
* @static
*/
export function readArmored(armoredText) {
var input = armor.decode(armoredText);
if (input.type !== enums.armor.signed) {
throw new Error('No cleartext signed message.');
}
var packetlist = new packet.List();
packetlist.read(input.data);
verifyHeaders(input.headers, packetlist);
var signature = new sigModule.Signature(packetlist);
var newMessage = new CleartextMessage(input.text, signature);
return newMessage;
}
/**
* Compare hash algorithm specified in the armor header with signatures
* @private
* @param {Array<String>} headers Armor headers
* @param {module:packet/packetlist} packetlist The packetlist with signature packets
*/
function verifyHeaders(headers, packetlist) {
var checkHashAlgos = function(hashAlgos) {
function check(algo) {
return packetlist[i].hashAlgorithm === algo;
}
for (var i = 0; i < packetlist.length; i++) {
if (packetlist[i].tag === enums.packet.signature && !hashAlgos.some(check)) {
return false;
}
}
return true;
};
var oneHeader = null;
var hashAlgos = [];
headers.forEach(function(header) {
oneHeader = header.match(/Hash: (.+)/); // get header value
if (oneHeader) {
oneHeader = oneHeader[1].replace(/\s/g, ''); // remove whitespace
oneHeader = oneHeader.split(',');
oneHeader = oneHeader.map(function(hash) {
hash = hash.toLowerCase();
try {
return enums.write(enums.hash, hash);
} catch (e) {
throw new Error('Unknown hash algorithm in armor header: ' + hash);
}
});
hashAlgos = hashAlgos.concat(oneHeader);
} else {
throw new Error('Only "Hash" header allowed in cleartext signed message');
}
});
if (!hashAlgos.length && !checkHashAlgos([enums.hash.md5])) {
throw new Error('If no "Hash" header in cleartext signed message, then only MD5 signatures allowed');
} else if (!checkHashAlgos(hashAlgos)) {
throw new Error('Hash algorithm mismatch in armor header and signature');
}
}

View file

@ -1,978 +0,0 @@
/** @license zlib.js 2012 - imaya [ https://github.com/imaya/zlib.js ] The MIT License */
(aa => {
'use strict';
function m(d) {
throw d;
}
var w = void 0,
z = !0,
Q = new Uint8Array(256),
T = 0,
ca,
pa = [],
d = b => {
switch (z) {
case 3 === b:
return [257, b - 3, 0];
case 4 === b:
return [258, b - 4, 0];
case 5 === b:
return [259, b - 5, 0];
case 6 === b:
return [260, b - 6, 0];
case 7 === b:
return [261, b - 7, 0];
case 8 === b:
return [262, b - 8, 0];
case 9 === b:
return [263, b - 9, 0];
case 10 === b:
return [264, b - 10, 0];
case 12 >= b:
return [265, b - 11, 1];
case 14 >= b:
return [266, b - 13, 1];
case 16 >= b:
return [267, b - 15, 1];
case 18 >= b:
return [268, b - 17, 1];
case 22 >= b:
return [269, b - 19, 2];
case 26 >= b:
return [270, b - 23, 2];
case 30 >= b:
return [271, b - 27, 2];
case 34 >= b:
return [272, b - 31, 2];
case 42 >= b:
return [273, b - 35, 3];
case 50 >= b:
return [274, b - 43, 3];
case 58 >= b:
return [275, b - 51, 3];
case 66 >= b:
return [276, b - 59, 3];
case 82 >= b:
return [277, b - 67, 4];
case 98 >= b:
return [278, b - 83, 4];
case 114 >= b:
return [279, b - 99, 4];
case 130 >= b:
return [280, b - 115, 4];
case 162 >= b:
return [281, b - 131, 5];
case 194 >= b:
return [282, b - 163, 5];
case 226 >= b:
return [283, b - 195, 5];
case 257 >= b:
return [284, b - 227, 5];
case 258 === b:
return [285, b - 258, 0];
default:
m("invalid length: " + b)
}
},
xa = (() => {
var a = new Uint32Array(),
c, e;
for (c = 3; 258 >= c; c++) e = d(c), a[c] = e[2] << 24 | e[1] << 16 | e[0];
return a
})(),
qa = (d, a) => {
function c(b, c) {
var a = b.G,
d = [],
e = 0,
f = xa[b.length];
d[e++] = f & 65535;
d[e++] = f >> 16 & 255;
d[e++] = f >> 24;
var g;
switch (z) {
case 1 === a:
g = [0, a - 1, 0];
break;
case 2 === a:
g = [1, a - 2, 0];
break;
case 3 === a:
g = [2, a - 3, 0];
break;
case 4 === a:
g = [3, a - 4, 0];
break;
case 6 >= a:
g = [4, a - 5, 1];
break;
case 8 >= a:
g = [5, a - 7, 1];
break;
case 12 >= a:
g = [6, a - 9, 2];
break;
case 16 >= a:
g = [7, a - 13, 2];
break;
case 24 >= a:
g = [8, a - 17, 3];
break;
case 32 >= a:
g = [9, a - 25, 3];
break;
case 48 >= a:
g = [10, a - 33, 4];
break;
case 64 >= a:
g = [11, a - 49, 4];
break;
case 96 >= a:
g = [12, a - 65, 5];
break;
case 128 >= a:
g = [13, a - 97, 5];
break;
case 192 >= a:
g = [14, a - 129, 6];
break;
case 256 >= a:
g = [15, a - 193, 6];
break;
case 384 >= a:
g = [16, a - 257, 7];
break;
case 512 >= a:
g = [17, a - 385, 7];
break;
case 768 >= a:
g = [18, a - 513, 8];
break;
case 1024 >= a:
g = [19, a - 769, 8];
break;
case 1536 >= a:
g = [20, a - 1025, 9];
break;
case 2048 >= a:
g = [21, a - 1537, 9];
break;
case 3072 >= a:
g = [22, a - 2049, 10];
break;
case 4096 >= a:
g = [23, a - 3073, 10];
break;
case 6144 >= a:
g = [24, a - 4097, 11];
break;
case 8192 >= a:
g = [25, a - 6145, 11];
break;
case 12288 >= a:
g = [26, a - 8193, 12];
break;
case 16384 >= a:
g = [27, a - 12289, 12];
break;
case 24576 >= a:
g = [28, a - 16385, 13];
break;
case 32768 >= a:
g = [29, a - 24577, 13];
break;
default:
m("invalid distance")
}
f = g;
d[e++] = f[0];
d[e++] = f[1];
d[e++] = f[2];
var h, k;
h = 0;
for (k = d.length; h < k; ++h) n[l++] = d[h];
t[d[0]]++;
x[d[3]]++;
s = b.length + c - 1;
r = null
}
var e, b, f, g, h, k = {},
p, q, r, n = new Uint16Array(2 * a.length),
l = 0,
s = 0,
t = new Uint32Array(286),
x = new Uint32Array(30),
E = d.w,
B;
t[256] = 1;
e = 0;
for (b = a.length; e < b; ++e) {
f = h = 0;
for (g = 3; f < g && e + f !== b; ++f) h = h << 8 | a[e + f];
k[h] === w && (k[h] = []);
p = k[h];
if (!(0 < s--)) {
for (; 0 < p.length && 32768 < e - p[0];) p.shift();
if (e + 3 >= b) {
r && c(r, -1);
f = 0;
for (g = b - e; f < g; ++f) B = a[e + f], n[l++] = B, ++t[B];
break
}
0 < p.length ? (q = ya(a, e, p), r ? r.length < q.length ? (B = a[e - 1], n[l++] = B, ++t[B], c(q, 0)) : c(r, -1) : q.length < E ? r = q : c(q, 0)) : r ? c(r, -1) : (B = a[e], n[l++] = B, ++t[B])
}
p.push(e)
}
n[l++] = 256;
t[256]++;
d.L = t;
d.K = x;
return n.subarray(0, l)
},
ya = (d, a, c) => {
var e, b, f = 0,
g, h, k, p, q = d.length;
h = 0;
p = c.length;
a: for (; h < p; h++) {
e = c[p - h - 1];
g = 3;
if (3 < f) {
for (k = f; 3 < k; k--)
if (d[e + k - 1] !== d[a + k - 1]) continue a;
g = f
}
for (; 258 > g && a + g < q && d[e + g] === d[a + g];) ++g;
g > f && (b = e, f = g);
if (258 === g) break
}
return {length: f, G: a - b}
},
ra = (d, a) => {
var c = d.length,
e = new ja(572),
b = new Uint8Array(c),
f, g, h, k, p;
for (k = 0; k < c; ++k) 0 < d[k] && e.push(k, d[k]);
f = Array(e.length / 2);
g = new Uint32Array(e.length / 2);
if (1 === f.length) return b[e.pop().index] = 1, b;
k = 0;
for (p = e.length / 2; k < p; ++k) f[k] = e.pop(), g[k] = f[k].value;
h = za(g, g.length, a);
k = 0;
for (p = f.length; k < p; ++k) b[f[k].index] = h[k];
return b
},
za = (d, a, c) => {
function e(b) {
var c = k[b][p[b]];
c === a ? (e(b + 1), e(b + 1)) : --g[c];
++p[b]
}
var b = new Uint16Array(c),
f = new Uint8Array(c),
g = new Uint8Array(a),
h = Array(c),
k = Array(c),
p = Array(c),
q = (1 << c) - a,
r = 1 << c - 1,
n, l, s, t, x;
b[c - 1] = a;
for (l = 0; l < c; ++l) q < r ? f[l] = 0 : (f[l] = 1, q -= r), q <<= 1, b[c - 2 - l] = (b[c - 1 - l] / 2 | 0) + a;
b[0] = f[0];
h[0] = Array(b[0]);
k[0] = Array(b[0]);
for (l = 1; l < c; ++l) b[l] > 2 * b[l - 1] + f[l] && (b[l] = 2 * b[l - 1] + f[l]), h[l] = Array(b[l]), k[l] = Array(b[l]);
for (n = 0; n < a; ++n) g[n] = c;
for (s = 0; s < b[c - 1]; ++s) h[c -
1][s] = d[s], k[c - 1][s] = s;
for (n = 0; n < c; ++n) p[n] = 0;
1 === f[c - 1] && (--g[0], ++p[c - 1]);
for (l = c - 2; 0 <= l; --l) {
t = n = 0;
x = p[l + 1];
for (s = 0; s < b[l]; s++) t = h[l + 1][x] + h[l + 1][x + 1], t > d[n] ? (h[l][s] = t, k[l][s] = a, x += 2) : (h[l][s] = d[n], k[l][s] = n, ++n);
p[l] = 0;
1 === f[l] && e(l)
}
return g
},
ta = d => {
var a = new Uint16Array(d.length),
c = [],
e = [],
b = 0,
f, g, h, k;
f = 0;
for (g = d.length; f < g; f++) c[d[f]] = (c[d[f]] | 0) + 1;
f = 1;
for (g = 16; f <= g; f++) e[f] = b, b += c[f] | 0, b <<= 1;
f = 0;
for (g = d.length; f < g; f++) {
b = e[d[f]];
e[d[f]] += 1;
h = a[f] = 0;
for (k = d[f]; h < k; h++) a[f] = a[f] << 1 | b & 1, b >>>= 1
}
return a
};
for (; 288 > T; T++) switch (z) {
case 143 >= T:
pa.push([T + 48, 8]);
break;
case 255 >= T:
pa.push([T - 144 + 400, 9]);
break;
case 279 >= T:
pa.push([T - 256 + 0, 7]);
break;
case 287 >= T:
pa.push([T - 280 + 192, 8]);
break;
default:
m("invalid literal: " + T)
}
for (ca = 0; 256 > ca; ++ca) {
for (var R = ca, ha = R, ia = 7, R = R >>> 1; R; R >>>= 1) ha <<= 1, ha |= R & 1, --ia;
Q[ca] = (ha << ia & 255) >>> 0
}
class I
{
constructor(d, a) {
this.index = "number" === typeof a ? a : 0;
this.i = 0;
this.buffer = d instanceof Uint8Array ? d : new Uint8Array(32768);
2 * this.buffer.length <= this.index && m(Error("invalid index"));
this.buffer.length <= this.index && this.f()
}
f() {
var d = this.buffer,
c = d.length,
e = new Uint8Array(c << 1);
e.set(d);
return this.buffer = e
}
d(d, a, c) {
var e = this.buffer,
b = this.index,
f = this.i,
g = e[b],
h;
c && 1 < a && (d = 8 < a ? (Q[d & 255] << 24 | Q[d >>> 8 & 255] << 16 | Q[d >>> 16 & 255] << 8 | Q[d >>> 24 & 255]) >> 32 - a : Q[d] >> 8 - a);
if (8 > a + f) g = g << a | d, f += a;
else
for (h = 0; h < a; ++h) g = g << 1 | d >> a - h - 1 & 1, 8 === ++f && (f = 0, e[b++] = Q[g], g = 0, b === e.length && (e = this.f()));
e[b] = g;
this.buffer = e;
this.i = f;
this.index = b
}
finish() {
var d = this.buffer,
a = this.index,
c;
0 < this.i && (d[a] <<= 8 - this.i, d[a] = Q[d[a]], a++);
c = d.subarray(0, a);
return c
}
}
class ja
{
constructor(d) {
this.buffer = new Uint16Array(2 * d);
this.length = 0
}
getParent(d) {
return 2 * ((d - 2) / 4 | 0)
}
push(d, a) {
var c, e, b = this.buffer,
f;
c = this.length;
b[this.length++] = a;
for (b[this.length++] = d; 0 < c;)
if (e = this.getParent(c), b[c] > b[e]) f = b[c], b[c] = b[e], b[e] = f, f = b[c + 1], b[c + 1] = b[e + 1], b[e + 1] = f, c = e;
else break;
return this.length
}
pop() {
var d, a, c = this.buffer,
e, b, f;
a = c[0];
d = c[1];
this.length -= 2;
c[0] = c[this.length];
c[1] = c[this.length + 1];
for (f = 0;;) {
b = 2 * f + 2;
if (b >= this.length) break;
b + 2 < this.length && c[b + 2] > c[b] && (b += 2);
if (c[b] > c[f]) e = c[f], c[f] = c[b], c[b] = e, e = c[f + 1], c[f + 1] = c[b + 1], c[b + 1] = e;
else break;
f = b
}
return {
index: d,
value: a,
length: this.length
}
}
}
class ka
{
constructor(d, a) {
this.h = 2;
this.w = 0;
this.input = d instanceof Array ? new Uint8Array(d) : d;
this.b = 0;
a && (a.lazy && (this.w = a.lazy), "number" === typeof a.compressionType && (this.h = a.compressionType), a.outputBuffer && (this.a = a.outputBuffer instanceof Array ? new Uint8Array(a.outputBuffer) : a.outputBuffer), "number" === typeof a.outputIndex && (this.b = a.outputIndex));
this.a || (this.a = new Uint8Array(32768))
}
compress() {
this.j();
}
j() {
var d, a, c, e, b = this.input;
switch (this.h) {
case 0:
c = 0;
for (e = b.length; c < e;) {
a = b.subarray(c, c + 65535);
c += a.length;
var f = a,
g = c === e,
h = w,
k = w,
p = w,
n = this.a,
l = this.b;
for (n = new Uint8Array(this.a.buffer); n.length <= l + f.length + 5;) n = new Uint8Array(n.length << 1);
n.set(this.a)
h = g ? 1 : 0;
n[l++] = h | 0;
k = f.length;
p = ~k + 65536 & 65535;
n[l++] = k & 255;
n[l++] = k >>> 8 & 255;
n[l++] = p & 255;
n[l++] = p >>> 8 & 255;
n.set(f, l), l += f.length, n = n.subarray(0, l);
this.b = l;
this.a = n
}
break;
case 1:
var s = new I(new Uint8Array(this.a.buffer), this.b);
s.d(1, 1, z);
s.d(1, 2, z);
var t = qa(this, b),
x, E, B;
x = 0;
for (E = t.length; x < E; x++)
if (B = t[x], I.prototype.d.apply(s, pa[B]), 256 < B) s.d(t[++x], t[++x], z), s.d(t[++x], 5), s.d(t[++x], t[++x], z);
else if (256 === B) break;
this.a = s.finish();
this.b = this.a.length;
break;
case 2:
var C = new I(new Uint8Array(this.a.buffer), this.b),
L, v, M, Y, Z, gb = [16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15],
da, Fa, ea, Ga, la, sa = Array(19),
Ha, $, ma, D, Ia;
L = 2;
C.d(1, 1, z);
C.d(L, 2, z);
v = qa(this, b);
da = ra(this.L, 15);
Fa = ta(da);
ea = ra(this.K, 7);
Ga = ta(ea);
for (M = 286; 257 < M && 0 === da[M - 1]; M--);
for (Y = 30; 1 < Y && 0 === ea[Y - 1]; Y--);
var Ja = M,
Ka = Y,
K = new Uint32Array(Ja + Ka),
u, N, y, fa, J = new Uint32Array(316),
H, F, O = new Uint8Array(19);
for (u = N = 0; u < Ja; u++) K[N++] = da[u];
for (u = 0; u < Ka; u++) K[N++] = ea[u];
u = H = 0;
for (fa = K.length; u < fa; u += N) {
for (N = 1; u + N < fa && K[u + N] === K[u]; ++N);
y = N;
if (0 === K[u])
if (3 > y)
for (; 0 < y--;) J[H++] =
0, O[0]++;
else
for (; 0 < y;) F = 138 > y ? y : 138, F > y - 3 && F < y && (F = y - 3), 10 >= F ? (J[H++] = 17, J[H++] = F - 3, O[17]++) : (J[H++] = 18, J[H++] = F - 11, O[18]++), y -= F;
else if (J[H++] = K[u], O[K[u]]++, y--, 3 > y)
for (; 0 < y--;) J[H++] = K[u], O[K[u]]++;
else
for (; 0 < y;) F = 6 > y ? y : 6, F > y - 3 && F < y && (F = y - 3), J[H++] = 16, J[H++] = F - 3, O[16]++, y -= F
}
d = J.subarray(0, H);
la = ra(O, 7);
for (D = 0; 19 > D; D++) sa[D] = la[gb[D]];
for (Z = 19; 4 < Z && 0 === sa[Z - 1]; Z--);
Ha = ta(la);
C.d(M - 257, 5, z);
C.d(Y - 1, 5, z);
C.d(Z - 4, 4, z);
for (D = 0; D < Z; D++) C.d(sa[D], 3, z);
D = 0;
for (Ia = d.length; D < Ia; D++)
if ($ =
d[D], C.d(Ha[$], la[$], z), 16 <= $) {
D++;
switch ($) {
case 16:
ma = 2;
break;
case 17:
ma = 3;
break;
case 18:
ma = 7;
break;
default:
m("invalid code: " + $)
}
C.d(d[D], ma, z)
}
var La = [Fa, da],
Ma = [Ga, ea],
P, Na, ga, va, Oa, Pa, Qa, Ra;
Oa = La[0];
Pa = La[1];
Qa = Ma[0];
Ra = Ma[1];
P = 0;
for (Na = v.length; P < Na; ++P)
if (ga = v[P], C.d(Oa[ga], Pa[ga], z), 256 < ga) C.d(v[++P], v[++P], z), va = v[++P], C.d(Qa[va], Ra[va], z), C.d(v[++P], v[++P], z);
else if (256 === ga) break;
this.a = C.finish();
this.b = this.a.length;
break;
default:
m("invalid compression type")
}
return this.a
}
}
var S = d => {
var a = d.length,
c = 0,
e = Number.POSITIVE_INFINITY,
b, f, g, h, k, p, q, r, n, l;
for (r = 0; r < a; ++r) d[r] > c && (c = d[r]), d[r] < e && (e = d[r]);
b = 1 << c;
f = new Uint32Array(b);
g = 1;
h = 0;
for (k = 2; g <= c;) {
for (r = 0; r < a; ++r)
if (d[r] === g) {
p = 0;
q = h;
for (n = 0; n < g; ++n) p = p << 1 | q & 1, q >>= 1;
l = g << 16 | r;
for (n = p; n < b; n += k) f[n] = l;
++h
}++g;
h <<= 1;
k <<= 1
}
return [f, c, e]
},
Sa = new Uint16Array([16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15]),
Wa = new Uint16Array([3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 258, 258]),
Ya = new Uint8Array([0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 0, 0]),
$a = new Uint16Array([1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577]),
bb = new Uint8Array([0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13]),
W = 288,
cb = new Uint8Array(W),
Ea = S((new Uint8Array(30)).fill(5)),
V = (d, a) => {
for (var c = d.g, e = d.e, b = d.input, f = d.c, g = b.length, h; e < a;) f >= g && m(Error("input buffer is broken")), c |= b[f++] << e, e += 8;
h = c & (1 << a) - 1;
d.g = c >>> a;
d.e = e - a;
d.c = f;
return h
},
Ta = (d, a) => {
for (var c = d.g, e = d.e, b = d.input, f = d.c, g = b.length, h = a[0], k = a[1], p, q; e < k && !(f >= g);) c |= b[f++] << e, e += 8;
p = h[c & (1 << k) - 1];
q = p >>> 16;
q > e && m(Error("invalid code length: " + q));
d.g = c >> q;
d.e = e - q;
d.c = f;
return p & 65535
};
while (W--) cb[W] = 143 >= W ? 8 : 255 >= W ? 9 : 279 >= W ? 7 : 8;
var Da = S(cb);
class U
{
constructor(d, a) {
this.l = [];
this.m = 32768;
this.e = this.g = this.c = this.q = 0;
this.input = new Uint8Array(d);
this.s = !1;
this.n = 1;
this.B = !1;
if (a || !(a = {})) a.index && (this.c = a.index), a.bufferSize && (this.m = a.bufferSize), a.bufferType && (this.n = a.bufferType), a.resize && (this.B = a.resize);
switch (this.n) {
case 0:
this.b = 32768;
this.a = new Uint8Array(32768 + this.m + 258);
break;
case 1:
this.b = 0;
this.a = new Uint8Array(this.m);
this.f = this.J;
this.t = this.H;
this.o = this.I;
break;
default:
m(Error("invalid inflate mode"))
}
}
decompress() {
this.p();
}
p() {
for (; !this.s;) {
var d = V(this, 3);
d & 1 && (this.s = z);
d >>>= 1;
switch (d) {
case 0:
var a = this.input,
c = this.c,
e = this.a,
b = this.b,
f = a.length,
g = w,
h = w,
k = e.length,
p = w;
this.e = this.g = 0;
c + 1 >= f && m(Error("invalid uncompressed block header: LEN"));
g = a[c++] | a[c++] << 8;
c + 1 >= f && m(Error("invalid uncompressed block header: NLEN"));
h = a[c++] | a[c++] << 8;
g === ~h && m(Error("invalid uncompressed block header: length verify"));
c + g > a.length && m(Error("input buffer is broken"));
switch (this.n) {
case 0:
for (; b + g > e.length;) {
p =
k - b;
g -= p;
e.set(a.subarray(c, c + p), b), b += p, c += p;
this.b = b;
e = this.f();
b = this.b
}
break;
case 1:
for (; b + g > e.length;) e = this.f({
v: 2
});
break;
default:
m(Error("invalid inflate mode"))
}
e.set(a.subarray(c, c + g), b), b += g, c += g;
this.c = c;
this.b = b;
this.a = e;
break;
case 1:
this.o(Da, Ea);
break;
case 2:
for (var q = V(this, 5) + 257, r = V(this, 5) + 1, n = V(this, 4) + 4, l = new Uint8Array(Sa.length), s = w, t = w, x = w, E = w, B = w, C = w, L = w, v = w, M = w, v = 0; v < n; ++v) l[Sa[v]] = V(this, 3);
s = S(l);
E = new Uint8Array(q + r);
v = 0;
for (M = q + r; v < M;) switch (B = Ta(this, s), B) {
case 16:
for (L = 3 + V(this, 2); L--;) E[v++] = C;
break;
case 17:
for (L = 3 + V(this, 3); L--;) E[v++] = 0;
C = 0;
break;
case 18:
for (L = 11 + V(this, 7); L--;) E[v++] = 0;
C = 0;
break;
default:
C = E[v++] = B
}
t = S(E.subarray(0, q));
x = S(E.subarray(q));
this.o(t, x);
break;
default:
m(Error("unknown BTYPE: " + d))
}
}
return this.t()
}
o(d, a) {
var c = this.a,
e = this.b;
this.u = d;
for (var b = c.length - 258, f, g, h, k; 256 !== (f = Ta(this, d));)
if (256 > f) e >= b && (this.b = e, c = this.f(), e = this.b), c[e++] = f;
else {
g = f - 257;
k = Wa[g];
0 < Ya[g] && (k += V(this, Ya[g]));
f = Ta(this, a);
h = $a[f];
0 < bb[f] && (h += V(this, bb[f]));
e >= b && (this.b = e, c = this.f(), e = this.b);
for (; k--;) c[e] = c[e++ - h]
}
for (; 8 <= this.e;) this.e -= 8, this.c--;
this.b = e
}
I(d, a) {
var c = this.a,
e = this.b;
this.u = d;
for (var b = c.length, f, g, h, k; 256 !== (f = Ta(this, d));)
if (256 > f) e >= b && (c = this.f(), b = c.length), c[e++] = f;
else {
g = f - 257;
k = Wa[g];
0 < Ya[g] && (k += V(this, Ya[g]));
f = Ta(this, a);
h = $a[f];
0 < bb[f] && (h += V(this, bb[f]));
e + k > b && (c = this.f(), b = c.length);
for (; k--;) c[e] = c[e++ - h]
}
for (; 8 <= this.e;) this.e -= 8, this.c--;
this.b = e
}
f() {
var d = new Uint8Array(this.b - 32768),
a = this.b - 32768,
b = this.a;
d.set(b.subarray(32768, d.length));
this.l.push(d);
this.q += d.length;
b.set(b.subarray(a, a + 32768));
this.b = 32768;
return b
}
J(d) {
var a, c = this.input.length / this.c + 1 | 0,
e, b, f, g = this.input,
h = this.a;
d && ("number" === typeof d.v && (c = d.v), "number" === typeof d.F && (c += d.F));
2 > c ? (e = (g.length - this.c) / this.u[2], f = 258 * (e / 2) | 0, b = f < h.length ? h.length + f : h.length << 1) : b = h.length * c;
a = new Uint8Array(b), a.set(h);
return this.a = a
}
t() {
var d = 0,
a = this.a,
c = this.l,
e, b = new Uint8Array(this.q + (this.b - 32768)),
f, g, h, k;
if (0 === c.length) return this.a.subarray(32768, this.b);
f = 0;
for (g = c.length; f < g; ++f) {
e = c[f];
h = 0;
for (k = e.length; h < k; ++h) b[d++] = e[h]
}
f = 32768;
for (g = this.b; f < g; ++f) b[d++] = a[f];
this.l = [];
return this.buffer = b
}
H() {
var d, a = this.b;
this.B ? (d = new Uint8Array(a), d.set(this.a.subarray(0, a))) : d = this.a.subarray(0, a);
return this.buffer = d
}
}
function ib(d) {
if ("string" === typeof d) {
var a = d.split(""),
c, e;
c = 0;
for (e = a.length; c < e; c++) a[c] = (a[c].charCodeAt(0) & 255) >>> 0;
d = a
}
for (var b = 1, f = 0, g = d.length, h, k = 0; 0 < g;) {
h = 1024 < g ? 1024 : g;
g -= h;
do b += d[k++], f += b; while (--h);
b %= 65521;
f %= 65521
}
return (f << 16 | b) >>> 0
}
class jb
{
constructor(d, a) {
var c, e;
this.input = d;
this.c = 0;
if (a || !(a = {})) a.index && (this.c = a.index), a.verify && (this.M = a.verify);
c = d[this.c++];
e = d[this.c++];
switch (c & 15) {
case 8:
this.method = 8;
break;
default:
m(Error("unsupported compression method"))
}
0 !== ((c << 8) + e) % 31 && m(Error("invalid fcheck flag:" + ((c << 8) + e) % 31));
e & 32 && m(Error("fdict flag is not supported"));
this.A = new U(d, {
index: this.c,
bufferSize: a.bufferSize,
bufferType: a.bufferType,
resize: a.resize
})
}
decompress() {
var d = this.input,
a, c;
a = this.A.p();
this.c = this.A.c;
this.M && (c = (d[this.c++] << 24 | d[this.c++] << 16 | d[this.c++] << 8 | d[this.c++]) >>> 0, c !== ib(a) && m(Error("invalid adler-32 checksum")));
return a
}
}
class lb
{
constructor(d, a) {
this.input = d;
this.a = new Uint8Array(32768);
this.h = 2;
var c = {},
e;
if ((a || !(a = {})) && "number" === typeof a.compressionType) this.h = a.compressionType;
for (e in a) c[e] = a[e];
c.outputBuffer = this.a;
this.z = new ka(this.input, c)
}
compress = function () {
var d, a, c, e, b, f, g, h = 0;
g = this.a;
d = 8;
switch (d) {
case 8:
a = Math.LOG2E * Math.log(32768) - 8;
break;
default:
m(Error("invalid compression method"))
}
c = a << 4 | d;
g[h++] = c;
switch (d) {
case 8:
switch (this.h) {
case 0:
b = 0;
break;
case 1:
b = 1;
break;
case 2:
b = 2;
break;
default:
m(Error("unsupported compression type"))
}
break;
default:
m(Error("invalid compression method"))
}
e = b << 6 | 0;
g[h++] = e | 31 - (256 * c + e) % 31;
f = ib(this.input);
this.z.b = h;
g = this.z.j();
h = g.length;
(g = new Uint8Array(g.buffer), g.length <=
h + 4 && (this.a = new Uint8Array(g.length + 4), this.a.set(g), g = this.a), g = g.subarray(0, h + 4));
g[h++] = f >> 24 & 255;
g[h++] = f >> 16 & 255;
g[h++] = f >> 8 & 255;
g[h++] = f & 255;
return g
}
}
U.BufferType = jb.BufferType = {
ADAPTIVE: 1,
BLOCK: 0
};
ka.CompressionType = lb.CompressionType = {
NONE: 0,
FIXED: 1,
DYNAMIC: 2
};
aa.Zlib = {
Inflate: jb,
Deflate: lb,
RawDeflate: ka,
RawInflate: U
};
})(this);

View file

@ -1,47 +0,0 @@
// GPG4Browsers - An OpenPGP implementation in javascript
// Copyright (C) 2011 Recurity Labs GmbH
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// 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,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
/**
* This object contains configuration values.
* @requires enums
* @property {Integer} prefer_hash_algorithm
* @property {Integer} encryption_cipher
* @property {Integer} compression
* @property {Boolean} show_version
* @property {Boolean} show_comment
* @property {Boolean} integrity_protect
* @property {String} keyserver
* @module config/config
*/
'use strict';
import enums from '../enums.js';
export default {
prefer_hash_algorithm: enums.hash.sha256,
encryption_cipher: enums.symmetric.aes256,
compression: enums.compression.zip,
aead_protect: false, // use Authenticated Encryption with Additional Data (AEAD) protection for symmetric encryption
integrity_protect: true, // use integrity protection for symmetric encryption
ignore_mdc_error: false, // fail on decrypt if message is not integrity protected
checksum_required: false, // do not throw error when armor is missing a checksum
verify_expired_keys: true, // allow signature verification with expired keys
zero_copy: false, // use transferable objects between the Web Worker and main thread
tolerant: true, // ignore unsupported/unrecognizable packets instead of throwing an error
keyserver: "https://keyserver.ubuntu.com"
};

View file

@ -1,8 +0,0 @@
/**
* @see module:config/config
* @module config
*/
'use strict';
export { default } from './config.js';

View file

@ -1,34 +0,0 @@
/**
* This object storing and retrieving configuration from HTML5 local storage.
* @module config/localStorage
*/
'use strict';
/**
* @constructor
*/
export default function LocalStorage() {}
/**
* Reads the config out of the HTML5 local storage
* and initializes the object config.
* if config is null the default config will be used
*/
LocalStorage.prototype.read = function () {
var raw = window.localStorage.getItem("config");
var cf = (raw === null ? null : JSON.parse(raw));
if (cf === null) {
this.config = this.default_config;
this.write();
} else {
this.config = cf;
}
};
/**
* Writes the config to HTML5 local storage
*/
LocalStorage.prototype.write = function () {
window.localStorage.setItem("config", JSON.stringify(this.config));
};

View file

@ -1,318 +0,0 @@
// Modified by ProtonTech AG
// Modified by Recurity Labs GmbH
// modified version of http://www.hanewin.net/encrypt/PGdecode.js:
/* OpenPGP encryption using RSA/AES
* Copyright 2005-2006 Herbert Hanewinkel, www.haneWIN.de
* version 2.0, check www.haneWIN.de for the latest version
* This software is provided as-is, without express or implied warranty.
* Permission to use, copy, modify, distribute or sell this software, with or
* without fee, for any purpose and by any individual or organization, is hereby
* granted, provided that the above copyright notice and this paragraph appear
* in all copies. Distribution as a part of an application or binary must
* include the above copyright notice in the documentation and/or other
* materials provided with the application or distribution.
*/
/**
* @requires crypto/cipher
* @module crypto/cfb
*/
'use strict';
import cipher from './cipher';
export default {
/**
* This function encrypts a given with the specified prefixrandom
* using the specified blockcipher to encrypt a message
* @param {Uint8Array} prefixrandom random bytes of block_size length
* to be used in prefixing the data
* @param {String} cipherfn the algorithm cipher class to encrypt
* data in one block_size encryption, {@link module:crypto/cipher}.
* @param {Uint8Array} plaintext data to be encrypted
* @param {Uint8Array} key key to be used to encrypt the plaintext.
* This will be passed to the cipherfn
* @param {Boolean} resync a boolean value specifying if a resync of the
* IV should be used or not. The encrypteddatapacket uses the
* "old" style with a resync. Encryption within an
* encryptedintegrityprotecteddata packet is not resyncing the IV.
* @return {Uint8Array} encrypted data
*/
encrypt: function(prefixrandom, cipherfn, plaintext, key, resync) {
cipherfn = new cipher[cipherfn](key);
var block_size = cipherfn.blockSize;
var FR = new Uint8Array(block_size);
var FRE = new Uint8Array(block_size);
var new_prefix = new Uint8Array(prefixrandom.length + 2);
new_prefix.set(prefixrandom);
new_prefix[prefixrandom.length] = prefixrandom[block_size-2];
new_prefix[prefixrandom.length+1] = prefixrandom[block_size-1];
prefixrandom = new_prefix;
var ciphertext = new Uint8Array(plaintext.length + 2 + block_size * 2);
var i, n, begin;
var offset = resync ? 0 : 2;
// 1. The feedback register (FR) is set to the IV, which is all zeros.
for (i = 0; i < block_size; i++) {
FR[i] = 0;
}
// 2. FR is encrypted to produce FRE (FR Encrypted). This is the
// encryption of an all-zero value.
FRE = cipherfn.encrypt(FR);
// 3. FRE is xored with the first BS octets of random data prefixed to
// the plaintext to produce C[1] through C[BS], the first BS octets
// of ciphertext.
for (i = 0; i < block_size; i++) {
ciphertext[i] = FRE[i] ^ prefixrandom[i];
}
// 4. FR is loaded with C[1] through C[BS].
FR.set(ciphertext.subarray(0, block_size));
// 5. FR is encrypted to produce FRE, the encryption of the first BS
// octets of ciphertext.
FRE = cipherfn.encrypt(FR);
// 6. The left two octets of FRE get xored with the next two octets of
// data that were prefixed to the plaintext. This produces C[BS+1]
// and C[BS+2], the next two octets of ciphertext.
ciphertext[block_size] = FRE[0] ^ prefixrandom[block_size];
ciphertext[block_size + 1] = FRE[1] ^ prefixrandom[block_size + 1];
if (resync) {
// 7. (The resync step) FR is loaded with C[3] through C[BS+2].
FR.set(ciphertext.subarray(2, block_size + 2));
} else {
FR.set(ciphertext.subarray(0, block_size));
}
// 8. FR is encrypted to produce FRE.
FRE = cipherfn.encrypt(FR);
// 9. FRE is xored with the first BS octets of the given plaintext, now
// that we have finished encrypting the BS+2 octets of prefixed
// data. This produces C[BS+3] through C[BS+(BS+2)], the next BS
// octets of ciphertext.
for (i = 0; i < block_size; i++) {
ciphertext[block_size + 2 + i] = FRE[i + offset] ^ plaintext[i];
}
for (n = block_size; n < plaintext.length + offset; n += block_size) {
// 10. FR is loaded with C[BS+3] to C[BS + (BS+2)] (which is C11-C18 for
// an 8-octet block).
begin = n + 2 - offset;
FR.set(ciphertext.subarray(begin, begin + block_size));
// 11. FR is encrypted to produce FRE.
FRE = cipherfn.encrypt(FR);
// 12. FRE is xored with the next BS octets of plaintext, to produce
// the next BS octets of ciphertext. These are loaded into FR, and
// the process is repeated until the plaintext is used up.
for (i = 0; i < block_size; i++) {
ciphertext[block_size + begin + i] = FRE[i] ^ plaintext[n + i - offset];
}
}
ciphertext = ciphertext.subarray(0, plaintext.length + 2 + block_size);
return ciphertext;
},
/**
* Decrypts the prefixed data for the Modification Detection Code (MDC) computation
* @param {String} cipherfn.encrypt Cipher function to use,
* @see module:crypto/cipher.
* @param {Uint8Array} key Uint8Array representation of key to be used to check the mdc
* This will be passed to the cipherfn
* @param {Uint8Array} ciphertext The encrypted data
* @return {Uint8Array} plaintext Data of D(ciphertext) with blocksize length +2
*/
mdc: function(cipherfn, key, ciphertext) {
cipherfn = new cipher[cipherfn](key);
var block_size = cipherfn.blockSize;
var iblock = new Uint8Array(block_size);
var ablock = new Uint8Array(block_size);
var i;
// initialisation vector
for (i = 0; i < block_size; i++) {
iblock[i] = 0;
}
iblock = cipherfn.encrypt(iblock);
for (i = 0; i < block_size; i++) {
ablock[i] = ciphertext[i];
iblock[i] ^= ablock[i];
}
ablock = cipherfn.encrypt(ablock);
var result = new Uint8Array(iblock.length + 2);
result.set(iblock);
result[iblock.length] = ablock[0] ^ ciphertext[block_size];
result[iblock.length + 1] = ablock[1] ^ ciphertext[block_size + 1];
return result;
},
/**
* This function decrypts a given plaintext using the specified
* blockcipher to decrypt a message
* @param {String} cipherfn the algorithm cipher class to decrypt
* data in one block_size encryption, {@link module:crypto/cipher}.
* @param {Uint8Array} key Uint8Array representation of key to be used to decrypt the ciphertext.
* This will be passed to the cipherfn
* @param {Uint8Array} ciphertext to be decrypted
* @param {Boolean} resync a boolean value specifying if a resync of the
* IV should be used or not. The encrypteddatapacket uses the
* "old" style with a resync. Decryption within an
* encryptedintegrityprotecteddata packet is not resyncing the IV.
* @return {Uint8Array} the plaintext data
*/
decrypt: function(cipherfn, key, ciphertext, resync) {
cipherfn = new cipher[cipherfn](key);
var block_size = cipherfn.blockSize;
var iblock = new Uint8Array(block_size);
var ablock = new Uint8Array(block_size);
var i, j, n;
var text = new Uint8Array(ciphertext.length - block_size);
// initialisation vector
for (i = 0; i < block_size; i++) {
iblock[i] = 0;
}
iblock = cipherfn.encrypt(iblock);
for (i = 0; i < block_size; i++) {
ablock[i] = ciphertext[i];
iblock[i] ^= ablock[i];
}
ablock = cipherfn.encrypt(ablock);
// test check octets
if (iblock[block_size - 2] !== (ablock[0] ^ ciphertext[block_size]) ||
iblock[block_size - 1] !== (ablock[1] ^ ciphertext[block_size + 1])) {
throw new Error('CFB decrypt: invalid key');
}
/* RFC4880: Tag 18 and Resync:
* [...] Unlike the Symmetrically Encrypted Data Packet, no
* special CFB resynchronization is done after encrypting this prefix
* data. See "OpenPGP CFB Mode" below for more details.
*/
j = 0;
if (resync) {
for (i = 0; i < block_size; i++) {
iblock[i] = ciphertext[i + 2];
}
for (n = block_size + 2; n < ciphertext.length; n += block_size) {
ablock = cipherfn.encrypt(iblock);
for (i = 0; i < block_size && i + n < ciphertext.length; i++) {
iblock[i] = ciphertext[n + i];
if(j < text.length) {
text[j] = ablock[i] ^ iblock[i];
j++;
}
}
}
} else {
for (i = 0; i < block_size; i++) {
iblock[i] = ciphertext[i];
}
for (n = block_size; n < ciphertext.length; n += block_size) {
ablock = cipherfn.encrypt(iblock);
for (i = 0; i < block_size && i + n < ciphertext.length; i++) {
iblock[i] = ciphertext[n + i];
if(j < text.length) {
text[j] = ablock[i] ^ iblock[i];
j++;
}
}
}
}
n = resync ? 0 : 2;
text = text.subarray(n, ciphertext.length - block_size - 2 + n);
return text;
},
normalEncrypt: function(cipherfn, key, plaintext, iv) {
cipherfn = new cipher[cipherfn](key);
var block_size = cipherfn.blockSize;
var blocki = new Uint8Array(block_size);
var blockc = new Uint8Array(block_size);
var pos = 0;
var cyphertext = new Uint8Array(plaintext.length);
var i, j = 0;
if (iv === null) {
for (i = 0; i < block_size; i++) {
blockc[i] = 0;
}
}
else {
for (i = 0; i < block_size; i++) {
blockc[i] = iv[i];
}
}
while (plaintext.length > block_size * pos) {
var encblock = cipherfn.encrypt(blockc);
blocki = plaintext.subarray((pos * block_size), (pos * block_size) + block_size);
for (i = 0; i < blocki.length; i++) {
blockc[i] = blocki[i] ^ encblock[i];
cyphertext[j++] = blockc[i];
}
pos++;
}
return cyphertext;
},
normalDecrypt: function(cipherfn, key, ciphertext, iv) {
cipherfn = new cipher[cipherfn](key);
var block_size = cipherfn.blockSize;
var blockp;
var pos = 0;
var plaintext = new Uint8Array(ciphertext.length);
var offset = 0;
var i, j = 0;
if (iv === null) {
blockp = new Uint8Array(block_size);
for (i = 0; i < block_size; i++) {
blockp[i] = 0;
}
}
else {
blockp = iv.subarray(0, block_size);
}
while (ciphertext.length > (block_size * pos)) {
var decblock = cipherfn.encrypt(blockp);
blockp = ciphertext.subarray((pos * (block_size)) + offset, (pos * (block_size)) + (block_size) + offset);
for (i = 0; i < blockp.length; i++) {
plaintext[j++] = blockp[i] ^ decblock[i];
}
pos++;
}
return plaintext;
}
};

View file

@ -1,514 +0,0 @@
/* Rijndael (AES) Encryption
* Copyright 2005 Herbert Hanewinkel, www.haneWIN.de
* version 1.1, check www.haneWIN.de for the latest version
* This software is provided as-is, without express or implied warranty.
* Permission to use, copy, modify, distribute or sell this software, with or
* without fee, for any purpose and by any individual or organization, is hereby
* granted, provided that the above copyright notice and this paragraph appear
* in all copies. Distribution as a part of an application or binary must
* include the above copyright notice in the documentation and/or other
* materials provided with the application or distribution.
*/
/**
* @module crypto/cipher/aes
*/
'use strict';
// The round constants used in subkey expansion
var Rcon = new Uint8Array([
0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8,
0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4,
0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91
]);
// Precomputed lookup table for the SBox
var S = new Uint8Array([
99, 124, 119, 123, 242, 107, 111, 197, 48, 1, 103, 43, 254, 215, 171,
118, 202, 130, 201, 125, 250, 89, 71, 240, 173, 212, 162, 175, 156, 164,
114, 192, 183, 253, 147, 38, 54, 63, 247, 204, 52, 165, 229, 241, 113,
216, 49, 21, 4, 199, 35, 195, 24, 150, 5, 154, 7, 18, 128, 226,
235, 39, 178, 117, 9, 131, 44, 26, 27, 110, 90, 160, 82, 59, 214,
179, 41, 227, 47, 132, 83, 209, 0, 237, 32, 252, 177, 91, 106, 203,
190, 57, 74, 76, 88, 207, 208, 239, 170, 251, 67, 77, 51, 133, 69,
249, 2, 127, 80, 60, 159, 168, 81, 163, 64, 143, 146, 157, 56, 245,
188, 182, 218, 33, 16, 255, 243, 210, 205, 12, 19, 236, 95, 151, 68,
23, 196, 167, 126, 61, 100, 93, 25, 115, 96, 129, 79, 220, 34, 42,
144, 136, 70, 238, 184, 20, 222, 94, 11, 219, 224, 50, 58, 10, 73,
6, 36, 92, 194, 211, 172, 98, 145, 149, 228, 121, 231, 200, 55, 109,
141, 213, 78, 169, 108, 86, 244, 234, 101, 122, 174, 8, 186, 120, 37,
46, 28, 166, 180, 198, 232, 221, 116, 31, 75, 189, 139, 138, 112, 62,
181, 102, 72, 3, 246, 14, 97, 53, 87, 185, 134, 193, 29, 158, 225,
248, 152, 17, 105, 217, 142, 148, 155, 30, 135, 233, 206, 85, 40, 223,
140, 161, 137, 13, 191, 230, 66, 104, 65, 153, 45, 15, 176, 84, 187,
22
]);
var T1 = new Uint32Array([
0xa56363c6, 0x847c7cf8, 0x997777ee, 0x8d7b7bf6,
0x0df2f2ff, 0xbd6b6bd6, 0xb16f6fde, 0x54c5c591,
0x50303060, 0x03010102, 0xa96767ce, 0x7d2b2b56,
0x19fefee7, 0x62d7d7b5, 0xe6abab4d, 0x9a7676ec,
0x45caca8f, 0x9d82821f, 0x40c9c989, 0x877d7dfa,
0x15fafaef, 0xeb5959b2, 0xc947478e, 0x0bf0f0fb,
0xecadad41, 0x67d4d4b3, 0xfda2a25f, 0xeaafaf45,
0xbf9c9c23, 0xf7a4a453, 0x967272e4, 0x5bc0c09b,
0xc2b7b775, 0x1cfdfde1, 0xae93933d, 0x6a26264c,
0x5a36366c, 0x413f3f7e, 0x02f7f7f5, 0x4fcccc83,
0x5c343468, 0xf4a5a551, 0x34e5e5d1, 0x08f1f1f9,
0x937171e2, 0x73d8d8ab, 0x53313162, 0x3f15152a,
0x0c040408, 0x52c7c795, 0x65232346, 0x5ec3c39d,
0x28181830, 0xa1969637, 0x0f05050a, 0xb59a9a2f,
0x0907070e, 0x36121224, 0x9b80801b, 0x3de2e2df,
0x26ebebcd, 0x6927274e, 0xcdb2b27f, 0x9f7575ea,
0x1b090912, 0x9e83831d, 0x742c2c58, 0x2e1a1a34,
0x2d1b1b36, 0xb26e6edc, 0xee5a5ab4, 0xfba0a05b,
0xf65252a4, 0x4d3b3b76, 0x61d6d6b7, 0xceb3b37d,
0x7b292952, 0x3ee3e3dd, 0x712f2f5e, 0x97848413,
0xf55353a6, 0x68d1d1b9, 0x00000000, 0x2cededc1,
0x60202040, 0x1ffcfce3, 0xc8b1b179, 0xed5b5bb6,
0xbe6a6ad4, 0x46cbcb8d, 0xd9bebe67, 0x4b393972,
0xde4a4a94, 0xd44c4c98, 0xe85858b0, 0x4acfcf85,
0x6bd0d0bb, 0x2aefefc5, 0xe5aaaa4f, 0x16fbfbed,
0xc5434386, 0xd74d4d9a, 0x55333366, 0x94858511,
0xcf45458a, 0x10f9f9e9, 0x06020204, 0x817f7ffe,
0xf05050a0, 0x443c3c78, 0xba9f9f25, 0xe3a8a84b,
0xf35151a2, 0xfea3a35d, 0xc0404080, 0x8a8f8f05,
0xad92923f, 0xbc9d9d21, 0x48383870, 0x04f5f5f1,
0xdfbcbc63, 0xc1b6b677, 0x75dadaaf, 0x63212142,
0x30101020, 0x1affffe5, 0x0ef3f3fd, 0x6dd2d2bf,
0x4ccdcd81, 0x140c0c18, 0x35131326, 0x2fececc3,
0xe15f5fbe, 0xa2979735, 0xcc444488, 0x3917172e,
0x57c4c493, 0xf2a7a755, 0x827e7efc, 0x473d3d7a,
0xac6464c8, 0xe75d5dba, 0x2b191932, 0x957373e6,
0xa06060c0, 0x98818119, 0xd14f4f9e, 0x7fdcdca3,
0x66222244, 0x7e2a2a54, 0xab90903b, 0x8388880b,
0xca46468c, 0x29eeeec7, 0xd3b8b86b, 0x3c141428,
0x79dedea7, 0xe25e5ebc, 0x1d0b0b16, 0x76dbdbad,
0x3be0e0db, 0x56323264, 0x4e3a3a74, 0x1e0a0a14,
0xdb494992, 0x0a06060c, 0x6c242448, 0xe45c5cb8,
0x5dc2c29f, 0x6ed3d3bd, 0xefacac43, 0xa66262c4,
0xa8919139, 0xa4959531, 0x37e4e4d3, 0x8b7979f2,
0x32e7e7d5, 0x43c8c88b, 0x5937376e, 0xb76d6dda,
0x8c8d8d01, 0x64d5d5b1, 0xd24e4e9c, 0xe0a9a949,
0xb46c6cd8, 0xfa5656ac, 0x07f4f4f3, 0x25eaeacf,
0xaf6565ca, 0x8e7a7af4, 0xe9aeae47, 0x18080810,
0xd5baba6f, 0x887878f0, 0x6f25254a, 0x722e2e5c,
0x241c1c38, 0xf1a6a657, 0xc7b4b473, 0x51c6c697,
0x23e8e8cb, 0x7cdddda1, 0x9c7474e8, 0x211f1f3e,
0xdd4b4b96, 0xdcbdbd61, 0x868b8b0d, 0x858a8a0f,
0x907070e0, 0x423e3e7c, 0xc4b5b571, 0xaa6666cc,
0xd8484890, 0x05030306, 0x01f6f6f7, 0x120e0e1c,
0xa36161c2, 0x5f35356a, 0xf95757ae, 0xd0b9b969,
0x91868617, 0x58c1c199, 0x271d1d3a, 0xb99e9e27,
0x38e1e1d9, 0x13f8f8eb, 0xb398982b, 0x33111122,
0xbb6969d2, 0x70d9d9a9, 0x898e8e07, 0xa7949433,
0xb69b9b2d, 0x221e1e3c, 0x92878715, 0x20e9e9c9,
0x49cece87, 0xff5555aa, 0x78282850, 0x7adfdfa5,
0x8f8c8c03, 0xf8a1a159, 0x80898909, 0x170d0d1a,
0xdabfbf65, 0x31e6e6d7, 0xc6424284, 0xb86868d0,
0xc3414182, 0xb0999929, 0x772d2d5a, 0x110f0f1e,
0xcbb0b07b, 0xfc5454a8, 0xd6bbbb6d, 0x3a16162c
]);
var T2 = new Uint32Array([
0x6363c6a5, 0x7c7cf884, 0x7777ee99, 0x7b7bf68d,
0xf2f2ff0d, 0x6b6bd6bd, 0x6f6fdeb1, 0xc5c59154,
0x30306050, 0x01010203, 0x6767cea9, 0x2b2b567d,
0xfefee719, 0xd7d7b562, 0xabab4de6, 0x7676ec9a,
0xcaca8f45, 0x82821f9d, 0xc9c98940, 0x7d7dfa87,
0xfafaef15, 0x5959b2eb, 0x47478ec9, 0xf0f0fb0b,
0xadad41ec, 0xd4d4b367, 0xa2a25ffd, 0xafaf45ea,
0x9c9c23bf, 0xa4a453f7, 0x7272e496, 0xc0c09b5b,
0xb7b775c2, 0xfdfde11c, 0x93933dae, 0x26264c6a,
0x36366c5a, 0x3f3f7e41, 0xf7f7f502, 0xcccc834f,
0x3434685c, 0xa5a551f4, 0xe5e5d134, 0xf1f1f908,
0x7171e293, 0xd8d8ab73, 0x31316253, 0x15152a3f,
0x0404080c, 0xc7c79552, 0x23234665, 0xc3c39d5e,
0x18183028, 0x969637a1, 0x05050a0f, 0x9a9a2fb5,
0x07070e09, 0x12122436, 0x80801b9b, 0xe2e2df3d,
0xebebcd26, 0x27274e69, 0xb2b27fcd, 0x7575ea9f,
0x0909121b, 0x83831d9e, 0x2c2c5874, 0x1a1a342e,
0x1b1b362d, 0x6e6edcb2, 0x5a5ab4ee, 0xa0a05bfb,
0x5252a4f6, 0x3b3b764d, 0xd6d6b761, 0xb3b37dce,
0x2929527b, 0xe3e3dd3e, 0x2f2f5e71, 0x84841397,
0x5353a6f5, 0xd1d1b968, 0x00000000, 0xededc12c,
0x20204060, 0xfcfce31f, 0xb1b179c8, 0x5b5bb6ed,
0x6a6ad4be, 0xcbcb8d46, 0xbebe67d9, 0x3939724b,
0x4a4a94de, 0x4c4c98d4, 0x5858b0e8, 0xcfcf854a,
0xd0d0bb6b, 0xefefc52a, 0xaaaa4fe5, 0xfbfbed16,
0x434386c5, 0x4d4d9ad7, 0x33336655, 0x85851194,
0x45458acf, 0xf9f9e910, 0x02020406, 0x7f7ffe81,
0x5050a0f0, 0x3c3c7844, 0x9f9f25ba, 0xa8a84be3,
0x5151a2f3, 0xa3a35dfe, 0x404080c0, 0x8f8f058a,
0x92923fad, 0x9d9d21bc, 0x38387048, 0xf5f5f104,
0xbcbc63df, 0xb6b677c1, 0xdadaaf75, 0x21214263,
0x10102030, 0xffffe51a, 0xf3f3fd0e, 0xd2d2bf6d,
0xcdcd814c, 0x0c0c1814, 0x13132635, 0xececc32f,
0x5f5fbee1, 0x979735a2, 0x444488cc, 0x17172e39,
0xc4c49357, 0xa7a755f2, 0x7e7efc82, 0x3d3d7a47,
0x6464c8ac, 0x5d5dbae7, 0x1919322b, 0x7373e695,
0x6060c0a0, 0x81811998, 0x4f4f9ed1, 0xdcdca37f,
0x22224466, 0x2a2a547e, 0x90903bab, 0x88880b83,
0x46468cca, 0xeeeec729, 0xb8b86bd3, 0x1414283c,
0xdedea779, 0x5e5ebce2, 0x0b0b161d, 0xdbdbad76,
0xe0e0db3b, 0x32326456, 0x3a3a744e, 0x0a0a141e,
0x494992db, 0x06060c0a, 0x2424486c, 0x5c5cb8e4,
0xc2c29f5d, 0xd3d3bd6e, 0xacac43ef, 0x6262c4a6,
0x919139a8, 0x959531a4, 0xe4e4d337, 0x7979f28b,
0xe7e7d532, 0xc8c88b43, 0x37376e59, 0x6d6ddab7,
0x8d8d018c, 0xd5d5b164, 0x4e4e9cd2, 0xa9a949e0,
0x6c6cd8b4, 0x5656acfa, 0xf4f4f307, 0xeaeacf25,
0x6565caaf, 0x7a7af48e, 0xaeae47e9, 0x08081018,
0xbaba6fd5, 0x7878f088, 0x25254a6f, 0x2e2e5c72,
0x1c1c3824, 0xa6a657f1, 0xb4b473c7, 0xc6c69751,
0xe8e8cb23, 0xdddda17c, 0x7474e89c, 0x1f1f3e21,
0x4b4b96dd, 0xbdbd61dc, 0x8b8b0d86, 0x8a8a0f85,
0x7070e090, 0x3e3e7c42, 0xb5b571c4, 0x6666ccaa,
0x484890d8, 0x03030605, 0xf6f6f701, 0x0e0e1c12,
0x6161c2a3, 0x35356a5f, 0x5757aef9, 0xb9b969d0,
0x86861791, 0xc1c19958, 0x1d1d3a27, 0x9e9e27b9,
0xe1e1d938, 0xf8f8eb13, 0x98982bb3, 0x11112233,
0x6969d2bb, 0xd9d9a970, 0x8e8e0789, 0x949433a7,
0x9b9b2db6, 0x1e1e3c22, 0x87871592, 0xe9e9c920,
0xcece8749, 0x5555aaff, 0x28285078, 0xdfdfa57a,
0x8c8c038f, 0xa1a159f8, 0x89890980, 0x0d0d1a17,
0xbfbf65da, 0xe6e6d731, 0x424284c6, 0x6868d0b8,
0x414182c3, 0x999929b0, 0x2d2d5a77, 0x0f0f1e11,
0xb0b07bcb, 0x5454a8fc, 0xbbbb6dd6, 0x16162c3a
]);
var T3 = new Uint32Array([
0x63c6a563, 0x7cf8847c, 0x77ee9977, 0x7bf68d7b,
0xf2ff0df2, 0x6bd6bd6b, 0x6fdeb16f, 0xc59154c5,
0x30605030, 0x01020301, 0x67cea967, 0x2b567d2b,
0xfee719fe, 0xd7b562d7, 0xab4de6ab, 0x76ec9a76,
0xca8f45ca, 0x821f9d82, 0xc98940c9, 0x7dfa877d,
0xfaef15fa, 0x59b2eb59, 0x478ec947, 0xf0fb0bf0,
0xad41ecad, 0xd4b367d4, 0xa25ffda2, 0xaf45eaaf,
0x9c23bf9c, 0xa453f7a4, 0x72e49672, 0xc09b5bc0,
0xb775c2b7, 0xfde11cfd, 0x933dae93, 0x264c6a26,
0x366c5a36, 0x3f7e413f, 0xf7f502f7, 0xcc834fcc,
0x34685c34, 0xa551f4a5, 0xe5d134e5, 0xf1f908f1,
0x71e29371, 0xd8ab73d8, 0x31625331, 0x152a3f15,
0x04080c04, 0xc79552c7, 0x23466523, 0xc39d5ec3,
0x18302818, 0x9637a196, 0x050a0f05, 0x9a2fb59a,
0x070e0907, 0x12243612, 0x801b9b80, 0xe2df3de2,
0xebcd26eb, 0x274e6927, 0xb27fcdb2, 0x75ea9f75,
0x09121b09, 0x831d9e83, 0x2c58742c, 0x1a342e1a,
0x1b362d1b, 0x6edcb26e, 0x5ab4ee5a, 0xa05bfba0,
0x52a4f652, 0x3b764d3b, 0xd6b761d6, 0xb37dceb3,
0x29527b29, 0xe3dd3ee3, 0x2f5e712f, 0x84139784,
0x53a6f553, 0xd1b968d1, 0x00000000, 0xedc12ced,
0x20406020, 0xfce31ffc, 0xb179c8b1, 0x5bb6ed5b,
0x6ad4be6a, 0xcb8d46cb, 0xbe67d9be, 0x39724b39,
0x4a94de4a, 0x4c98d44c, 0x58b0e858, 0xcf854acf,
0xd0bb6bd0, 0xefc52aef, 0xaa4fe5aa, 0xfbed16fb,
0x4386c543, 0x4d9ad74d, 0x33665533, 0x85119485,
0x458acf45, 0xf9e910f9, 0x02040602, 0x7ffe817f,
0x50a0f050, 0x3c78443c, 0x9f25ba9f, 0xa84be3a8,
0x51a2f351, 0xa35dfea3, 0x4080c040, 0x8f058a8f,
0x923fad92, 0x9d21bc9d, 0x38704838, 0xf5f104f5,
0xbc63dfbc, 0xb677c1b6, 0xdaaf75da, 0x21426321,
0x10203010, 0xffe51aff, 0xf3fd0ef3, 0xd2bf6dd2,
0xcd814ccd, 0x0c18140c, 0x13263513, 0xecc32fec,
0x5fbee15f, 0x9735a297, 0x4488cc44, 0x172e3917,
0xc49357c4, 0xa755f2a7, 0x7efc827e, 0x3d7a473d,
0x64c8ac64, 0x5dbae75d, 0x19322b19, 0x73e69573,
0x60c0a060, 0x81199881, 0x4f9ed14f, 0xdca37fdc,
0x22446622, 0x2a547e2a, 0x903bab90, 0x880b8388,
0x468cca46, 0xeec729ee, 0xb86bd3b8, 0x14283c14,
0xdea779de, 0x5ebce25e, 0x0b161d0b, 0xdbad76db,
0xe0db3be0, 0x32645632, 0x3a744e3a, 0x0a141e0a,
0x4992db49, 0x060c0a06, 0x24486c24, 0x5cb8e45c,
0xc29f5dc2, 0xd3bd6ed3, 0xac43efac, 0x62c4a662,
0x9139a891, 0x9531a495, 0xe4d337e4, 0x79f28b79,
0xe7d532e7, 0xc88b43c8, 0x376e5937, 0x6ddab76d,
0x8d018c8d, 0xd5b164d5, 0x4e9cd24e, 0xa949e0a9,
0x6cd8b46c, 0x56acfa56, 0xf4f307f4, 0xeacf25ea,
0x65caaf65, 0x7af48e7a, 0xae47e9ae, 0x08101808,
0xba6fd5ba, 0x78f08878, 0x254a6f25, 0x2e5c722e,
0x1c38241c, 0xa657f1a6, 0xb473c7b4, 0xc69751c6,
0xe8cb23e8, 0xdda17cdd, 0x74e89c74, 0x1f3e211f,
0x4b96dd4b, 0xbd61dcbd, 0x8b0d868b, 0x8a0f858a,
0x70e09070, 0x3e7c423e, 0xb571c4b5, 0x66ccaa66,
0x4890d848, 0x03060503, 0xf6f701f6, 0x0e1c120e,
0x61c2a361, 0x356a5f35, 0x57aef957, 0xb969d0b9,
0x86179186, 0xc19958c1, 0x1d3a271d, 0x9e27b99e,
0xe1d938e1, 0xf8eb13f8, 0x982bb398, 0x11223311,
0x69d2bb69, 0xd9a970d9, 0x8e07898e, 0x9433a794,
0x9b2db69b, 0x1e3c221e, 0x87159287, 0xe9c920e9,
0xce8749ce, 0x55aaff55, 0x28507828, 0xdfa57adf,
0x8c038f8c, 0xa159f8a1, 0x89098089, 0x0d1a170d,
0xbf65dabf, 0xe6d731e6, 0x4284c642, 0x68d0b868,
0x4182c341, 0x9929b099, 0x2d5a772d, 0x0f1e110f,
0xb07bcbb0, 0x54a8fc54, 0xbb6dd6bb, 0x162c3a16
]);
var T4 = new Uint32Array([
0xc6a56363, 0xf8847c7c, 0xee997777, 0xf68d7b7b,
0xff0df2f2, 0xd6bd6b6b, 0xdeb16f6f, 0x9154c5c5,
0x60503030, 0x02030101, 0xcea96767, 0x567d2b2b,
0xe719fefe, 0xb562d7d7, 0x4de6abab, 0xec9a7676,
0x8f45caca, 0x1f9d8282, 0x8940c9c9, 0xfa877d7d,
0xef15fafa, 0xb2eb5959, 0x8ec94747, 0xfb0bf0f0,
0x41ecadad, 0xb367d4d4, 0x5ffda2a2, 0x45eaafaf,
0x23bf9c9c, 0x53f7a4a4, 0xe4967272, 0x9b5bc0c0,
0x75c2b7b7, 0xe11cfdfd, 0x3dae9393, 0x4c6a2626,
0x6c5a3636, 0x7e413f3f, 0xf502f7f7, 0x834fcccc,
0x685c3434, 0x51f4a5a5, 0xd134e5e5, 0xf908f1f1,
0xe2937171, 0xab73d8d8, 0x62533131, 0x2a3f1515,
0x080c0404, 0x9552c7c7, 0x46652323, 0x9d5ec3c3,
0x30281818, 0x37a19696, 0x0a0f0505, 0x2fb59a9a,
0x0e090707, 0x24361212, 0x1b9b8080, 0xdf3de2e2,
0xcd26ebeb, 0x4e692727, 0x7fcdb2b2, 0xea9f7575,
0x121b0909, 0x1d9e8383, 0x58742c2c, 0x342e1a1a,
0x362d1b1b, 0xdcb26e6e, 0xb4ee5a5a, 0x5bfba0a0,
0xa4f65252, 0x764d3b3b, 0xb761d6d6, 0x7dceb3b3,
0x527b2929, 0xdd3ee3e3, 0x5e712f2f, 0x13978484,
0xa6f55353, 0xb968d1d1, 0x00000000, 0xc12ceded,
0x40602020, 0xe31ffcfc, 0x79c8b1b1, 0xb6ed5b5b,
0xd4be6a6a, 0x8d46cbcb, 0x67d9bebe, 0x724b3939,
0x94de4a4a, 0x98d44c4c, 0xb0e85858, 0x854acfcf,
0xbb6bd0d0, 0xc52aefef, 0x4fe5aaaa, 0xed16fbfb,
0x86c54343, 0x9ad74d4d, 0x66553333, 0x11948585,
0x8acf4545, 0xe910f9f9, 0x04060202, 0xfe817f7f,
0xa0f05050, 0x78443c3c, 0x25ba9f9f, 0x4be3a8a8,
0xa2f35151, 0x5dfea3a3, 0x80c04040, 0x058a8f8f,
0x3fad9292, 0x21bc9d9d, 0x70483838, 0xf104f5f5,
0x63dfbcbc, 0x77c1b6b6, 0xaf75dada, 0x42632121,
0x20301010, 0xe51affff, 0xfd0ef3f3, 0xbf6dd2d2,
0x814ccdcd, 0x18140c0c, 0x26351313, 0xc32fecec,
0xbee15f5f, 0x35a29797, 0x88cc4444, 0x2e391717,
0x9357c4c4, 0x55f2a7a7, 0xfc827e7e, 0x7a473d3d,
0xc8ac6464, 0xbae75d5d, 0x322b1919, 0xe6957373,
0xc0a06060, 0x19988181, 0x9ed14f4f, 0xa37fdcdc,
0x44662222, 0x547e2a2a, 0x3bab9090, 0x0b838888,
0x8cca4646, 0xc729eeee, 0x6bd3b8b8, 0x283c1414,
0xa779dede, 0xbce25e5e, 0x161d0b0b, 0xad76dbdb,
0xdb3be0e0, 0x64563232, 0x744e3a3a, 0x141e0a0a,
0x92db4949, 0x0c0a0606, 0x486c2424, 0xb8e45c5c,
0x9f5dc2c2, 0xbd6ed3d3, 0x43efacac, 0xc4a66262,
0x39a89191, 0x31a49595, 0xd337e4e4, 0xf28b7979,
0xd532e7e7, 0x8b43c8c8, 0x6e593737, 0xdab76d6d,
0x018c8d8d, 0xb164d5d5, 0x9cd24e4e, 0x49e0a9a9,
0xd8b46c6c, 0xacfa5656, 0xf307f4f4, 0xcf25eaea,
0xcaaf6565, 0xf48e7a7a, 0x47e9aeae, 0x10180808,
0x6fd5baba, 0xf0887878, 0x4a6f2525, 0x5c722e2e,
0x38241c1c, 0x57f1a6a6, 0x73c7b4b4, 0x9751c6c6,
0xcb23e8e8, 0xa17cdddd, 0xe89c7474, 0x3e211f1f,
0x96dd4b4b, 0x61dcbdbd, 0x0d868b8b, 0x0f858a8a,
0xe0907070, 0x7c423e3e, 0x71c4b5b5, 0xccaa6666,
0x90d84848, 0x06050303, 0xf701f6f6, 0x1c120e0e,
0xc2a36161, 0x6a5f3535, 0xaef95757, 0x69d0b9b9,
0x17918686, 0x9958c1c1, 0x3a271d1d, 0x27b99e9e,
0xd938e1e1, 0xeb13f8f8, 0x2bb39898, 0x22331111,
0xd2bb6969, 0xa970d9d9, 0x07898e8e, 0x33a79494,
0x2db69b9b, 0x3c221e1e, 0x15928787, 0xc920e9e9,
0x8749cece, 0xaaff5555, 0x50782828, 0xa57adfdf,
0x038f8c8c, 0x59f8a1a1, 0x09808989, 0x1a170d0d,
0x65dabfbf, 0xd731e6e6, 0x84c64242, 0xd0b86868,
0x82c34141, 0x29b09999, 0x5a772d2d, 0x1e110f0f,
0x7bcbb0b0, 0xa8fc5454, 0x6dd6bbbb, 0x2c3a1616
]);
function B0(x) {
return (x & 255);
}
function B1(x) {
return ((x >> 8) & 255);
}
function B2(x) {
return ((x >> 16) & 255);
}
function B3(x) {
return ((x >> 24) & 255);
}
function F1(x0, x1, x2, x3) {
return B1(T1[x0 & 255]) | (B1(T1[(x1 >> 8) & 255]) << 8) | (B1(T1[(x2 >> 16) & 255]) << 16) | (B1(T1[x3 >>> 24]) << 24);
}
function packBytes(octets) {
var i, j;
var len = octets.length;
var b = new Array(len / 4);
if (!octets || len % 4) {
return;
}
for (i = 0, j = 0; j < len; j += 4) {
b[i++] = octets[j] | (octets[j + 1] << 8) | (octets[j + 2] << 16) | (octets[j + 3] << 24);
}
return b;
}
function unpackBytes(packed) {
var j;
var i = 0,
l = packed.length;
var r = new Array(l * 4);
for (j = 0; j < l; j++) {
r[i++] = B0(packed[j]);
r[i++] = B1(packed[j]);
r[i++] = B2(packed[j]);
r[i++] = B3(packed[j]);
}
return r;
}
// ------------------------------------------------
var maxkc = 8;
var maxrk = 14;
function keyExpansion(key) {
var kc, i, j, r, t;
var rounds;
var keySched = new Array(maxrk + 1);
var keylen = key.length;
var k = new Array(maxkc);
var tk = new Array(maxkc);
var rconpointer = 0;
if (keylen === 16) {
rounds = 10;
kc = 4;
} else if (keylen === 24) {
rounds = 12;
kc = 6;
} else if (keylen === 32) {
rounds = 14;
kc = 8;
} else {
throw new Error('Invalid key-length for AES key:' + keylen);
}
for (i = 0; i < maxrk + 1; i++) {
keySched[i] = new Uint32Array(4);
}
for (i = 0, j = 0; j < keylen; j++, i += 4) {
k[j] = key[i] | (key[i + 1] << 8) | (key[i + 2] << 16) | (key[i + 3] << 24);
}
for (j = kc - 1; j >= 0; j--) {
tk[j] = k[j];
}
r = 0;
t = 0;
for (j = 0; (j < kc) && (r < rounds + 1);) {
for (; (j < kc) && (t < 4); j++, t++) {
keySched[r][t] = tk[j];
}
if (t === 4) {
r++;
t = 0;
}
}
while (r < rounds + 1) {
var temp = tk[kc - 1];
tk[0] ^= S[B1(temp)] | (S[B2(temp)] << 8) | (S[B3(temp)] << 16) | (S[B0(temp)] << 24);
tk[0] ^= Rcon[rconpointer++];
if (kc !== 8) {
for (j = 1; j < kc; j++) {
tk[j] ^= tk[j - 1];
}
} else {
for (j = 1; j < kc / 2; j++) {
tk[j] ^= tk[j - 1];
}
temp = tk[kc / 2 - 1];
tk[kc / 2] ^= S[B0(temp)] | (S[B1(temp)] << 8) | (S[B2(temp)] << 16) | (S[B3(temp)] << 24);
for (j = kc / 2 + 1; j < kc; j++) {
tk[j] ^= tk[j - 1];
}
}
for (j = 0; (j < kc) && (r < rounds + 1);) {
for (; (j < kc) && (t < 4); j++, t++) {
keySched[r][t] = tk[j];
}
if (t === 4) {
r++;
t = 0;
}
}
}
return {
rounds: rounds,
rk: keySched
};
}
function AESencrypt(block, ctx, t) {
var r, rounds, b;
b = packBytes(block);
rounds = ctx.rounds;
for (r = 0; r < rounds - 1; r++) {
t[0] = b[0] ^ ctx.rk[r][0];
t[1] = b[1] ^ ctx.rk[r][1];
t[2] = b[2] ^ ctx.rk[r][2];
t[3] = b[3] ^ ctx.rk[r][3];
b[0] = T1[t[0] & 255] ^ T2[(t[1] >> 8) & 255] ^ T3[(t[2] >> 16) & 255] ^ T4[t[3] >>> 24];
b[1] = T1[t[1] & 255] ^ T2[(t[2] >> 8) & 255] ^ T3[(t[3] >> 16) & 255] ^ T4[t[0] >>> 24];
b[2] = T1[t[2] & 255] ^ T2[(t[3] >> 8) & 255] ^ T3[(t[0] >> 16) & 255] ^ T4[t[1] >>> 24];
b[3] = T1[t[3] & 255] ^ T2[(t[0] >> 8) & 255] ^ T3[(t[1] >> 16) & 255] ^ T4[t[2] >>> 24];
}
// last round is special
r = rounds - 1;
t[0] = b[0] ^ ctx.rk[r][0];
t[1] = b[1] ^ ctx.rk[r][1];
t[2] = b[2] ^ ctx.rk[r][2];
t[3] = b[3] ^ ctx.rk[r][3];
b[0] = F1(t[0], t[1], t[2], t[3]) ^ ctx.rk[rounds][0];
b[1] = F1(t[1], t[2], t[3], t[0]) ^ ctx.rk[rounds][1];
b[2] = F1(t[2], t[3], t[0], t[1]) ^ ctx.rk[rounds][2];
b[3] = F1(t[3], t[0], t[1], t[2]) ^ ctx.rk[rounds][3];
return unpackBytes(b);
}
function makeClass(length) {
var c = function(key) {
this.key = keyExpansion(key);
this._temp = new Uint32Array(this.blockSize / 4);
this.encrypt = function(block) {
return AESencrypt(block, this.key, this._temp);
};
};
c.blockSize = c.prototype.blockSize = 16;
c.keySize = c.prototype.keySize = length / 8;
return c;
}
export default {
128: makeClass(128),
192: makeClass(192),
256: makeClass(256)
};

View file

@ -1,407 +0,0 @@
/* Modified by Recurity Labs GmbH
*
* Originally written by nklein software (nklein.com)
*/
/**
* @module crypto/cipher/blowfish
*/
'use strict';
/*
* Javascript implementation based on Bruce Schneier's reference implementation.
*
*
* The constructor doesn't do much of anything. It's just here
* so we can start defining properties and methods and such.
*/
function Blowfish() {}
/*
* Declare the block size so that protocols know what size
* Initialization Vector (IV) they will need.
*/
Blowfish.prototype.BLOCKSIZE = 8;
/*
* These are the default SBOXES.
*/
Blowfish.prototype.SBOXES = [
[
0xd1310ba6, 0x98dfb5ac, 0x2ffd72db, 0xd01adfb7, 0xb8e1afed, 0x6a267e96,
0xba7c9045, 0xf12c7f99, 0x24a19947, 0xb3916cf7, 0x0801f2e2, 0x858efc16,
0x636920d8, 0x71574e69, 0xa458fea3, 0xf4933d7e, 0x0d95748f, 0x728eb658,
0x718bcd58, 0x82154aee, 0x7b54a41d, 0xc25a59b5, 0x9c30d539, 0x2af26013,
0xc5d1b023, 0x286085f0, 0xca417918, 0xb8db38ef, 0x8e79dcb0, 0x603a180e,
0x6c9e0e8b, 0xb01e8a3e, 0xd71577c1, 0xbd314b27, 0x78af2fda, 0x55605c60,
0xe65525f3, 0xaa55ab94, 0x57489862, 0x63e81440, 0x55ca396a, 0x2aab10b6,
0xb4cc5c34, 0x1141e8ce, 0xa15486af, 0x7c72e993, 0xb3ee1411, 0x636fbc2a,
0x2ba9c55d, 0x741831f6, 0xce5c3e16, 0x9b87931e, 0xafd6ba33, 0x6c24cf5c,
0x7a325381, 0x28958677, 0x3b8f4898, 0x6b4bb9af, 0xc4bfe81b, 0x66282193,
0x61d809cc, 0xfb21a991, 0x487cac60, 0x5dec8032, 0xef845d5d, 0xe98575b1,
0xdc262302, 0xeb651b88, 0x23893e81, 0xd396acc5, 0x0f6d6ff3, 0x83f44239,
0x2e0b4482, 0xa4842004, 0x69c8f04a, 0x9e1f9b5e, 0x21c66842, 0xf6e96c9a,
0x670c9c61, 0xabd388f0, 0x6a51a0d2, 0xd8542f68, 0x960fa728, 0xab5133a3,
0x6eef0b6c, 0x137a3be4, 0xba3bf050, 0x7efb2a98, 0xa1f1651d, 0x39af0176,
0x66ca593e, 0x82430e88, 0x8cee8619, 0x456f9fb4, 0x7d84a5c3, 0x3b8b5ebe,
0xe06f75d8, 0x85c12073, 0x401a449f, 0x56c16aa6, 0x4ed3aa62, 0x363f7706,
0x1bfedf72, 0x429b023d, 0x37d0d724, 0xd00a1248, 0xdb0fead3, 0x49f1c09b,
0x075372c9, 0x80991b7b, 0x25d479d8, 0xf6e8def7, 0xe3fe501a, 0xb6794c3b,
0x976ce0bd, 0x04c006ba, 0xc1a94fb6, 0x409f60c4, 0x5e5c9ec2, 0x196a2463,
0x68fb6faf, 0x3e6c53b5, 0x1339b2eb, 0x3b52ec6f, 0x6dfc511f, 0x9b30952c,
0xcc814544, 0xaf5ebd09, 0xbee3d004, 0xde334afd, 0x660f2807, 0x192e4bb3,
0xc0cba857, 0x45c8740f, 0xd20b5f39, 0xb9d3fbdb, 0x5579c0bd, 0x1a60320a,
0xd6a100c6, 0x402c7279, 0x679f25fe, 0xfb1fa3cc, 0x8ea5e9f8, 0xdb3222f8,
0x3c7516df, 0xfd616b15, 0x2f501ec8, 0xad0552ab, 0x323db5fa, 0xfd238760,
0x53317b48, 0x3e00df82, 0x9e5c57bb, 0xca6f8ca0, 0x1a87562e, 0xdf1769db,
0xd542a8f6, 0x287effc3, 0xac6732c6, 0x8c4f5573, 0x695b27b0, 0xbbca58c8,
0xe1ffa35d, 0xb8f011a0, 0x10fa3d98, 0xfd2183b8, 0x4afcb56c, 0x2dd1d35b,
0x9a53e479, 0xb6f84565, 0xd28e49bc, 0x4bfb9790, 0xe1ddf2da, 0xa4cb7e33,
0x62fb1341, 0xcee4c6e8, 0xef20cada, 0x36774c01, 0xd07e9efe, 0x2bf11fb4,
0x95dbda4d, 0xae909198, 0xeaad8e71, 0x6b93d5a0, 0xd08ed1d0, 0xafc725e0,
0x8e3c5b2f, 0x8e7594b7, 0x8ff6e2fb, 0xf2122b64, 0x8888b812, 0x900df01c,
0x4fad5ea0, 0x688fc31c, 0xd1cff191, 0xb3a8c1ad, 0x2f2f2218, 0xbe0e1777,
0xea752dfe, 0x8b021fa1, 0xe5a0cc0f, 0xb56f74e8, 0x18acf3d6, 0xce89e299,
0xb4a84fe0, 0xfd13e0b7, 0x7cc43b81, 0xd2ada8d9, 0x165fa266, 0x80957705,
0x93cc7314, 0x211a1477, 0xe6ad2065, 0x77b5fa86, 0xc75442f5, 0xfb9d35cf,
0xebcdaf0c, 0x7b3e89a0, 0xd6411bd3, 0xae1e7e49, 0x00250e2d, 0x2071b35e,
0x226800bb, 0x57b8e0af, 0x2464369b, 0xf009b91e, 0x5563911d, 0x59dfa6aa,
0x78c14389, 0xd95a537f, 0x207d5ba2, 0x02e5b9c5, 0x83260376, 0x6295cfa9,
0x11c81968, 0x4e734a41, 0xb3472dca, 0x7b14a94a, 0x1b510052, 0x9a532915,
0xd60f573f, 0xbc9bc6e4, 0x2b60a476, 0x81e67400, 0x08ba6fb5, 0x571be91f,
0xf296ec6b, 0x2a0dd915, 0xb6636521, 0xe7b9f9b6, 0xff34052e, 0xc5855664,
0x53b02d5d, 0xa99f8fa1, 0x08ba4799, 0x6e85076a
],
[
0x4b7a70e9, 0xb5b32944, 0xdb75092e, 0xc4192623, 0xad6ea6b0, 0x49a7df7d,
0x9cee60b8, 0x8fedb266, 0xecaa8c71, 0x699a17ff, 0x5664526c, 0xc2b19ee1,
0x193602a5, 0x75094c29, 0xa0591340, 0xe4183a3e, 0x3f54989a, 0x5b429d65,
0x6b8fe4d6, 0x99f73fd6, 0xa1d29c07, 0xefe830f5, 0x4d2d38e6, 0xf0255dc1,
0x4cdd2086, 0x8470eb26, 0x6382e9c6, 0x021ecc5e, 0x09686b3f, 0x3ebaefc9,
0x3c971814, 0x6b6a70a1, 0x687f3584, 0x52a0e286, 0xb79c5305, 0xaa500737,
0x3e07841c, 0x7fdeae5c, 0x8e7d44ec, 0x5716f2b8, 0xb03ada37, 0xf0500c0d,
0xf01c1f04, 0x0200b3ff, 0xae0cf51a, 0x3cb574b2, 0x25837a58, 0xdc0921bd,
0xd19113f9, 0x7ca92ff6, 0x94324773, 0x22f54701, 0x3ae5e581, 0x37c2dadc,
0xc8b57634, 0x9af3dda7, 0xa9446146, 0x0fd0030e, 0xecc8c73e, 0xa4751e41,
0xe238cd99, 0x3bea0e2f, 0x3280bba1, 0x183eb331, 0x4e548b38, 0x4f6db908,
0x6f420d03, 0xf60a04bf, 0x2cb81290, 0x24977c79, 0x5679b072, 0xbcaf89af,
0xde9a771f, 0xd9930810, 0xb38bae12, 0xdccf3f2e, 0x5512721f, 0x2e6b7124,
0x501adde6, 0x9f84cd87, 0x7a584718, 0x7408da17, 0xbc9f9abc, 0xe94b7d8c,
0xec7aec3a, 0xdb851dfa, 0x63094366, 0xc464c3d2, 0xef1c1847, 0x3215d908,
0xdd433b37, 0x24c2ba16, 0x12a14d43, 0x2a65c451, 0x50940002, 0x133ae4dd,
0x71dff89e, 0x10314e55, 0x81ac77d6, 0x5f11199b, 0x043556f1, 0xd7a3c76b,
0x3c11183b, 0x5924a509, 0xf28fe6ed, 0x97f1fbfa, 0x9ebabf2c, 0x1e153c6e,
0x86e34570, 0xeae96fb1, 0x860e5e0a, 0x5a3e2ab3, 0x771fe71c, 0x4e3d06fa,
0x2965dcb9, 0x99e71d0f, 0x803e89d6, 0x5266c825, 0x2e4cc978, 0x9c10b36a,
0xc6150eba, 0x94e2ea78, 0xa5fc3c53, 0x1e0a2df4, 0xf2f74ea7, 0x361d2b3d,
0x1939260f, 0x19c27960, 0x5223a708, 0xf71312b6, 0xebadfe6e, 0xeac31f66,
0xe3bc4595, 0xa67bc883, 0xb17f37d1, 0x018cff28, 0xc332ddef, 0xbe6c5aa5,
0x65582185, 0x68ab9802, 0xeecea50f, 0xdb2f953b, 0x2aef7dad, 0x5b6e2f84,
0x1521b628, 0x29076170, 0xecdd4775, 0x619f1510, 0x13cca830, 0xeb61bd96,
0x0334fe1e, 0xaa0363cf, 0xb5735c90, 0x4c70a239, 0xd59e9e0b, 0xcbaade14,
0xeecc86bc, 0x60622ca7, 0x9cab5cab, 0xb2f3846e, 0x648b1eaf, 0x19bdf0ca,
0xa02369b9, 0x655abb50, 0x40685a32, 0x3c2ab4b3, 0x319ee9d5, 0xc021b8f7,
0x9b540b19, 0x875fa099, 0x95f7997e, 0x623d7da8, 0xf837889a, 0x97e32d77,
0x11ed935f, 0x16681281, 0x0e358829, 0xc7e61fd6, 0x96dedfa1, 0x7858ba99,
0x57f584a5, 0x1b227263, 0x9b83c3ff, 0x1ac24696, 0xcdb30aeb, 0x532e3054,
0x8fd948e4, 0x6dbc3128, 0x58ebf2ef, 0x34c6ffea, 0xfe28ed61, 0xee7c3c73,
0x5d4a14d9, 0xe864b7e3, 0x42105d14, 0x203e13e0, 0x45eee2b6, 0xa3aaabea,
0xdb6c4f15, 0xfacb4fd0, 0xc742f442, 0xef6abbb5, 0x654f3b1d, 0x41cd2105,
0xd81e799e, 0x86854dc7, 0xe44b476a, 0x3d816250, 0xcf62a1f2, 0x5b8d2646,
0xfc8883a0, 0xc1c7b6a3, 0x7f1524c3, 0x69cb7492, 0x47848a0b, 0x5692b285,
0x095bbf00, 0xad19489d, 0x1462b174, 0x23820e00, 0x58428d2a, 0x0c55f5ea,
0x1dadf43e, 0x233f7061, 0x3372f092, 0x8d937e41, 0xd65fecf1, 0x6c223bdb,
0x7cde3759, 0xcbee7460, 0x4085f2a7, 0xce77326e, 0xa6078084, 0x19f8509e,
0xe8efd855, 0x61d99735, 0xa969a7aa, 0xc50c06c2, 0x5a04abfc, 0x800bcadc,
0x9e447a2e, 0xc3453484, 0xfdd56705, 0x0e1e9ec9, 0xdb73dbd3, 0x105588cd,
0x675fda79, 0xe3674340, 0xc5c43465, 0x713e38d8, 0x3d28f89e, 0xf16dff20,
0x153e21e7, 0x8fb03d4a, 0xe6e39f2b, 0xdb83adf7
],
[
0xe93d5a68, 0x948140f7, 0xf64c261c, 0x94692934, 0x411520f7, 0x7602d4f7,
0xbcf46b2e, 0xd4a20068, 0xd4082471, 0x3320f46a, 0x43b7d4b7, 0x500061af,
0x1e39f62e, 0x97244546, 0x14214f74, 0xbf8b8840, 0x4d95fc1d, 0x96b591af,
0x70f4ddd3, 0x66a02f45, 0xbfbc09ec, 0x03bd9785, 0x7fac6dd0, 0x31cb8504,
0x96eb27b3, 0x55fd3941, 0xda2547e6, 0xabca0a9a, 0x28507825, 0x530429f4,
0x0a2c86da, 0xe9b66dfb, 0x68dc1462, 0xd7486900, 0x680ec0a4, 0x27a18dee,
0x4f3ffea2, 0xe887ad8c, 0xb58ce006, 0x7af4d6b6, 0xaace1e7c, 0xd3375fec,
0xce78a399, 0x406b2a42, 0x20fe9e35, 0xd9f385b9, 0xee39d7ab, 0x3b124e8b,
0x1dc9faf7, 0x4b6d1856, 0x26a36631, 0xeae397b2, 0x3a6efa74, 0xdd5b4332,
0x6841e7f7, 0xca7820fb, 0xfb0af54e, 0xd8feb397, 0x454056ac, 0xba489527,
0x55533a3a, 0x20838d87, 0xfe6ba9b7, 0xd096954b, 0x55a867bc, 0xa1159a58,
0xcca92963, 0x99e1db33, 0xa62a4a56, 0x3f3125f9, 0x5ef47e1c, 0x9029317c,
0xfdf8e802, 0x04272f70, 0x80bb155c, 0x05282ce3, 0x95c11548, 0xe4c66d22,
0x48c1133f, 0xc70f86dc, 0x07f9c9ee, 0x41041f0f, 0x404779a4, 0x5d886e17,
0x325f51eb, 0xd59bc0d1, 0xf2bcc18f, 0x41113564, 0x257b7834, 0x602a9c60,
0xdff8e8a3, 0x1f636c1b, 0x0e12b4c2, 0x02e1329e, 0xaf664fd1, 0xcad18115,
0x6b2395e0, 0x333e92e1, 0x3b240b62, 0xeebeb922, 0x85b2a20e, 0xe6ba0d99,
0xde720c8c, 0x2da2f728, 0xd0127845, 0x95b794fd, 0x647d0862, 0xe7ccf5f0,
0x5449a36f, 0x877d48fa, 0xc39dfd27, 0xf33e8d1e, 0x0a476341, 0x992eff74,
0x3a6f6eab, 0xf4f8fd37, 0xa812dc60, 0xa1ebddf8, 0x991be14c, 0xdb6e6b0d,
0xc67b5510, 0x6d672c37, 0x2765d43b, 0xdcd0e804, 0xf1290dc7, 0xcc00ffa3,
0xb5390f92, 0x690fed0b, 0x667b9ffb, 0xcedb7d9c, 0xa091cf0b, 0xd9155ea3,
0xbb132f88, 0x515bad24, 0x7b9479bf, 0x763bd6eb, 0x37392eb3, 0xcc115979,
0x8026e297, 0xf42e312d, 0x6842ada7, 0xc66a2b3b, 0x12754ccc, 0x782ef11c,
0x6a124237, 0xb79251e7, 0x06a1bbe6, 0x4bfb6350, 0x1a6b1018, 0x11caedfa,
0x3d25bdd8, 0xe2e1c3c9, 0x44421659, 0x0a121386, 0xd90cec6e, 0xd5abea2a,
0x64af674e, 0xda86a85f, 0xbebfe988, 0x64e4c3fe, 0x9dbc8057, 0xf0f7c086,
0x60787bf8, 0x6003604d, 0xd1fd8346, 0xf6381fb0, 0x7745ae04, 0xd736fccc,
0x83426b33, 0xf01eab71, 0xb0804187, 0x3c005e5f, 0x77a057be, 0xbde8ae24,
0x55464299, 0xbf582e61, 0x4e58f48f, 0xf2ddfda2, 0xf474ef38, 0x8789bdc2,
0x5366f9c3, 0xc8b38e74, 0xb475f255, 0x46fcd9b9, 0x7aeb2661, 0x8b1ddf84,
0x846a0e79, 0x915f95e2, 0x466e598e, 0x20b45770, 0x8cd55591, 0xc902de4c,
0xb90bace1, 0xbb8205d0, 0x11a86248, 0x7574a99e, 0xb77f19b6, 0xe0a9dc09,
0x662d09a1, 0xc4324633, 0xe85a1f02, 0x09f0be8c, 0x4a99a025, 0x1d6efe10,
0x1ab93d1d, 0x0ba5a4df, 0xa186f20f, 0x2868f169, 0xdcb7da83, 0x573906fe,
0xa1e2ce9b, 0x4fcd7f52, 0x50115e01, 0xa70683fa, 0xa002b5c4, 0x0de6d027,
0x9af88c27, 0x773f8641, 0xc3604c06, 0x61a806b5, 0xf0177a28, 0xc0f586e0,
0x006058aa, 0x30dc7d62, 0x11e69ed7, 0x2338ea63, 0x53c2dd94, 0xc2c21634,
0xbbcbee56, 0x90bcb6de, 0xebfc7da1, 0xce591d76, 0x6f05e409, 0x4b7c0188,
0x39720a3d, 0x7c927c24, 0x86e3725f, 0x724d9db9, 0x1ac15bb4, 0xd39eb8fc,
0xed545578, 0x08fca5b5, 0xd83d7cd3, 0x4dad0fc4, 0x1e50ef5e, 0xb161e6f8,
0xa28514d9, 0x6c51133c, 0x6fd5c7e7, 0x56e14ec4, 0x362abfce, 0xddc6c837,
0xd79a3234, 0x92638212, 0x670efa8e, 0x406000e0
],
[
0x3a39ce37, 0xd3faf5cf, 0xabc27737, 0x5ac52d1b, 0x5cb0679e, 0x4fa33742,
0xd3822740, 0x99bc9bbe, 0xd5118e9d, 0xbf0f7315, 0xd62d1c7e, 0xc700c47b,
0xb78c1b6b, 0x21a19045, 0xb26eb1be, 0x6a366eb4, 0x5748ab2f, 0xbc946e79,
0xc6a376d2, 0x6549c2c8, 0x530ff8ee, 0x468dde7d, 0xd5730a1d, 0x4cd04dc6,
0x2939bbdb, 0xa9ba4650, 0xac9526e8, 0xbe5ee304, 0xa1fad5f0, 0x6a2d519a,
0x63ef8ce2, 0x9a86ee22, 0xc089c2b8, 0x43242ef6, 0xa51e03aa, 0x9cf2d0a4,
0x83c061ba, 0x9be96a4d, 0x8fe51550, 0xba645bd6, 0x2826a2f9, 0xa73a3ae1,
0x4ba99586, 0xef5562e9, 0xc72fefd3, 0xf752f7da, 0x3f046f69, 0x77fa0a59,
0x80e4a915, 0x87b08601, 0x9b09e6ad, 0x3b3ee593, 0xe990fd5a, 0x9e34d797,
0x2cf0b7d9, 0x022b8b51, 0x96d5ac3a, 0x017da67d, 0xd1cf3ed6, 0x7c7d2d28,
0x1f9f25cf, 0xadf2b89b, 0x5ad6b472, 0x5a88f54c, 0xe029ac71, 0xe019a5e6,
0x47b0acfd, 0xed93fa9b, 0xe8d3c48d, 0x283b57cc, 0xf8d56629, 0x79132e28,
0x785f0191, 0xed756055, 0xf7960e44, 0xe3d35e8c, 0x15056dd4, 0x88f46dba,
0x03a16125, 0x0564f0bd, 0xc3eb9e15, 0x3c9057a2, 0x97271aec, 0xa93a072a,
0x1b3f6d9b, 0x1e6321f5, 0xf59c66fb, 0x26dcf319, 0x7533d928, 0xb155fdf5,
0x03563482, 0x8aba3cbb, 0x28517711, 0xc20ad9f8, 0xabcc5167, 0xccad925f,
0x4de81751, 0x3830dc8e, 0x379d5862, 0x9320f991, 0xea7a90c2, 0xfb3e7bce,
0x5121ce64, 0x774fbe32, 0xa8b6e37e, 0xc3293d46, 0x48de5369, 0x6413e680,
0xa2ae0810, 0xdd6db224, 0x69852dfd, 0x09072166, 0xb39a460a, 0x6445c0dd,
0x586cdecf, 0x1c20c8ae, 0x5bbef7dd, 0x1b588d40, 0xccd2017f, 0x6bb4e3bb,
0xdda26a7e, 0x3a59ff45, 0x3e350a44, 0xbcb4cdd5, 0x72eacea8, 0xfa6484bb,
0x8d6612ae, 0xbf3c6f47, 0xd29be463, 0x542f5d9e, 0xaec2771b, 0xf64e6370,
0x740e0d8d, 0xe75b1357, 0xf8721671, 0xaf537d5d, 0x4040cb08, 0x4eb4e2cc,
0x34d2466a, 0x0115af84, 0xe1b00428, 0x95983a1d, 0x06b89fb4, 0xce6ea048,
0x6f3f3b82, 0x3520ab82, 0x011a1d4b, 0x277227f8, 0x611560b1, 0xe7933fdc,
0xbb3a792b, 0x344525bd, 0xa08839e1, 0x51ce794b, 0x2f32c9b7, 0xa01fbac9,
0xe01cc87e, 0xbcc7d1f6, 0xcf0111c3, 0xa1e8aac7, 0x1a908749, 0xd44fbd9a,
0xd0dadecb, 0xd50ada38, 0x0339c32a, 0xc6913667, 0x8df9317c, 0xe0b12b4f,
0xf79e59b7, 0x43f5bb3a, 0xf2d519ff, 0x27d9459c, 0xbf97222c, 0x15e6fc2a,
0x0f91fc71, 0x9b941525, 0xfae59361, 0xceb69ceb, 0xc2a86459, 0x12baa8d1,
0xb6c1075e, 0xe3056a0c, 0x10d25065, 0xcb03a442, 0xe0ec6e0e, 0x1698db3b,
0x4c98a0be, 0x3278e964, 0x9f1f9532, 0xe0d392df, 0xd3a0342b, 0x8971f21e,
0x1b0a7441, 0x4ba3348c, 0xc5be7120, 0xc37632d8, 0xdf359f8d, 0x9b992f2e,
0xe60b6f47, 0x0fe3f11d, 0xe54cda54, 0x1edad891, 0xce6279cf, 0xcd3e7e6f,
0x1618b166, 0xfd2c1d05, 0x848fd2c5, 0xf6fb2299, 0xf523f357, 0xa6327623,
0x93a83531, 0x56cccd02, 0xacf08162, 0x5a75ebb5, 0x6e163697, 0x88d273cc,
0xde966292, 0x81b949d0, 0x4c50901b, 0x71c65614, 0xe6c6c7bd, 0x327a140a,
0x45e1d006, 0xc3f27b9a, 0xc9aa53fd, 0x62a80f00, 0xbb25bfe2, 0x35bdd2f6,
0x71126905, 0xb2040222, 0xb6cbcf7c, 0xcd769c2b, 0x53113ec0, 0x1640e3d3,
0x38abbd60, 0x2547adf0, 0xba38209c, 0xf746ce76, 0x77afa1c5, 0x20756060,
0x85cbfe4e, 0x8ae88dd8, 0x7aaaf9b0, 0x4cf9aa7e, 0x1948c25c, 0x02fb8a8c,
0x01c36ae4, 0xd6ebe1f9, 0x90d4f869, 0xa65cdea0, 0x3f09252d, 0xc208e69f,
0xb74e6132, 0xce77e25b, 0x578fdfe3, 0x3ac372e6
]
];
//*
//* This is the default PARRAY
//*
Blowfish.prototype.PARRAY = [
0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344, 0xa4093822, 0x299f31d0,
0x082efa98, 0xec4e6c89, 0x452821e6, 0x38d01377, 0xbe5466cf, 0x34e90c6c,
0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5, 0xb5470917, 0x9216d5d9, 0x8979fb1b
];
//*
//* This is the number of rounds the cipher will go
//*
Blowfish.prototype.NN = 16;
//*
//* This function is needed to get rid of problems
//* with the high-bit getting set. If we don't do
//* this, then sometimes ( aa & 0x00FFFFFFFF ) is not
//* equal to ( bb & 0x00FFFFFFFF ) even when they
//* agree bit-for-bit for the first 32 bits.
//*
Blowfish.prototype._clean = function(xx) {
if (xx < 0) {
var yy = xx & 0x7FFFFFFF;
xx = yy + 0x80000000;
}
return xx;
};
//*
//* This is the mixing function that uses the sboxes
//*
Blowfish.prototype._F = function(xx) {
var aa;
var bb;
var cc;
var dd;
var yy;
dd = xx & 0x00FF;
xx >>>= 8;
cc = xx & 0x00FF;
xx >>>= 8;
bb = xx & 0x00FF;
xx >>>= 8;
aa = xx & 0x00FF;
yy = this.sboxes[0][aa] + this.sboxes[1][bb];
yy = yy ^ this.sboxes[2][cc];
yy = yy + this.sboxes[3][dd];
return yy;
};
//*
//* This method takes an array with two values, left and right
//* and does NN rounds of Blowfish on them.
//*
Blowfish.prototype._encrypt_block = function(vals) {
var dataL = vals[0];
var dataR = vals[1];
var ii;
for (ii = 0; ii < this.NN; ++ii) {
dataL = dataL ^ this.parray[ii];
dataR = this._F(dataL) ^ dataR;
var tmp = dataL;
dataL = dataR;
dataR = tmp;
}
dataL = dataL ^ this.parray[this.NN + 0];
dataR = dataR ^ this.parray[this.NN + 1];
vals[0] = this._clean(dataR);
vals[1] = this._clean(dataL);
};
//*
//* This method takes a vector of numbers and turns them
//* into long words so that they can be processed by the
//* real algorithm.
//*
//* Maybe I should make the real algorithm above take a vector
//* instead. That will involve more looping, but it won't require
//* the F() method to deconstruct the vector.
//*
Blowfish.prototype.encrypt_block = function(vector) {
var ii;
var vals = [0, 0];
var off = this.BLOCKSIZE / 2;
for (ii = 0; ii < this.BLOCKSIZE / 2; ++ii) {
vals[0] = (vals[0] << 8) | (vector[ii + 0] & 0x00FF);
vals[1] = (vals[1] << 8) | (vector[ii + off] & 0x00FF);
}
this._encrypt_block(vals);
var ret = [];
for (ii = 0; ii < this.BLOCKSIZE / 2; ++ii) {
ret[ii + 0] = (vals[0] >>> (24 - 8 * (ii)) & 0x00FF);
ret[ii + off] = (vals[1] >>> (24 - 8 * (ii)) & 0x00FF);
// vals[ 0 ] = ( vals[ 0 ] >>> 8 );
// vals[ 1 ] = ( vals[ 1 ] >>> 8 );
}
return ret;
};
//*
//* This method takes an array with two values, left and right
//* and undoes NN rounds of Blowfish on them.
//*
Blowfish.prototype._decrypt_block = function(vals) {
var dataL = vals[0];
var dataR = vals[1];
var ii;
for (ii = this.NN + 1; ii > 1; --ii) {
dataL = dataL ^ this.parray[ii];
dataR = this._F(dataL) ^ dataR;
var tmp = dataL;
dataL = dataR;
dataR = tmp;
}
dataL = dataL ^ this.parray[1];
dataR = dataR ^ this.parray[0];
vals[0] = this._clean(dataR);
vals[1] = this._clean(dataL);
};
//*
//* This method takes a key array and initializes the
//* sboxes and parray for this encryption.
//*
Blowfish.prototype.init = function(key) {
var ii;
var jj = 0;
this.parray = [];
for (ii = 0; ii < this.NN + 2; ++ii) {
var data = 0x00000000;
var kk;
for (kk = 0; kk < 4; ++kk) {
data = (data << 8) | (key[jj] & 0x00FF);
if (++jj >= key.length) {
jj = 0;
}
}
this.parray[ii] = this.PARRAY[ii] ^ data;
}
this.sboxes = [];
for (ii = 0; ii < 4; ++ii) {
this.sboxes[ii] = [];
for (jj = 0; jj < 256; ++jj) {
this.sboxes[ii][jj] = this.SBOXES[ii][jj];
}
}
var vals = [0x00000000, 0x00000000];
for (ii = 0; ii < this.NN + 2; ii += 2) {
this._encrypt_block(vals);
this.parray[ii + 0] = vals[0];
this.parray[ii + 1] = vals[1];
}
for (ii = 0; ii < 4; ++ii) {
for (jj = 0; jj < 256; jj += 2) {
this._encrypt_block(vals);
this.sboxes[ii][jj + 0] = vals[0];
this.sboxes[ii][jj + 1] = vals[1];
}
}
};
// added by Recurity Labs
export default function BF(key) {
this.bf = new Blowfish();
this.bf.init(key);
this.encrypt = function(block) {
return this.bf.encrypt_block(block);
};
}
BF.keySize = BF.prototype.keySize = 16;
BF.blockSize = BF.prototype.blockSize = 16;

View file

@ -1,605 +0,0 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Copyright 2010 pjacobs@xeekr.com . All rights reserved.
// Modified by Recurity Labs GmbH
// fixed/modified by Herbert Hanewinkel, www.haneWIN.de
// check www.haneWIN.de for the latest version
// cast5.js is a Javascript implementation of CAST-128, as defined in RFC 2144.
// CAST-128 is a common OpenPGP cipher.
// CAST5 constructor
/** @module crypto/cipher/cast5 */
'use strict';
function OpenpgpSymencCast5() {
this.BlockSize = 8;
this.KeySize = 16;
this.setKey = function(key) {
this.masking = new Array(16);
this.rotate = new Array(16);
this.reset();
if (key.length === this.KeySize) {
this.keySchedule(key);
} else {
throw new Error('CAST-128: keys must be 16 bytes');
}
return true;
};
this.reset = function() {
for (var i = 0; i < 16; i++) {
this.masking[i] = 0;
this.rotate[i] = 0;
}
};
this.getBlockSize = function() {
return this.BlockSize;
};
this.encrypt = function(src) {
var dst = new Array(src.length);
for (var i = 0; i < src.length; i += 8) {
var l = src[i] << 24 | src[i + 1] << 16 | src[i + 2] << 8 | src[i + 3];
var r = src[i + 4] << 24 | src[i + 5] << 16 | src[i + 6] << 8 | src[i + 7];
var t;
t = r;
r = l ^ f1(r, this.masking[0], this.rotate[0]);
l = t;
t = r;
r = l ^ f2(r, this.masking[1], this.rotate[1]);
l = t;
t = r;
r = l ^ f3(r, this.masking[2], this.rotate[2]);
l = t;
t = r;
r = l ^ f1(r, this.masking[3], this.rotate[3]);
l = t;
t = r;
r = l ^ f2(r, this.masking[4], this.rotate[4]);
l = t;
t = r;
r = l ^ f3(r, this.masking[5], this.rotate[5]);
l = t;
t = r;
r = l ^ f1(r, this.masking[6], this.rotate[6]);
l = t;
t = r;
r = l ^ f2(r, this.masking[7], this.rotate[7]);
l = t;
t = r;
r = l ^ f3(r, this.masking[8], this.rotate[8]);
l = t;
t = r;
r = l ^ f1(r, this.masking[9], this.rotate[9]);
l = t;
t = r;
r = l ^ f2(r, this.masking[10], this.rotate[10]);
l = t;
t = r;
r = l ^ f3(r, this.masking[11], this.rotate[11]);
l = t;
t = r;
r = l ^ f1(r, this.masking[12], this.rotate[12]);
l = t;
t = r;
r = l ^ f2(r, this.masking[13], this.rotate[13]);
l = t;
t = r;
r = l ^ f3(r, this.masking[14], this.rotate[14]);
l = t;
t = r;
r = l ^ f1(r, this.masking[15], this.rotate[15]);
l = t;
dst[i] = (r >>> 24) & 255;
dst[i + 1] = (r >>> 16) & 255;
dst[i + 2] = (r >>> 8) & 255;
dst[i + 3] = r & 255;
dst[i + 4] = (l >>> 24) & 255;
dst[i + 5] = (l >>> 16) & 255;
dst[i + 6] = (l >>> 8) & 255;
dst[i + 7] = l & 255;
}
return dst;
};
this.decrypt = function(src) {
var dst = new Array(src.length);
for (var i = 0; i < src.length; i += 8) {
var l = src[i] << 24 | src[i + 1] << 16 | src[i + 2] << 8 | src[i + 3];
var r = src[i + 4] << 24 | src[i + 5] << 16 | src[i + 6] << 8 | src[i + 7];
var t;
t = r;
r = l ^ f1(r, this.masking[15], this.rotate[15]);
l = t;
t = r;
r = l ^ f3(r, this.masking[14], this.rotate[14]);
l = t;
t = r;
r = l ^ f2(r, this.masking[13], this.rotate[13]);
l = t;
t = r;
r = l ^ f1(r, this.masking[12], this.rotate[12]);
l = t;
t = r;
r = l ^ f3(r, this.masking[11], this.rotate[11]);
l = t;
t = r;
r = l ^ f2(r, this.masking[10], this.rotate[10]);
l = t;
t = r;
r = l ^ f1(r, this.masking[9], this.rotate[9]);
l = t;
t = r;
r = l ^ f3(r, this.masking[8], this.rotate[8]);
l = t;
t = r;
r = l ^ f2(r, this.masking[7], this.rotate[7]);
l = t;
t = r;
r = l ^ f1(r, this.masking[6], this.rotate[6]);
l = t;
t = r;
r = l ^ f3(r, this.masking[5], this.rotate[5]);
l = t;
t = r;
r = l ^ f2(r, this.masking[4], this.rotate[4]);
l = t;
t = r;
r = l ^ f1(r, this.masking[3], this.rotate[3]);
l = t;
t = r;
r = l ^ f3(r, this.masking[2], this.rotate[2]);
l = t;
t = r;
r = l ^ f2(r, this.masking[1], this.rotate[1]);
l = t;
t = r;
r = l ^ f1(r, this.masking[0], this.rotate[0]);
l = t;
dst[i] = (r >>> 24) & 255;
dst[i + 1] = (r >>> 16) & 255;
dst[i + 2] = (r >>> 8) & 255;
dst[i + 3] = r & 255;
dst[i + 4] = (l >>> 24) & 255;
dst[i + 5] = (l >> 16) & 255;
dst[i + 6] = (l >> 8) & 255;
dst[i + 7] = l & 255;
}
return dst;
};
var scheduleA = new Array(4);
scheduleA[0] = new Array(4);
scheduleA[0][0] = new Array(4, 0, 0xd, 0xf, 0xc, 0xe, 0x8);
scheduleA[0][1] = new Array(5, 2, 16 + 0, 16 + 2, 16 + 1, 16 + 3, 0xa);
scheduleA[0][2] = new Array(6, 3, 16 + 7, 16 + 6, 16 + 5, 16 + 4, 9);
scheduleA[0][3] = new Array(7, 1, 16 + 0xa, 16 + 9, 16 + 0xb, 16 + 8, 0xb);
scheduleA[1] = new Array(4);
scheduleA[1][0] = new Array(0, 6, 16 + 5, 16 + 7, 16 + 4, 16 + 6, 16 + 0);
scheduleA[1][1] = new Array(1, 4, 0, 2, 1, 3, 16 + 2);
scheduleA[1][2] = new Array(2, 5, 7, 6, 5, 4, 16 + 1);
scheduleA[1][3] = new Array(3, 7, 0xa, 9, 0xb, 8, 16 + 3);
scheduleA[2] = new Array(4);
scheduleA[2][0] = new Array(4, 0, 0xd, 0xf, 0xc, 0xe, 8);
scheduleA[2][1] = new Array(5, 2, 16 + 0, 16 + 2, 16 + 1, 16 + 3, 0xa);
scheduleA[2][2] = new Array(6, 3, 16 + 7, 16 + 6, 16 + 5, 16 + 4, 9);
scheduleA[2][3] = new Array(7, 1, 16 + 0xa, 16 + 9, 16 + 0xb, 16 + 8, 0xb);
scheduleA[3] = new Array(4);
scheduleA[3][0] = new Array(0, 6, 16 + 5, 16 + 7, 16 + 4, 16 + 6, 16 + 0);
scheduleA[3][1] = new Array(1, 4, 0, 2, 1, 3, 16 + 2);
scheduleA[3][2] = new Array(2, 5, 7, 6, 5, 4, 16 + 1);
scheduleA[3][3] = new Array(3, 7, 0xa, 9, 0xb, 8, 16 + 3);
var scheduleB = new Array(4);
scheduleB[0] = new Array(4);
scheduleB[0][0] = new Array(16 + 8, 16 + 9, 16 + 7, 16 + 6, 16 + 2);
scheduleB[0][1] = new Array(16 + 0xa, 16 + 0xb, 16 + 5, 16 + 4, 16 + 6);
scheduleB[0][2] = new Array(16 + 0xc, 16 + 0xd, 16 + 3, 16 + 2, 16 + 9);
scheduleB[0][3] = new Array(16 + 0xe, 16 + 0xf, 16 + 1, 16 + 0, 16 + 0xc);
scheduleB[1] = new Array(4);
scheduleB[1][0] = new Array(3, 2, 0xc, 0xd, 8);
scheduleB[1][1] = new Array(1, 0, 0xe, 0xf, 0xd);
scheduleB[1][2] = new Array(7, 6, 8, 9, 3);
scheduleB[1][3] = new Array(5, 4, 0xa, 0xb, 7);
scheduleB[2] = new Array(4);
scheduleB[2][0] = new Array(16 + 3, 16 + 2, 16 + 0xc, 16 + 0xd, 16 + 9);
scheduleB[2][1] = new Array(16 + 1, 16 + 0, 16 + 0xe, 16 + 0xf, 16 + 0xc);
scheduleB[2][2] = new Array(16 + 7, 16 + 6, 16 + 8, 16 + 9, 16 + 2);
scheduleB[2][3] = new Array(16 + 5, 16 + 4, 16 + 0xa, 16 + 0xb, 16 + 6);
scheduleB[3] = new Array(4);
scheduleB[3][0] = new Array(8, 9, 7, 6, 3);
scheduleB[3][1] = new Array(0xa, 0xb, 5, 4, 7);
scheduleB[3][2] = new Array(0xc, 0xd, 3, 2, 8);
scheduleB[3][3] = new Array(0xe, 0xf, 1, 0, 0xd);
// changed 'in' to 'inn' (in javascript 'in' is a reserved word)
this.keySchedule = function(inn) {
var t = new Array(8);
var k = new Array(32);
var i, j;
for (i = 0; i < 4; i++) {
j = i * 4;
t[i] = inn[j] << 24 | inn[j + 1] << 16 | inn[j + 2] << 8 | inn[j + 3];
}
var x = [6, 7, 4, 5];
var ki = 0;
var w;
for (var half = 0; half < 2; half++) {
for (var round = 0; round < 4; round++) {
for (j = 0; j < 4; j++) {
var a = scheduleA[round][j];
w = t[a[1]];
w ^= sBox[4][(t[a[2] >>> 2] >>> (24 - 8 * (a[2] & 3))) & 0xff];
w ^= sBox[5][(t[a[3] >>> 2] >>> (24 - 8 * (a[3] & 3))) & 0xff];
w ^= sBox[6][(t[a[4] >>> 2] >>> (24 - 8 * (a[4] & 3))) & 0xff];
w ^= sBox[7][(t[a[5] >>> 2] >>> (24 - 8 * (a[5] & 3))) & 0xff];
w ^= sBox[x[j]][(t[a[6] >>> 2] >>> (24 - 8 * (a[6] & 3))) & 0xff];
t[a[0]] = w;
}
for (j = 0; j < 4; j++) {
var b = scheduleB[round][j];
w = sBox[4][(t[b[0] >>> 2] >>> (24 - 8 * (b[0] & 3))) & 0xff];
w ^= sBox[5][(t[b[1] >>> 2] >>> (24 - 8 * (b[1] & 3))) & 0xff];
w ^= sBox[6][(t[b[2] >>> 2] >>> (24 - 8 * (b[2] & 3))) & 0xff];
w ^= sBox[7][(t[b[3] >>> 2] >>> (24 - 8 * (b[3] & 3))) & 0xff];
w ^= sBox[4 + j][(t[b[4] >>> 2] >>> (24 - 8 * (b[4] & 3))) & 0xff];
k[ki] = w;
ki++;
}
}
}
for (i = 0; i < 16; i++) {
this.masking[i] = k[i];
this.rotate[i] = k[16 + i] & 0x1f;
}
};
// These are the three 'f' functions. See RFC 2144, section 2.2.
function f1(d, m, r) {
var t = m + d;
var I = (t << r) | (t >>> (32 - r));
return ((sBox[0][I >>> 24] ^ sBox[1][(I >>> 16) & 255]) - sBox[2][(I >>> 8) & 255]) + sBox[3][I & 255];
}
function f2(d, m, r) {
var t = m ^ d;
var I = (t << r) | (t >>> (32 - r));
return ((sBox[0][I >>> 24] - sBox[1][(I >>> 16) & 255]) + sBox[2][(I >>> 8) & 255]) ^ sBox[3][I & 255];
}
function f3(d, m, r) {
var t = m - d;
var I = (t << r) | (t >>> (32 - r));
return ((sBox[0][I >>> 24] + sBox[1][(I >>> 16) & 255]) ^ sBox[2][(I >>> 8) & 255]) - sBox[3][I & 255];
}
var sBox = new Array(8);
sBox[0] = new Array(
0x30fb40d4, 0x9fa0ff0b, 0x6beccd2f, 0x3f258c7a, 0x1e213f2f, 0x9c004dd3, 0x6003e540, 0xcf9fc949,
0xbfd4af27, 0x88bbbdb5, 0xe2034090, 0x98d09675, 0x6e63a0e0, 0x15c361d2, 0xc2e7661d, 0x22d4ff8e,
0x28683b6f, 0xc07fd059, 0xff2379c8, 0x775f50e2, 0x43c340d3, 0xdf2f8656, 0x887ca41a, 0xa2d2bd2d,
0xa1c9e0d6, 0x346c4819, 0x61b76d87, 0x22540f2f, 0x2abe32e1, 0xaa54166b, 0x22568e3a, 0xa2d341d0,
0x66db40c8, 0xa784392f, 0x004dff2f, 0x2db9d2de, 0x97943fac, 0x4a97c1d8, 0x527644b7, 0xb5f437a7,
0xb82cbaef, 0xd751d159, 0x6ff7f0ed, 0x5a097a1f, 0x827b68d0, 0x90ecf52e, 0x22b0c054, 0xbc8e5935,
0x4b6d2f7f, 0x50bb64a2, 0xd2664910, 0xbee5812d, 0xb7332290, 0xe93b159f, 0xb48ee411, 0x4bff345d,
0xfd45c240, 0xad31973f, 0xc4f6d02e, 0x55fc8165, 0xd5b1caad, 0xa1ac2dae, 0xa2d4b76d, 0xc19b0c50,
0x882240f2, 0x0c6e4f38, 0xa4e4bfd7, 0x4f5ba272, 0x564c1d2f, 0xc59c5319, 0xb949e354, 0xb04669fe,
0xb1b6ab8a, 0xc71358dd, 0x6385c545, 0x110f935d, 0x57538ad5, 0x6a390493, 0xe63d37e0, 0x2a54f6b3,
0x3a787d5f, 0x6276a0b5, 0x19a6fcdf, 0x7a42206a, 0x29f9d4d5, 0xf61b1891, 0xbb72275e, 0xaa508167,
0x38901091, 0xc6b505eb, 0x84c7cb8c, 0x2ad75a0f, 0x874a1427, 0xa2d1936b, 0x2ad286af, 0xaa56d291,
0xd7894360, 0x425c750d, 0x93b39e26, 0x187184c9, 0x6c00b32d, 0x73e2bb14, 0xa0bebc3c, 0x54623779,
0x64459eab, 0x3f328b82, 0x7718cf82, 0x59a2cea6, 0x04ee002e, 0x89fe78e6, 0x3fab0950, 0x325ff6c2,
0x81383f05, 0x6963c5c8, 0x76cb5ad6, 0xd49974c9, 0xca180dcf, 0x380782d5, 0xc7fa5cf6, 0x8ac31511,
0x35e79e13, 0x47da91d0, 0xf40f9086, 0xa7e2419e, 0x31366241, 0x051ef495, 0xaa573b04, 0x4a805d8d,
0x548300d0, 0x00322a3c, 0xbf64cddf, 0xba57a68e, 0x75c6372b, 0x50afd341, 0xa7c13275, 0x915a0bf5,
0x6b54bfab, 0x2b0b1426, 0xab4cc9d7, 0x449ccd82, 0xf7fbf265, 0xab85c5f3, 0x1b55db94, 0xaad4e324,
0xcfa4bd3f, 0x2deaa3e2, 0x9e204d02, 0xc8bd25ac, 0xeadf55b3, 0xd5bd9e98, 0xe31231b2, 0x2ad5ad6c,
0x954329de, 0xadbe4528, 0xd8710f69, 0xaa51c90f, 0xaa786bf6, 0x22513f1e, 0xaa51a79b, 0x2ad344cc,
0x7b5a41f0, 0xd37cfbad, 0x1b069505, 0x41ece491, 0xb4c332e6, 0x032268d4, 0xc9600acc, 0xce387e6d,
0xbf6bb16c, 0x6a70fb78, 0x0d03d9c9, 0xd4df39de, 0xe01063da, 0x4736f464, 0x5ad328d8, 0xb347cc96,
0x75bb0fc3, 0x98511bfb, 0x4ffbcc35, 0xb58bcf6a, 0xe11f0abc, 0xbfc5fe4a, 0xa70aec10, 0xac39570a,
0x3f04442f, 0x6188b153, 0xe0397a2e, 0x5727cb79, 0x9ceb418f, 0x1cacd68d, 0x2ad37c96, 0x0175cb9d,
0xc69dff09, 0xc75b65f0, 0xd9db40d8, 0xec0e7779, 0x4744ead4, 0xb11c3274, 0xdd24cb9e, 0x7e1c54bd,
0xf01144f9, 0xd2240eb1, 0x9675b3fd, 0xa3ac3755, 0xd47c27af, 0x51c85f4d, 0x56907596, 0xa5bb15e6,
0x580304f0, 0xca042cf1, 0x011a37ea, 0x8dbfaadb, 0x35ba3e4a, 0x3526ffa0, 0xc37b4d09, 0xbc306ed9,
0x98a52666, 0x5648f725, 0xff5e569d, 0x0ced63d0, 0x7c63b2cf, 0x700b45e1, 0xd5ea50f1, 0x85a92872,
0xaf1fbda7, 0xd4234870, 0xa7870bf3, 0x2d3b4d79, 0x42e04198, 0x0cd0ede7, 0x26470db8, 0xf881814c,
0x474d6ad7, 0x7c0c5e5c, 0xd1231959, 0x381b7298, 0xf5d2f4db, 0xab838653, 0x6e2f1e23, 0x83719c9e,
0xbd91e046, 0x9a56456e, 0xdc39200c, 0x20c8c571, 0x962bda1c, 0xe1e696ff, 0xb141ab08, 0x7cca89b9,
0x1a69e783, 0x02cc4843, 0xa2f7c579, 0x429ef47d, 0x427b169c, 0x5ac9f049, 0xdd8f0f00, 0x5c8165bf);
sBox[1] = new Array(
0x1f201094, 0xef0ba75b, 0x69e3cf7e, 0x393f4380, 0xfe61cf7a, 0xeec5207a, 0x55889c94, 0x72fc0651,
0xada7ef79, 0x4e1d7235, 0xd55a63ce, 0xde0436ba, 0x99c430ef, 0x5f0c0794, 0x18dcdb7d, 0xa1d6eff3,
0xa0b52f7b, 0x59e83605, 0xee15b094, 0xe9ffd909, 0xdc440086, 0xef944459, 0xba83ccb3, 0xe0c3cdfb,
0xd1da4181, 0x3b092ab1, 0xf997f1c1, 0xa5e6cf7b, 0x01420ddb, 0xe4e7ef5b, 0x25a1ff41, 0xe180f806,
0x1fc41080, 0x179bee7a, 0xd37ac6a9, 0xfe5830a4, 0x98de8b7f, 0x77e83f4e, 0x79929269, 0x24fa9f7b,
0xe113c85b, 0xacc40083, 0xd7503525, 0xf7ea615f, 0x62143154, 0x0d554b63, 0x5d681121, 0xc866c359,
0x3d63cf73, 0xcee234c0, 0xd4d87e87, 0x5c672b21, 0x071f6181, 0x39f7627f, 0x361e3084, 0xe4eb573b,
0x602f64a4, 0xd63acd9c, 0x1bbc4635, 0x9e81032d, 0x2701f50c, 0x99847ab4, 0xa0e3df79, 0xba6cf38c,
0x10843094, 0x2537a95e, 0xf46f6ffe, 0xa1ff3b1f, 0x208cfb6a, 0x8f458c74, 0xd9e0a227, 0x4ec73a34,
0xfc884f69, 0x3e4de8df, 0xef0e0088, 0x3559648d, 0x8a45388c, 0x1d804366, 0x721d9bfd, 0xa58684bb,
0xe8256333, 0x844e8212, 0x128d8098, 0xfed33fb4, 0xce280ae1, 0x27e19ba5, 0xd5a6c252, 0xe49754bd,
0xc5d655dd, 0xeb667064, 0x77840b4d, 0xa1b6a801, 0x84db26a9, 0xe0b56714, 0x21f043b7, 0xe5d05860,
0x54f03084, 0x066ff472, 0xa31aa153, 0xdadc4755, 0xb5625dbf, 0x68561be6, 0x83ca6b94, 0x2d6ed23b,
0xeccf01db, 0xa6d3d0ba, 0xb6803d5c, 0xaf77a709, 0x33b4a34c, 0x397bc8d6, 0x5ee22b95, 0x5f0e5304,
0x81ed6f61, 0x20e74364, 0xb45e1378, 0xde18639b, 0x881ca122, 0xb96726d1, 0x8049a7e8, 0x22b7da7b,
0x5e552d25, 0x5272d237, 0x79d2951c, 0xc60d894c, 0x488cb402, 0x1ba4fe5b, 0xa4b09f6b, 0x1ca815cf,
0xa20c3005, 0x8871df63, 0xb9de2fcb, 0x0cc6c9e9, 0x0beeff53, 0xe3214517, 0xb4542835, 0x9f63293c,
0xee41e729, 0x6e1d2d7c, 0x50045286, 0x1e6685f3, 0xf33401c6, 0x30a22c95, 0x31a70850, 0x60930f13,
0x73f98417, 0xa1269859, 0xec645c44, 0x52c877a9, 0xcdff33a6, 0xa02b1741, 0x7cbad9a2, 0x2180036f,
0x50d99c08, 0xcb3f4861, 0xc26bd765, 0x64a3f6ab, 0x80342676, 0x25a75e7b, 0xe4e6d1fc, 0x20c710e6,
0xcdf0b680, 0x17844d3b, 0x31eef84d, 0x7e0824e4, 0x2ccb49eb, 0x846a3bae, 0x8ff77888, 0xee5d60f6,
0x7af75673, 0x2fdd5cdb, 0xa11631c1, 0x30f66f43, 0xb3faec54, 0x157fd7fa, 0xef8579cc, 0xd152de58,
0xdb2ffd5e, 0x8f32ce19, 0x306af97a, 0x02f03ef8, 0x99319ad5, 0xc242fa0f, 0xa7e3ebb0, 0xc68e4906,
0xb8da230c, 0x80823028, 0xdcdef3c8, 0xd35fb171, 0x088a1bc8, 0xbec0c560, 0x61a3c9e8, 0xbca8f54d,
0xc72feffa, 0x22822e99, 0x82c570b4, 0xd8d94e89, 0x8b1c34bc, 0x301e16e6, 0x273be979, 0xb0ffeaa6,
0x61d9b8c6, 0x00b24869, 0xb7ffce3f, 0x08dc283b, 0x43daf65a, 0xf7e19798, 0x7619b72f, 0x8f1c9ba4,
0xdc8637a0, 0x16a7d3b1, 0x9fc393b7, 0xa7136eeb, 0xc6bcc63e, 0x1a513742, 0xef6828bc, 0x520365d6,
0x2d6a77ab, 0x3527ed4b, 0x821fd216, 0x095c6e2e, 0xdb92f2fb, 0x5eea29cb, 0x145892f5, 0x91584f7f,
0x5483697b, 0x2667a8cc, 0x85196048, 0x8c4bacea, 0x833860d4, 0x0d23e0f9, 0x6c387e8a, 0x0ae6d249,
0xb284600c, 0xd835731d, 0xdcb1c647, 0xac4c56ea, 0x3ebd81b3, 0x230eabb0, 0x6438bc87, 0xf0b5b1fa,
0x8f5ea2b3, 0xfc184642, 0x0a036b7a, 0x4fb089bd, 0x649da589, 0xa345415e, 0x5c038323, 0x3e5d3bb9,
0x43d79572, 0x7e6dd07c, 0x06dfdf1e, 0x6c6cc4ef, 0x7160a539, 0x73bfbe70, 0x83877605, 0x4523ecf1);
sBox[2] = new Array(
0x8defc240, 0x25fa5d9f, 0xeb903dbf, 0xe810c907, 0x47607fff, 0x369fe44b, 0x8c1fc644, 0xaececa90,
0xbeb1f9bf, 0xeefbcaea, 0xe8cf1950, 0x51df07ae, 0x920e8806, 0xf0ad0548, 0xe13c8d83, 0x927010d5,
0x11107d9f, 0x07647db9, 0xb2e3e4d4, 0x3d4f285e, 0xb9afa820, 0xfade82e0, 0xa067268b, 0x8272792e,
0x553fb2c0, 0x489ae22b, 0xd4ef9794, 0x125e3fbc, 0x21fffcee, 0x825b1bfd, 0x9255c5ed, 0x1257a240,
0x4e1a8302, 0xbae07fff, 0x528246e7, 0x8e57140e, 0x3373f7bf, 0x8c9f8188, 0xa6fc4ee8, 0xc982b5a5,
0xa8c01db7, 0x579fc264, 0x67094f31, 0xf2bd3f5f, 0x40fff7c1, 0x1fb78dfc, 0x8e6bd2c1, 0x437be59b,
0x99b03dbf, 0xb5dbc64b, 0x638dc0e6, 0x55819d99, 0xa197c81c, 0x4a012d6e, 0xc5884a28, 0xccc36f71,
0xb843c213, 0x6c0743f1, 0x8309893c, 0x0feddd5f, 0x2f7fe850, 0xd7c07f7e, 0x02507fbf, 0x5afb9a04,
0xa747d2d0, 0x1651192e, 0xaf70bf3e, 0x58c31380, 0x5f98302e, 0x727cc3c4, 0x0a0fb402, 0x0f7fef82,
0x8c96fdad, 0x5d2c2aae, 0x8ee99a49, 0x50da88b8, 0x8427f4a0, 0x1eac5790, 0x796fb449, 0x8252dc15,
0xefbd7d9b, 0xa672597d, 0xada840d8, 0x45f54504, 0xfa5d7403, 0xe83ec305, 0x4f91751a, 0x925669c2,
0x23efe941, 0xa903f12e, 0x60270df2, 0x0276e4b6, 0x94fd6574, 0x927985b2, 0x8276dbcb, 0x02778176,
0xf8af918d, 0x4e48f79e, 0x8f616ddf, 0xe29d840e, 0x842f7d83, 0x340ce5c8, 0x96bbb682, 0x93b4b148,
0xef303cab, 0x984faf28, 0x779faf9b, 0x92dc560d, 0x224d1e20, 0x8437aa88, 0x7d29dc96, 0x2756d3dc,
0x8b907cee, 0xb51fd240, 0xe7c07ce3, 0xe566b4a1, 0xc3e9615e, 0x3cf8209d, 0x6094d1e3, 0xcd9ca341,
0x5c76460e, 0x00ea983b, 0xd4d67881, 0xfd47572c, 0xf76cedd9, 0xbda8229c, 0x127dadaa, 0x438a074e,
0x1f97c090, 0x081bdb8a, 0x93a07ebe, 0xb938ca15, 0x97b03cff, 0x3dc2c0f8, 0x8d1ab2ec, 0x64380e51,
0x68cc7bfb, 0xd90f2788, 0x12490181, 0x5de5ffd4, 0xdd7ef86a, 0x76a2e214, 0xb9a40368, 0x925d958f,
0x4b39fffa, 0xba39aee9, 0xa4ffd30b, 0xfaf7933b, 0x6d498623, 0x193cbcfa, 0x27627545, 0x825cf47a,
0x61bd8ba0, 0xd11e42d1, 0xcead04f4, 0x127ea392, 0x10428db7, 0x8272a972, 0x9270c4a8, 0x127de50b,
0x285ba1c8, 0x3c62f44f, 0x35c0eaa5, 0xe805d231, 0x428929fb, 0xb4fcdf82, 0x4fb66a53, 0x0e7dc15b,
0x1f081fab, 0x108618ae, 0xfcfd086d, 0xf9ff2889, 0x694bcc11, 0x236a5cae, 0x12deca4d, 0x2c3f8cc5,
0xd2d02dfe, 0xf8ef5896, 0xe4cf52da, 0x95155b67, 0x494a488c, 0xb9b6a80c, 0x5c8f82bc, 0x89d36b45,
0x3a609437, 0xec00c9a9, 0x44715253, 0x0a874b49, 0xd773bc40, 0x7c34671c, 0x02717ef6, 0x4feb5536,
0xa2d02fff, 0xd2bf60c4, 0xd43f03c0, 0x50b4ef6d, 0x07478cd1, 0x006e1888, 0xa2e53f55, 0xb9e6d4bc,
0xa2048016, 0x97573833, 0xd7207d67, 0xde0f8f3d, 0x72f87b33, 0xabcc4f33, 0x7688c55d, 0x7b00a6b0,
0x947b0001, 0x570075d2, 0xf9bb88f8, 0x8942019e, 0x4264a5ff, 0x856302e0, 0x72dbd92b, 0xee971b69,
0x6ea22fde, 0x5f08ae2b, 0xaf7a616d, 0xe5c98767, 0xcf1febd2, 0x61efc8c2, 0xf1ac2571, 0xcc8239c2,
0x67214cb8, 0xb1e583d1, 0xb7dc3e62, 0x7f10bdce, 0xf90a5c38, 0x0ff0443d, 0x606e6dc6, 0x60543a49,
0x5727c148, 0x2be98a1d, 0x8ab41738, 0x20e1be24, 0xaf96da0f, 0x68458425, 0x99833be5, 0x600d457d,
0x282f9350, 0x8334b362, 0xd91d1120, 0x2b6d8da0, 0x642b1e31, 0x9c305a00, 0x52bce688, 0x1b03588a,
0xf7baefd5, 0x4142ed9c, 0xa4315c11, 0x83323ec5, 0xdfef4636, 0xa133c501, 0xe9d3531c, 0xee353783);
sBox[3] = new Array(
0x9db30420, 0x1fb6e9de, 0xa7be7bef, 0xd273a298, 0x4a4f7bdb, 0x64ad8c57, 0x85510443, 0xfa020ed1,
0x7e287aff, 0xe60fb663, 0x095f35a1, 0x79ebf120, 0xfd059d43, 0x6497b7b1, 0xf3641f63, 0x241e4adf,
0x28147f5f, 0x4fa2b8cd, 0xc9430040, 0x0cc32220, 0xfdd30b30, 0xc0a5374f, 0x1d2d00d9, 0x24147b15,
0xee4d111a, 0x0fca5167, 0x71ff904c, 0x2d195ffe, 0x1a05645f, 0x0c13fefe, 0x081b08ca, 0x05170121,
0x80530100, 0xe83e5efe, 0xac9af4f8, 0x7fe72701, 0xd2b8ee5f, 0x06df4261, 0xbb9e9b8a, 0x7293ea25,
0xce84ffdf, 0xf5718801, 0x3dd64b04, 0xa26f263b, 0x7ed48400, 0x547eebe6, 0x446d4ca0, 0x6cf3d6f5,
0x2649abdf, 0xaea0c7f5, 0x36338cc1, 0x503f7e93, 0xd3772061, 0x11b638e1, 0x72500e03, 0xf80eb2bb,
0xabe0502e, 0xec8d77de, 0x57971e81, 0xe14f6746, 0xc9335400, 0x6920318f, 0x081dbb99, 0xffc304a5,
0x4d351805, 0x7f3d5ce3, 0xa6c866c6, 0x5d5bcca9, 0xdaec6fea, 0x9f926f91, 0x9f46222f, 0x3991467d,
0xa5bf6d8e, 0x1143c44f, 0x43958302, 0xd0214eeb, 0x022083b8, 0x3fb6180c, 0x18f8931e, 0x281658e6,
0x26486e3e, 0x8bd78a70, 0x7477e4c1, 0xb506e07c, 0xf32d0a25, 0x79098b02, 0xe4eabb81, 0x28123b23,
0x69dead38, 0x1574ca16, 0xdf871b62, 0x211c40b7, 0xa51a9ef9, 0x0014377b, 0x041e8ac8, 0x09114003,
0xbd59e4d2, 0xe3d156d5, 0x4fe876d5, 0x2f91a340, 0x557be8de, 0x00eae4a7, 0x0ce5c2ec, 0x4db4bba6,
0xe756bdff, 0xdd3369ac, 0xec17b035, 0x06572327, 0x99afc8b0, 0x56c8c391, 0x6b65811c, 0x5e146119,
0x6e85cb75, 0xbe07c002, 0xc2325577, 0x893ff4ec, 0x5bbfc92d, 0xd0ec3b25, 0xb7801ab7, 0x8d6d3b24,
0x20c763ef, 0xc366a5fc, 0x9c382880, 0x0ace3205, 0xaac9548a, 0xeca1d7c7, 0x041afa32, 0x1d16625a,
0x6701902c, 0x9b757a54, 0x31d477f7, 0x9126b031, 0x36cc6fdb, 0xc70b8b46, 0xd9e66a48, 0x56e55a79,
0x026a4ceb, 0x52437eff, 0x2f8f76b4, 0x0df980a5, 0x8674cde3, 0xedda04eb, 0x17a9be04, 0x2c18f4df,
0xb7747f9d, 0xab2af7b4, 0xefc34d20, 0x2e096b7c, 0x1741a254, 0xe5b6a035, 0x213d42f6, 0x2c1c7c26,
0x61c2f50f, 0x6552daf9, 0xd2c231f8, 0x25130f69, 0xd8167fa2, 0x0418f2c8, 0x001a96a6, 0x0d1526ab,
0x63315c21, 0x5e0a72ec, 0x49bafefd, 0x187908d9, 0x8d0dbd86, 0x311170a7, 0x3e9b640c, 0xcc3e10d7,
0xd5cad3b6, 0x0caec388, 0xf73001e1, 0x6c728aff, 0x71eae2a1, 0x1f9af36e, 0xcfcbd12f, 0xc1de8417,
0xac07be6b, 0xcb44a1d8, 0x8b9b0f56, 0x013988c3, 0xb1c52fca, 0xb4be31cd, 0xd8782806, 0x12a3a4e2,
0x6f7de532, 0x58fd7eb6, 0xd01ee900, 0x24adffc2, 0xf4990fc5, 0x9711aac5, 0x001d7b95, 0x82e5e7d2,
0x109873f6, 0x00613096, 0xc32d9521, 0xada121ff, 0x29908415, 0x7fbb977f, 0xaf9eb3db, 0x29c9ed2a,
0x5ce2a465, 0xa730f32c, 0xd0aa3fe8, 0x8a5cc091, 0xd49e2ce7, 0x0ce454a9, 0xd60acd86, 0x015f1919,
0x77079103, 0xdea03af6, 0x78a8565e, 0xdee356df, 0x21f05cbe, 0x8b75e387, 0xb3c50651, 0xb8a5c3ef,
0xd8eeb6d2, 0xe523be77, 0xc2154529, 0x2f69efdf, 0xafe67afb, 0xf470c4b2, 0xf3e0eb5b, 0xd6cc9876,
0x39e4460c, 0x1fda8538, 0x1987832f, 0xca007367, 0xa99144f8, 0x296b299e, 0x492fc295, 0x9266beab,
0xb5676e69, 0x9bd3ddda, 0xdf7e052f, 0xdb25701c, 0x1b5e51ee, 0xf65324e6, 0x6afce36c, 0x0316cc04,
0x8644213e, 0xb7dc59d0, 0x7965291f, 0xccd6fd43, 0x41823979, 0x932bcdf6, 0xb657c34d, 0x4edfd282,
0x7ae5290c, 0x3cb9536b, 0x851e20fe, 0x9833557e, 0x13ecf0b0, 0xd3ffb372, 0x3f85c5c1, 0x0aef7ed2);
sBox[4] = new Array(
0x7ec90c04, 0x2c6e74b9, 0x9b0e66df, 0xa6337911, 0xb86a7fff, 0x1dd358f5, 0x44dd9d44, 0x1731167f,
0x08fbf1fa, 0xe7f511cc, 0xd2051b00, 0x735aba00, 0x2ab722d8, 0x386381cb, 0xacf6243a, 0x69befd7a,
0xe6a2e77f, 0xf0c720cd, 0xc4494816, 0xccf5c180, 0x38851640, 0x15b0a848, 0xe68b18cb, 0x4caadeff,
0x5f480a01, 0x0412b2aa, 0x259814fc, 0x41d0efe2, 0x4e40b48d, 0x248eb6fb, 0x8dba1cfe, 0x41a99b02,
0x1a550a04, 0xba8f65cb, 0x7251f4e7, 0x95a51725, 0xc106ecd7, 0x97a5980a, 0xc539b9aa, 0x4d79fe6a,
0xf2f3f763, 0x68af8040, 0xed0c9e56, 0x11b4958b, 0xe1eb5a88, 0x8709e6b0, 0xd7e07156, 0x4e29fea7,
0x6366e52d, 0x02d1c000, 0xc4ac8e05, 0x9377f571, 0x0c05372a, 0x578535f2, 0x2261be02, 0xd642a0c9,
0xdf13a280, 0x74b55bd2, 0x682199c0, 0xd421e5ec, 0x53fb3ce8, 0xc8adedb3, 0x28a87fc9, 0x3d959981,
0x5c1ff900, 0xfe38d399, 0x0c4eff0b, 0x062407ea, 0xaa2f4fb1, 0x4fb96976, 0x90c79505, 0xb0a8a774,
0xef55a1ff, 0xe59ca2c2, 0xa6b62d27, 0xe66a4263, 0xdf65001f, 0x0ec50966, 0xdfdd55bc, 0x29de0655,
0x911e739a, 0x17af8975, 0x32c7911c, 0x89f89468, 0x0d01e980, 0x524755f4, 0x03b63cc9, 0x0cc844b2,
0xbcf3f0aa, 0x87ac36e9, 0xe53a7426, 0x01b3d82b, 0x1a9e7449, 0x64ee2d7e, 0xcddbb1da, 0x01c94910,
0xb868bf80, 0x0d26f3fd, 0x9342ede7, 0x04a5c284, 0x636737b6, 0x50f5b616, 0xf24766e3, 0x8eca36c1,
0x136e05db, 0xfef18391, 0xfb887a37, 0xd6e7f7d4, 0xc7fb7dc9, 0x3063fcdf, 0xb6f589de, 0xec2941da,
0x26e46695, 0xb7566419, 0xf654efc5, 0xd08d58b7, 0x48925401, 0xc1bacb7f, 0xe5ff550f, 0xb6083049,
0x5bb5d0e8, 0x87d72e5a, 0xab6a6ee1, 0x223a66ce, 0xc62bf3cd, 0x9e0885f9, 0x68cb3e47, 0x086c010f,
0xa21de820, 0xd18b69de, 0xf3f65777, 0xfa02c3f6, 0x407edac3, 0xcbb3d550, 0x1793084d, 0xb0d70eba,
0x0ab378d5, 0xd951fb0c, 0xded7da56, 0x4124bbe4, 0x94ca0b56, 0x0f5755d1, 0xe0e1e56e, 0x6184b5be,
0x580a249f, 0x94f74bc0, 0xe327888e, 0x9f7b5561, 0xc3dc0280, 0x05687715, 0x646c6bd7, 0x44904db3,
0x66b4f0a3, 0xc0f1648a, 0x697ed5af, 0x49e92ff6, 0x309e374f, 0x2cb6356a, 0x85808573, 0x4991f840,
0x76f0ae02, 0x083be84d, 0x28421c9a, 0x44489406, 0x736e4cb8, 0xc1092910, 0x8bc95fc6, 0x7d869cf4,
0x134f616f, 0x2e77118d, 0xb31b2be1, 0xaa90b472, 0x3ca5d717, 0x7d161bba, 0x9cad9010, 0xaf462ba2,
0x9fe459d2, 0x45d34559, 0xd9f2da13, 0xdbc65487, 0xf3e4f94e, 0x176d486f, 0x097c13ea, 0x631da5c7,
0x445f7382, 0x175683f4, 0xcdc66a97, 0x70be0288, 0xb3cdcf72, 0x6e5dd2f3, 0x20936079, 0x459b80a5,
0xbe60e2db, 0xa9c23101, 0xeba5315c, 0x224e42f2, 0x1c5c1572, 0xf6721b2c, 0x1ad2fff3, 0x8c25404e,
0x324ed72f, 0x4067b7fd, 0x0523138e, 0x5ca3bc78, 0xdc0fd66e, 0x75922283, 0x784d6b17, 0x58ebb16e,
0x44094f85, 0x3f481d87, 0xfcfeae7b, 0x77b5ff76, 0x8c2302bf, 0xaaf47556, 0x5f46b02a, 0x2b092801,
0x3d38f5f7, 0x0ca81f36, 0x52af4a8a, 0x66d5e7c0, 0xdf3b0874, 0x95055110, 0x1b5ad7a8, 0xf61ed5ad,
0x6cf6e479, 0x20758184, 0xd0cefa65, 0x88f7be58, 0x4a046826, 0x0ff6f8f3, 0xa09c7f70, 0x5346aba0,
0x5ce96c28, 0xe176eda3, 0x6bac307f, 0x376829d2, 0x85360fa9, 0x17e3fe2a, 0x24b79767, 0xf5a96b20,
0xd6cd2595, 0x68ff1ebf, 0x7555442c, 0xf19f06be, 0xf9e0659a, 0xeeb9491d, 0x34010718, 0xbb30cab8,
0xe822fe15, 0x88570983, 0x750e6249, 0xda627e55, 0x5e76ffa8, 0xb1534546, 0x6d47de08, 0xefe9e7d4);
sBox[5] = new Array(
0xf6fa8f9d, 0x2cac6ce1, 0x4ca34867, 0xe2337f7c, 0x95db08e7, 0x016843b4, 0xeced5cbc, 0x325553ac,
0xbf9f0960, 0xdfa1e2ed, 0x83f0579d, 0x63ed86b9, 0x1ab6a6b8, 0xde5ebe39, 0xf38ff732, 0x8989b138,
0x33f14961, 0xc01937bd, 0xf506c6da, 0xe4625e7e, 0xa308ea99, 0x4e23e33c, 0x79cbd7cc, 0x48a14367,
0xa3149619, 0xfec94bd5, 0xa114174a, 0xeaa01866, 0xa084db2d, 0x09a8486f, 0xa888614a, 0x2900af98,
0x01665991, 0xe1992863, 0xc8f30c60, 0x2e78ef3c, 0xd0d51932, 0xcf0fec14, 0xf7ca07d2, 0xd0a82072,
0xfd41197e, 0x9305a6b0, 0xe86be3da, 0x74bed3cd, 0x372da53c, 0x4c7f4448, 0xdab5d440, 0x6dba0ec3,
0x083919a7, 0x9fbaeed9, 0x49dbcfb0, 0x4e670c53, 0x5c3d9c01, 0x64bdb941, 0x2c0e636a, 0xba7dd9cd,
0xea6f7388, 0xe70bc762, 0x35f29adb, 0x5c4cdd8d, 0xf0d48d8c, 0xb88153e2, 0x08a19866, 0x1ae2eac8,
0x284caf89, 0xaa928223, 0x9334be53, 0x3b3a21bf, 0x16434be3, 0x9aea3906, 0xefe8c36e, 0xf890cdd9,
0x80226dae, 0xc340a4a3, 0xdf7e9c09, 0xa694a807, 0x5b7c5ecc, 0x221db3a6, 0x9a69a02f, 0x68818a54,
0xceb2296f, 0x53c0843a, 0xfe893655, 0x25bfe68a, 0xb4628abc, 0xcf222ebf, 0x25ac6f48, 0xa9a99387,
0x53bddb65, 0xe76ffbe7, 0xe967fd78, 0x0ba93563, 0x8e342bc1, 0xe8a11be9, 0x4980740d, 0xc8087dfc,
0x8de4bf99, 0xa11101a0, 0x7fd37975, 0xda5a26c0, 0xe81f994f, 0x9528cd89, 0xfd339fed, 0xb87834bf,
0x5f04456d, 0x22258698, 0xc9c4c83b, 0x2dc156be, 0x4f628daa, 0x57f55ec5, 0xe2220abe, 0xd2916ebf,
0x4ec75b95, 0x24f2c3c0, 0x42d15d99, 0xcd0d7fa0, 0x7b6e27ff, 0xa8dc8af0, 0x7345c106, 0xf41e232f,
0x35162386, 0xe6ea8926, 0x3333b094, 0x157ec6f2, 0x372b74af, 0x692573e4, 0xe9a9d848, 0xf3160289,
0x3a62ef1d, 0xa787e238, 0xf3a5f676, 0x74364853, 0x20951063, 0x4576698d, 0xb6fad407, 0x592af950,
0x36f73523, 0x4cfb6e87, 0x7da4cec0, 0x6c152daa, 0xcb0396a8, 0xc50dfe5d, 0xfcd707ab, 0x0921c42f,
0x89dff0bb, 0x5fe2be78, 0x448f4f33, 0x754613c9, 0x2b05d08d, 0x48b9d585, 0xdc049441, 0xc8098f9b,
0x7dede786, 0xc39a3373, 0x42410005, 0x6a091751, 0x0ef3c8a6, 0x890072d6, 0x28207682, 0xa9a9f7be,
0xbf32679d, 0xd45b5b75, 0xb353fd00, 0xcbb0e358, 0x830f220a, 0x1f8fb214, 0xd372cf08, 0xcc3c4a13,
0x8cf63166, 0x061c87be, 0x88c98f88, 0x6062e397, 0x47cf8e7a, 0xb6c85283, 0x3cc2acfb, 0x3fc06976,
0x4e8f0252, 0x64d8314d, 0xda3870e3, 0x1e665459, 0xc10908f0, 0x513021a5, 0x6c5b68b7, 0x822f8aa0,
0x3007cd3e, 0x74719eef, 0xdc872681, 0x073340d4, 0x7e432fd9, 0x0c5ec241, 0x8809286c, 0xf592d891,
0x08a930f6, 0x957ef305, 0xb7fbffbd, 0xc266e96f, 0x6fe4ac98, 0xb173ecc0, 0xbc60b42a, 0x953498da,
0xfba1ae12, 0x2d4bd736, 0x0f25faab, 0xa4f3fceb, 0xe2969123, 0x257f0c3d, 0x9348af49, 0x361400bc,
0xe8816f4a, 0x3814f200, 0xa3f94043, 0x9c7a54c2, 0xbc704f57, 0xda41e7f9, 0xc25ad33a, 0x54f4a084,
0xb17f5505, 0x59357cbe, 0xedbd15c8, 0x7f97c5ab, 0xba5ac7b5, 0xb6f6deaf, 0x3a479c3a, 0x5302da25,
0x653d7e6a, 0x54268d49, 0x51a477ea, 0x5017d55b, 0xd7d25d88, 0x44136c76, 0x0404a8c8, 0xb8e5a121,
0xb81a928a, 0x60ed5869, 0x97c55b96, 0xeaec991b, 0x29935913, 0x01fdb7f1, 0x088e8dfa, 0x9ab6f6f5,
0x3b4cbf9f, 0x4a5de3ab, 0xe6051d35, 0xa0e1d855, 0xd36b4cf1, 0xf544edeb, 0xb0e93524, 0xbebb8fbd,
0xa2d762cf, 0x49c92f54, 0x38b5f331, 0x7128a454, 0x48392905, 0xa65b1db8, 0x851c97bd, 0xd675cf2f);
sBox[6] = new Array(
0x85e04019, 0x332bf567, 0x662dbfff, 0xcfc65693, 0x2a8d7f6f, 0xab9bc912, 0xde6008a1, 0x2028da1f,
0x0227bce7, 0x4d642916, 0x18fac300, 0x50f18b82, 0x2cb2cb11, 0xb232e75c, 0x4b3695f2, 0xb28707de,
0xa05fbcf6, 0xcd4181e9, 0xe150210c, 0xe24ef1bd, 0xb168c381, 0xfde4e789, 0x5c79b0d8, 0x1e8bfd43,
0x4d495001, 0x38be4341, 0x913cee1d, 0x92a79c3f, 0x089766be, 0xbaeeadf4, 0x1286becf, 0xb6eacb19,
0x2660c200, 0x7565bde4, 0x64241f7a, 0x8248dca9, 0xc3b3ad66, 0x28136086, 0x0bd8dfa8, 0x356d1cf2,
0x107789be, 0xb3b2e9ce, 0x0502aa8f, 0x0bc0351e, 0x166bf52a, 0xeb12ff82, 0xe3486911, 0xd34d7516,
0x4e7b3aff, 0x5f43671b, 0x9cf6e037, 0x4981ac83, 0x334266ce, 0x8c9341b7, 0xd0d854c0, 0xcb3a6c88,
0x47bc2829, 0x4725ba37, 0xa66ad22b, 0x7ad61f1e, 0x0c5cbafa, 0x4437f107, 0xb6e79962, 0x42d2d816,
0x0a961288, 0xe1a5c06e, 0x13749e67, 0x72fc081a, 0xb1d139f7, 0xf9583745, 0xcf19df58, 0xbec3f756,
0xc06eba30, 0x07211b24, 0x45c28829, 0xc95e317f, 0xbc8ec511, 0x38bc46e9, 0xc6e6fa14, 0xbae8584a,
0xad4ebc46, 0x468f508b, 0x7829435f, 0xf124183b, 0x821dba9f, 0xaff60ff4, 0xea2c4e6d, 0x16e39264,
0x92544a8b, 0x009b4fc3, 0xaba68ced, 0x9ac96f78, 0x06a5b79a, 0xb2856e6e, 0x1aec3ca9, 0xbe838688,
0x0e0804e9, 0x55f1be56, 0xe7e5363b, 0xb3a1f25d, 0xf7debb85, 0x61fe033c, 0x16746233, 0x3c034c28,
0xda6d0c74, 0x79aac56c, 0x3ce4e1ad, 0x51f0c802, 0x98f8f35a, 0x1626a49f, 0xeed82b29, 0x1d382fe3,
0x0c4fb99a, 0xbb325778, 0x3ec6d97b, 0x6e77a6a9, 0xcb658b5c, 0xd45230c7, 0x2bd1408b, 0x60c03eb7,
0xb9068d78, 0xa33754f4, 0xf430c87d, 0xc8a71302, 0xb96d8c32, 0xebd4e7be, 0xbe8b9d2d, 0x7979fb06,
0xe7225308, 0x8b75cf77, 0x11ef8da4, 0xe083c858, 0x8d6b786f, 0x5a6317a6, 0xfa5cf7a0, 0x5dda0033,
0xf28ebfb0, 0xf5b9c310, 0xa0eac280, 0x08b9767a, 0xa3d9d2b0, 0x79d34217, 0x021a718d, 0x9ac6336a,
0x2711fd60, 0x438050e3, 0x069908a8, 0x3d7fedc4, 0x826d2bef, 0x4eeb8476, 0x488dcf25, 0x36c9d566,
0x28e74e41, 0xc2610aca, 0x3d49a9cf, 0xbae3b9df, 0xb65f8de6, 0x92aeaf64, 0x3ac7d5e6, 0x9ea80509,
0xf22b017d, 0xa4173f70, 0xdd1e16c3, 0x15e0d7f9, 0x50b1b887, 0x2b9f4fd5, 0x625aba82, 0x6a017962,
0x2ec01b9c, 0x15488aa9, 0xd716e740, 0x40055a2c, 0x93d29a22, 0xe32dbf9a, 0x058745b9, 0x3453dc1e,
0xd699296e, 0x496cff6f, 0x1c9f4986, 0xdfe2ed07, 0xb87242d1, 0x19de7eae, 0x053e561a, 0x15ad6f8c,
0x66626c1c, 0x7154c24c, 0xea082b2a, 0x93eb2939, 0x17dcb0f0, 0x58d4f2ae, 0x9ea294fb, 0x52cf564c,
0x9883fe66, 0x2ec40581, 0x763953c3, 0x01d6692e, 0xd3a0c108, 0xa1e7160e, 0xe4f2dfa6, 0x693ed285,
0x74904698, 0x4c2b0edd, 0x4f757656, 0x5d393378, 0xa132234f, 0x3d321c5d, 0xc3f5e194, 0x4b269301,
0xc79f022f, 0x3c997e7e, 0x5e4f9504, 0x3ffafbbd, 0x76f7ad0e, 0x296693f4, 0x3d1fce6f, 0xc61e45be,
0xd3b5ab34, 0xf72bf9b7, 0x1b0434c0, 0x4e72b567, 0x5592a33d, 0xb5229301, 0xcfd2a87f, 0x60aeb767,
0x1814386b, 0x30bcc33d, 0x38a0c07d, 0xfd1606f2, 0xc363519b, 0x589dd390, 0x5479f8e6, 0x1cb8d647,
0x97fd61a9, 0xea7759f4, 0x2d57539d, 0x569a58cf, 0xe84e63ad, 0x462e1b78, 0x6580f87e, 0xf3817914,
0x91da55f4, 0x40a230f3, 0xd1988f35, 0xb6e318d2, 0x3ffa50bc, 0x3d40f021, 0xc3c0bdae, 0x4958c24c,
0x518f36b2, 0x84b1d370, 0x0fedce83, 0x878ddada, 0xf2a279c7, 0x94e01be8, 0x90716f4b, 0x954b8aa3);
sBox[7] = new Array(
0xe216300d, 0xbbddfffc, 0xa7ebdabd, 0x35648095, 0x7789f8b7, 0xe6c1121b, 0x0e241600, 0x052ce8b5,
0x11a9cfb0, 0xe5952f11, 0xece7990a, 0x9386d174, 0x2a42931c, 0x76e38111, 0xb12def3a, 0x37ddddfc,
0xde9adeb1, 0x0a0cc32c, 0xbe197029, 0x84a00940, 0xbb243a0f, 0xb4d137cf, 0xb44e79f0, 0x049eedfd,
0x0b15a15d, 0x480d3168, 0x8bbbde5a, 0x669ded42, 0xc7ece831, 0x3f8f95e7, 0x72df191b, 0x7580330d,
0x94074251, 0x5c7dcdfa, 0xabbe6d63, 0xaa402164, 0xb301d40a, 0x02e7d1ca, 0x53571dae, 0x7a3182a2,
0x12a8ddec, 0xfdaa335d, 0x176f43e8, 0x71fb46d4, 0x38129022, 0xce949ad4, 0xb84769ad, 0x965bd862,
0x82f3d055, 0x66fb9767, 0x15b80b4e, 0x1d5b47a0, 0x4cfde06f, 0xc28ec4b8, 0x57e8726e, 0x647a78fc,
0x99865d44, 0x608bd593, 0x6c200e03, 0x39dc5ff6, 0x5d0b00a3, 0xae63aff2, 0x7e8bd632, 0x70108c0c,
0xbbd35049, 0x2998df04, 0x980cf42a, 0x9b6df491, 0x9e7edd53, 0x06918548, 0x58cb7e07, 0x3b74ef2e,
0x522fffb1, 0xd24708cc, 0x1c7e27cd, 0xa4eb215b, 0x3cf1d2e2, 0x19b47a38, 0x424f7618, 0x35856039,
0x9d17dee7, 0x27eb35e6, 0xc9aff67b, 0x36baf5b8, 0x09c467cd, 0xc18910b1, 0xe11dbf7b, 0x06cd1af8,
0x7170c608, 0x2d5e3354, 0xd4de495a, 0x64c6d006, 0xbcc0c62c, 0x3dd00db3, 0x708f8f34, 0x77d51b42,
0x264f620f, 0x24b8d2bf, 0x15c1b79e, 0x46a52564, 0xf8d7e54e, 0x3e378160, 0x7895cda5, 0x859c15a5,
0xe6459788, 0xc37bc75f, 0xdb07ba0c, 0x0676a3ab, 0x7f229b1e, 0x31842e7b, 0x24259fd7, 0xf8bef472,
0x835ffcb8, 0x6df4c1f2, 0x96f5b195, 0xfd0af0fc, 0xb0fe134c, 0xe2506d3d, 0x4f9b12ea, 0xf215f225,
0xa223736f, 0x9fb4c428, 0x25d04979, 0x34c713f8, 0xc4618187, 0xea7a6e98, 0x7cd16efc, 0x1436876c,
0xf1544107, 0xbedeee14, 0x56e9af27, 0xa04aa441, 0x3cf7c899, 0x92ecbae6, 0xdd67016d, 0x151682eb,
0xa842eedf, 0xfdba60b4, 0xf1907b75, 0x20e3030f, 0x24d8c29e, 0xe139673b, 0xefa63fb8, 0x71873054,
0xb6f2cf3b, 0x9f326442, 0xcb15a4cc, 0xb01a4504, 0xf1e47d8d, 0x844a1be5, 0xbae7dfdc, 0x42cbda70,
0xcd7dae0a, 0x57e85b7a, 0xd53f5af6, 0x20cf4d8c, 0xcea4d428, 0x79d130a4, 0x3486ebfb, 0x33d3cddc,
0x77853b53, 0x37effcb5, 0xc5068778, 0xe580b3e6, 0x4e68b8f4, 0xc5c8b37e, 0x0d809ea2, 0x398feb7c,
0x132a4f94, 0x43b7950e, 0x2fee7d1c, 0x223613bd, 0xdd06caa2, 0x37df932b, 0xc4248289, 0xacf3ebc3,
0x5715f6b7, 0xef3478dd, 0xf267616f, 0xc148cbe4, 0x9052815e, 0x5e410fab, 0xb48a2465, 0x2eda7fa4,
0xe87b40e4, 0xe98ea084, 0x5889e9e1, 0xefd390fc, 0xdd07d35b, 0xdb485694, 0x38d7e5b2, 0x57720101,
0x730edebc, 0x5b643113, 0x94917e4f, 0x503c2fba, 0x646f1282, 0x7523d24a, 0xe0779695, 0xf9c17a8f,
0x7a5b2121, 0xd187b896, 0x29263a4d, 0xba510cdf, 0x81f47c9f, 0xad1163ed, 0xea7b5965, 0x1a00726e,
0x11403092, 0x00da6d77, 0x4a0cdd61, 0xad1f4603, 0x605bdfb0, 0x9eedc364, 0x22ebe6a8, 0xcee7d28a,
0xa0e736a0, 0x5564a6b9, 0x10853209, 0xc7eb8f37, 0x2de705ca, 0x8951570f, 0xdf09822b, 0xbd691a6c,
0xaa12e4f2, 0x87451c0f, 0xe0f6a27a, 0x3ada4819, 0x4cf1764f, 0x0d771c2b, 0x67cdb156, 0x350d8384,
0x5938fa0f, 0x42399ef3, 0x36997b07, 0x0e84093d, 0x4aa93e61, 0x8360d87b, 0x1fa98b0c, 0x1149382c,
0xe97625a5, 0x0614d1b7, 0x0e25244b, 0x0c768347, 0x589e8d82, 0x0d2059d1, 0xa466bb1e, 0xf8da0a82,
0x04f19130, 0xba6e4ec0, 0x99265164, 0x1ee7230d, 0x50b2ad80, 0xeaee6801, 0x8db2a283, 0xea8bf59e);
}
export default function Cast5(key) {
this.cast5 = new OpenpgpSymencCast5();
this.cast5.setKey(key);
this.encrypt = function(block) {
return this.cast5.encrypt(block);
};
}
Cast5.blockSize = Cast5.prototype.blockSize = 8;
Cast5.keySize = Cast5.prototype.keySize = 16;

View file

@ -1,430 +0,0 @@
//Paul Tero, July 2001
//http://www.tero.co.uk/des/
//
//Optimised for performance with large blocks by Michael Hayworth, November 2001
//http://www.netdealing.com
//
// Modified by Recurity Labs GmbH
//THIS SOFTWARE IS PROVIDED "AS IS" AND
//ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
//IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
//ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
//FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
//DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
//OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
//HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
//LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
//OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
//SUCH DAMAGE.
//des
//this takes the key, the message, and whether to encrypt or decrypt
/**
* @module crypto/cipher/des
*/
'use strict';
function des(keys, message, encrypt, mode, iv, padding) {
//declaring this locally speeds things up a bit
var spfunction1 = new Array(0x1010400, 0, 0x10000, 0x1010404, 0x1010004, 0x10404, 0x4, 0x10000, 0x400, 0x1010400,
0x1010404, 0x400, 0x1000404, 0x1010004, 0x1000000, 0x4, 0x404, 0x1000400, 0x1000400, 0x10400, 0x10400, 0x1010000,
0x1010000, 0x1000404, 0x10004, 0x1000004, 0x1000004, 0x10004, 0, 0x404, 0x10404, 0x1000000, 0x10000, 0x1010404, 0x4,
0x1010000, 0x1010400, 0x1000000, 0x1000000, 0x400, 0x1010004, 0x10000, 0x10400, 0x1000004, 0x400, 0x4, 0x1000404,
0x10404, 0x1010404, 0x10004, 0x1010000, 0x1000404, 0x1000004, 0x404, 0x10404, 0x1010400, 0x404, 0x1000400,
0x1000400, 0, 0x10004, 0x10400, 0, 0x1010004);
var spfunction2 = new Array(-0x7fef7fe0, -0x7fff8000, 0x8000, 0x108020, 0x100000, 0x20, -0x7fefffe0, -0x7fff7fe0, -
0x7fffffe0, -0x7fef7fe0, -0x7fef8000, -0x80000000, -0x7fff8000, 0x100000, 0x20, -0x7fefffe0, 0x108000, 0x100020, -
0x7fff7fe0, 0, -0x80000000, 0x8000, 0x108020, -0x7ff00000, 0x100020, -0x7fffffe0, 0, 0x108000, 0x8020, -0x7fef8000, -
0x7ff00000, 0x8020, 0, 0x108020, -0x7fefffe0, 0x100000, -0x7fff7fe0, -0x7ff00000, -0x7fef8000, 0x8000, -0x7ff00000, -
0x7fff8000, 0x20, -0x7fef7fe0, 0x108020, 0x20, 0x8000, -0x80000000, 0x8020, -0x7fef8000, 0x100000, -0x7fffffe0,
0x100020, -0x7fff7fe0, -0x7fffffe0, 0x100020, 0x108000, 0, -0x7fff8000, 0x8020, -0x80000000, -0x7fefffe0, -
0x7fef7fe0, 0x108000);
var spfunction3 = new Array(0x208, 0x8020200, 0, 0x8020008, 0x8000200, 0, 0x20208, 0x8000200, 0x20008, 0x8000008,
0x8000008, 0x20000, 0x8020208, 0x20008, 0x8020000, 0x208, 0x8000000, 0x8, 0x8020200, 0x200, 0x20200, 0x8020000,
0x8020008, 0x20208, 0x8000208, 0x20200, 0x20000, 0x8000208, 0x8, 0x8020208, 0x200, 0x8000000, 0x8020200, 0x8000000,
0x20008, 0x208, 0x20000, 0x8020200, 0x8000200, 0, 0x200, 0x20008, 0x8020208, 0x8000200, 0x8000008, 0x200, 0,
0x8020008, 0x8000208, 0x20000, 0x8000000, 0x8020208, 0x8, 0x20208, 0x20200, 0x8000008, 0x8020000, 0x8000208, 0x208,
0x8020000, 0x20208, 0x8, 0x8020008, 0x20200);
var spfunction4 = new Array(0x802001, 0x2081, 0x2081, 0x80, 0x802080, 0x800081, 0x800001, 0x2001, 0, 0x802000,
0x802000, 0x802081, 0x81, 0, 0x800080, 0x800001, 0x1, 0x2000, 0x800000, 0x802001, 0x80, 0x800000, 0x2001, 0x2080,
0x800081, 0x1, 0x2080, 0x800080, 0x2000, 0x802080, 0x802081, 0x81, 0x800080, 0x800001, 0x802000, 0x802081, 0x81, 0,
0, 0x802000, 0x2080, 0x800080, 0x800081, 0x1, 0x802001, 0x2081, 0x2081, 0x80, 0x802081, 0x81, 0x1, 0x2000, 0x800001,
0x2001, 0x802080, 0x800081, 0x2001, 0x2080, 0x800000, 0x802001, 0x80, 0x800000, 0x2000, 0x802080);
var spfunction5 = new Array(0x100, 0x2080100, 0x2080000, 0x42000100, 0x80000, 0x100, 0x40000000, 0x2080000,
0x40080100, 0x80000, 0x2000100, 0x40080100, 0x42000100, 0x42080000, 0x80100, 0x40000000, 0x2000000, 0x40080000,
0x40080000, 0, 0x40000100, 0x42080100, 0x42080100, 0x2000100, 0x42080000, 0x40000100, 0, 0x42000000, 0x2080100,
0x2000000, 0x42000000, 0x80100, 0x80000, 0x42000100, 0x100, 0x2000000, 0x40000000, 0x2080000, 0x42000100,
0x40080100, 0x2000100, 0x40000000, 0x42080000, 0x2080100, 0x40080100, 0x100, 0x2000000, 0x42080000, 0x42080100,
0x80100, 0x42000000, 0x42080100, 0x2080000, 0, 0x40080000, 0x42000000, 0x80100, 0x2000100, 0x40000100, 0x80000, 0,
0x40080000, 0x2080100, 0x40000100);
var spfunction6 = new Array(0x20000010, 0x20400000, 0x4000, 0x20404010, 0x20400000, 0x10, 0x20404010, 0x400000,
0x20004000, 0x404010, 0x400000, 0x20000010, 0x400010, 0x20004000, 0x20000000, 0x4010, 0, 0x400010, 0x20004010,
0x4000, 0x404000, 0x20004010, 0x10, 0x20400010, 0x20400010, 0, 0x404010, 0x20404000, 0x4010, 0x404000, 0x20404000,
0x20000000, 0x20004000, 0x10, 0x20400010, 0x404000, 0x20404010, 0x400000, 0x4010, 0x20000010, 0x400000, 0x20004000,
0x20000000, 0x4010, 0x20000010, 0x20404010, 0x404000, 0x20400000, 0x404010, 0x20404000, 0, 0x20400010, 0x10, 0x4000,
0x20400000, 0x404010, 0x4000, 0x400010, 0x20004010, 0, 0x20404000, 0x20000000, 0x400010, 0x20004010);
var spfunction7 = new Array(0x200000, 0x4200002, 0x4000802, 0, 0x800, 0x4000802, 0x200802, 0x4200800, 0x4200802,
0x200000, 0, 0x4000002, 0x2, 0x4000000, 0x4200002, 0x802, 0x4000800, 0x200802, 0x200002, 0x4000800, 0x4000002,
0x4200000, 0x4200800, 0x200002, 0x4200000, 0x800, 0x802, 0x4200802, 0x200800, 0x2, 0x4000000, 0x200800, 0x4000000,
0x200800, 0x200000, 0x4000802, 0x4000802, 0x4200002, 0x4200002, 0x2, 0x200002, 0x4000000, 0x4000800, 0x200000,
0x4200800, 0x802, 0x200802, 0x4200800, 0x802, 0x4000002, 0x4200802, 0x4200000, 0x200800, 0, 0x2, 0x4200802, 0,
0x200802, 0x4200000, 0x800, 0x4000002, 0x4000800, 0x800, 0x200002);
var spfunction8 = new Array(0x10001040, 0x1000, 0x40000, 0x10041040, 0x10000000, 0x10001040, 0x40, 0x10000000,
0x40040, 0x10040000, 0x10041040, 0x41000, 0x10041000, 0x41040, 0x1000, 0x40, 0x10040000, 0x10000040, 0x10001000,
0x1040, 0x41000, 0x40040, 0x10040040, 0x10041000, 0x1040, 0, 0, 0x10040040, 0x10000040, 0x10001000, 0x41040,
0x40000, 0x41040, 0x40000, 0x10041000, 0x1000, 0x40, 0x10040040, 0x1000, 0x41040, 0x10001000, 0x40, 0x10000040,
0x10040000, 0x10040040, 0x10000000, 0x40000, 0x10001040, 0, 0x10041040, 0x40040, 0x10000040, 0x10040000, 0x10001000,
0x10001040, 0, 0x10041040, 0x41000, 0x41000, 0x1040, 0x1040, 0x40040, 0x10000000, 0x10041000);
//create the 16 or 48 subkeys we will need
var m = 0,
i, j, temp, right1, right2, left, right, looping;
var cbcleft, cbcleft2, cbcright, cbcright2;
var endloop, loopinc;
var len = message.length;
//set up the loops for single and triple des
var iterations = keys.length === 32 ? 3 : 9; //single or triple des
if (iterations === 3) {
looping = encrypt ? new Array(0, 32, 2) : new Array(30, -2, -2);
} else {
looping = encrypt ? new Array(0, 32, 2, 62, 30, -2, 64, 96, 2) : new Array(94, 62, -2, 32, 64, 2, 30, -2, -2);
}
//pad the message depending on the padding parameter
//only add padding if encrypting - note that you need to use the same padding option for both encrypt and decrypt
if (encrypt) {
message = des_addPadding(message, padding);
len = message.length;
}
//store the result here
var result = new Uint8Array(len);
var k = 0;
if (mode === 1) { //CBC mode
cbcleft = (iv[m++] << 24) | (iv[m++] << 16) | (iv[m++] << 8) | iv[m++];
cbcright = (iv[m++] << 24) | (iv[m++] << 16) | (iv[m++] << 8) | iv[m++];
m = 0;
}
//loop through each 64 bit chunk of the message
while (m < len) {
left = (message[m++] << 24) | (message[m++] << 16) | (message[m++] << 8) | message[m++];
right = (message[m++] << 24) | (message[m++] << 16) | (message[m++] << 8) | message[m++];
//for Cipher Block Chaining mode, xor the message with the previous result
if (mode === 1) {
if (encrypt) {
left ^= cbcleft;
right ^= cbcright;
} else {
cbcleft2 = cbcleft;
cbcright2 = cbcright;
cbcleft = left;
cbcright = right;
}
}
//first each 64 but chunk of the message must be permuted according to IP
temp = ((left >>> 4) ^ right) & 0x0f0f0f0f;
right ^= temp;
left ^= (temp << 4);
temp = ((left >>> 16) ^ right) & 0x0000ffff;
right ^= temp;
left ^= (temp << 16);
temp = ((right >>> 2) ^ left) & 0x33333333;
left ^= temp;
right ^= (temp << 2);
temp = ((right >>> 8) ^ left) & 0x00ff00ff;
left ^= temp;
right ^= (temp << 8);
temp = ((left >>> 1) ^ right) & 0x55555555;
right ^= temp;
left ^= (temp << 1);
left = ((left << 1) | (left >>> 31));
right = ((right << 1) | (right >>> 31));
//do this either 1 or 3 times for each chunk of the message
for (j = 0; j < iterations; j += 3) {
endloop = looping[j + 1];
loopinc = looping[j + 2];
//now go through and perform the encryption or decryption
for (i = looping[j]; i !== endloop; i += loopinc) { //for efficiency
right1 = right ^ keys[i];
right2 = ((right >>> 4) | (right << 28)) ^ keys[i + 1];
//the result is attained by passing these bytes through the S selection functions
temp = left;
left = right;
right = temp ^ (spfunction2[(right1 >>> 24) & 0x3f] | spfunction4[(right1 >>> 16) & 0x3f] | spfunction6[(right1 >>>
8) & 0x3f] | spfunction8[right1 & 0x3f] | spfunction1[(right2 >>> 24) & 0x3f] | spfunction3[(right2 >>> 16) &
0x3f] | spfunction5[(right2 >>> 8) & 0x3f] | spfunction7[right2 & 0x3f]);
}
temp = left;
left = right;
right = temp; //unreverse left and right
} //for either 1 or 3 iterations
//move then each one bit to the right
left = ((left >>> 1) | (left << 31));
right = ((right >>> 1) | (right << 31));
//now perform IP-1, which is IP in the opposite direction
temp = ((left >>> 1) ^ right) & 0x55555555;
right ^= temp;
left ^= (temp << 1);
temp = ((right >>> 8) ^ left) & 0x00ff00ff;
left ^= temp;
right ^= (temp << 8);
temp = ((right >>> 2) ^ left) & 0x33333333;
left ^= temp;
right ^= (temp << 2);
temp = ((left >>> 16) ^ right) & 0x0000ffff;
right ^= temp;
left ^= (temp << 16);
temp = ((left >>> 4) ^ right) & 0x0f0f0f0f;
right ^= temp;
left ^= (temp << 4);
//for Cipher Block Chaining mode, xor the message with the previous result
if (mode === 1) {
if (encrypt) {
cbcleft = left;
cbcright = right;
} else {
left ^= cbcleft2;
right ^= cbcright2;
}
}
result[k++] = (left >>> 24);
result[k++] = ((left >>> 16) & 0xff);
result[k++] = ((left >>> 8) & 0xff);
result[k++] = (left & 0xff);
result[k++] = (right >>> 24);
result[k++] = ((right >>> 16) & 0xff);
result[k++] = ((right >>> 8) & 0xff);
result[k++] = (right & 0xff);
} //for every 8 characters, or 64 bits in the message
//only remove padding if decrypting - note that you need to use the same padding option for both encrypt and decrypt
if (!encrypt) {
result = des_removePadding(result, padding);
}
return result;
} //end of des
//des_createKeys
//this takes as input a 64 bit key (even though only 56 bits are used)
//as an array of 2 integers, and returns 16 48 bit keys
function des_createKeys(key) {
//declaring this locally speeds things up a bit
var pc2bytes0 = new Array(0, 0x4, 0x20000000, 0x20000004, 0x10000, 0x10004, 0x20010000, 0x20010004, 0x200, 0x204,
0x20000200, 0x20000204, 0x10200, 0x10204, 0x20010200, 0x20010204);
var pc2bytes1 = new Array(0, 0x1, 0x100000, 0x100001, 0x4000000, 0x4000001, 0x4100000, 0x4100001, 0x100, 0x101, 0x100100,
0x100101, 0x4000100, 0x4000101, 0x4100100, 0x4100101);
var pc2bytes2 = new Array(0, 0x8, 0x800, 0x808, 0x1000000, 0x1000008, 0x1000800, 0x1000808, 0, 0x8, 0x800, 0x808,
0x1000000, 0x1000008, 0x1000800, 0x1000808);
var pc2bytes3 = new Array(0, 0x200000, 0x8000000, 0x8200000, 0x2000, 0x202000, 0x8002000, 0x8202000, 0x20000, 0x220000,
0x8020000, 0x8220000, 0x22000, 0x222000, 0x8022000, 0x8222000);
var pc2bytes4 = new Array(0, 0x40000, 0x10, 0x40010, 0, 0x40000, 0x10, 0x40010, 0x1000, 0x41000, 0x1010, 0x41010, 0x1000,
0x41000, 0x1010, 0x41010);
var pc2bytes5 = new Array(0, 0x400, 0x20, 0x420, 0, 0x400, 0x20, 0x420, 0x2000000, 0x2000400, 0x2000020, 0x2000420,
0x2000000, 0x2000400, 0x2000020, 0x2000420);
var pc2bytes6 = new Array(0, 0x10000000, 0x80000, 0x10080000, 0x2, 0x10000002, 0x80002, 0x10080002, 0, 0x10000000,
0x80000, 0x10080000, 0x2, 0x10000002, 0x80002, 0x10080002);
var pc2bytes7 = new Array(0, 0x10000, 0x800, 0x10800, 0x20000000, 0x20010000, 0x20000800, 0x20010800, 0x20000, 0x30000,
0x20800, 0x30800, 0x20020000, 0x20030000, 0x20020800, 0x20030800);
var pc2bytes8 = new Array(0, 0x40000, 0, 0x40000, 0x2, 0x40002, 0x2, 0x40002, 0x2000000, 0x2040000, 0x2000000, 0x2040000,
0x2000002, 0x2040002, 0x2000002, 0x2040002);
var pc2bytes9 = new Array(0, 0x10000000, 0x8, 0x10000008, 0, 0x10000000, 0x8, 0x10000008, 0x400, 0x10000400, 0x408,
0x10000408, 0x400, 0x10000400, 0x408, 0x10000408);
var pc2bytes10 = new Array(0, 0x20, 0, 0x20, 0x100000, 0x100020, 0x100000, 0x100020, 0x2000, 0x2020, 0x2000, 0x2020,
0x102000, 0x102020, 0x102000, 0x102020);
var pc2bytes11 = new Array(0, 0x1000000, 0x200, 0x1000200, 0x200000, 0x1200000, 0x200200, 0x1200200, 0x4000000, 0x5000000,
0x4000200, 0x5000200, 0x4200000, 0x5200000, 0x4200200, 0x5200200);
var pc2bytes12 = new Array(0, 0x1000, 0x8000000, 0x8001000, 0x80000, 0x81000, 0x8080000, 0x8081000, 0x10, 0x1010,
0x8000010, 0x8001010, 0x80010, 0x81010, 0x8080010, 0x8081010);
var pc2bytes13 = new Array(0, 0x4, 0x100, 0x104, 0, 0x4, 0x100, 0x104, 0x1, 0x5, 0x101, 0x105, 0x1, 0x5, 0x101, 0x105);
//how many iterations (1 for des, 3 for triple des)
var iterations = key.length > 8 ? 3 : 1; //changed by Paul 16/6/2007 to use Triple DES for 9+ byte keys
//stores the return keys
var keys = new Array(32 * iterations);
//now define the left shifts which need to be done
var shifts = new Array(0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0);
//other variables
var lefttemp, righttemp, m = 0,
n = 0,
temp;
for (var j = 0; j < iterations; j++) { //either 1 or 3 iterations
var left = (key[m++] << 24) | (key[m++] << 16) | (key[m++] << 8) | key[m++];
var right = (key[m++] << 24) | (key[m++] << 16) | (key[m++] << 8) | key[m++];
temp = ((left >>> 4) ^ right) & 0x0f0f0f0f;
right ^= temp;
left ^= (temp << 4);
temp = ((right >>> -16) ^ left) & 0x0000ffff;
left ^= temp;
right ^= (temp << -16);
temp = ((left >>> 2) ^ right) & 0x33333333;
right ^= temp;
left ^= (temp << 2);
temp = ((right >>> -16) ^ left) & 0x0000ffff;
left ^= temp;
right ^= (temp << -16);
temp = ((left >>> 1) ^ right) & 0x55555555;
right ^= temp;
left ^= (temp << 1);
temp = ((right >>> 8) ^ left) & 0x00ff00ff;
left ^= temp;
right ^= (temp << 8);
temp = ((left >>> 1) ^ right) & 0x55555555;
right ^= temp;
left ^= (temp << 1);
//the right side needs to be shifted and to get the last four bits of the left side
temp = (left << 8) | ((right >>> 20) & 0x000000f0);
//left needs to be put upside down
left = (right << 24) | ((right << 8) & 0xff0000) | ((right >>> 8) & 0xff00) | ((right >>> 24) & 0xf0);
right = temp;
//now go through and perform these shifts on the left and right keys
for (var i = 0; i < shifts.length; i++) {
//shift the keys either one or two bits to the left
if (shifts[i]) {
left = (left << 2) | (left >>> 26);
right = (right << 2) | (right >>> 26);
} else {
left = (left << 1) | (left >>> 27);
right = (right << 1) | (right >>> 27);
}
left &= -0xf;
right &= -0xf;
//now apply PC-2, in such a way that E is easier when encrypting or decrypting
//this conversion will look like PC-2 except only the last 6 bits of each byte are used
//rather than 48 consecutive bits and the order of lines will be according to
//how the S selection functions will be applied: S2, S4, S6, S8, S1, S3, S5, S7
lefttemp = pc2bytes0[left >>> 28] | pc2bytes1[(left >>> 24) & 0xf] | pc2bytes2[(left >>> 20) & 0xf] | pc2bytes3[(
left >>> 16) & 0xf] | pc2bytes4[(left >>> 12) & 0xf] | pc2bytes5[(left >>> 8) & 0xf] | pc2bytes6[(left >>> 4) &
0xf];
righttemp = pc2bytes7[right >>> 28] | pc2bytes8[(right >>> 24) & 0xf] | pc2bytes9[(right >>> 20) & 0xf] |
pc2bytes10[(right >>> 16) & 0xf] | pc2bytes11[(right >>> 12) & 0xf] | pc2bytes12[(right >>> 8) & 0xf] |
pc2bytes13[(right >>> 4) & 0xf];
temp = ((righttemp >>> 16) ^ lefttemp) & 0x0000ffff;
keys[n++] = lefttemp ^ temp;
keys[n++] = righttemp ^ (temp << 16);
}
} //for each iterations
//return the keys we've created
return keys;
} //end of des_createKeys
function des_addPadding(message, padding) {
var padLength = 8 - (message.length % 8);
var pad;
if (padding === 2 && (padLength < 8)) { //pad the message with spaces
pad = " ".charCodeAt(0);
} else if (padding === 1) { //PKCS7 padding
pad = padLength;
} else if (!padding && (padLength < 8)) { //pad the message out with null bytes
pad = 0;
} else if (padLength === 8) {
return message;
}
else {
throw new Error('des: invalid padding');
}
var paddedMessage = new Uint8Array(message.length + padLength);
for(var i = 0; i < message.length; i++) {
paddedMessage[i] = message[i];
}
for(var j = 0; j < padLength; j++) {
paddedMessage[message.length + j] = pad;
}
return paddedMessage;
}
function des_removePadding(message, padding) {
var padLength = null;
var pad;
if (padding === 2) { // space padded
pad = " ".charCodeAt(0);
} else if (padding === 1) { // PKCS7
padLength = message[message.length - 1];
} else if (!padding) { // null padding
pad = 0;
}
else {
throw new Error('des: invalid padding');
}
if(!padLength) {
padLength = 1;
while(message[message.length - padLength] === pad) {
padLength++;
}
padLength--;
}
return message.subarray(0, message.length - padLength);
}
// added by Recurity Labs
function Des(key) {
this.key = [];
for (var i = 0; i < 3; i++) {
this.key.push(new Uint8Array(key.subarray(i * 8, (i * 8) + 8)));
}
this.encrypt = function(block) {
return des(des_createKeys(this.key[2]),
des(des_createKeys(this.key[1]),
des(des_createKeys(this.key[0]),
block, true, 0, null, null),
false, 0, null, null), true, 0, null, null);
};
}
Des.keySize = Des.prototype.keySize = 24;
Des.blockSize = Des.prototype.blockSize = 8;
// This is "original" DES - Des is actually Triple DES.
// This is only exported so we can unit test.
function OriginalDes(key) {
this.key = key;
this.encrypt = function(block, padding) {
var keys = des_createKeys(this.key);
return des(keys, block, true, 0, null, padding);
};
this.decrypt = function(block, padding) {
var keys = des_createKeys(this.key);
return des(keys, block, false, 0, null, padding);
};
}
export default {
/** @static */
des: Des,
/** @static */
originalDes: OriginalDes
};

View file

@ -1,36 +0,0 @@
/**
* @requires crypto/cipher/aes
* @requires crypto/cipher/blowfish
* @requires crypto/cipher/cast5
* @requires crypto/cipher/twofish
* @module crypto/cipher
*/
'use strict';
import aes from'./aes.js';
import desModule from './des.js';
import cast5 from './cast5.js';
import twofish from './twofish.js';
import blowfish from './blowfish.js';
export default {
/** @see module:crypto/cipher/aes */
aes128: aes[128],
aes192: aes[192],
aes256: aes[256],
/** @see module:crypto/cipher/des.originalDes */
des: desModule.originalDes,
/** @see module:crypto/cipher/des.des */
tripledes: desModule.des,
/** @see module:crypto/cipher/cast5 */
cast5: cast5,
/** @see module:crypto/cipher/twofish */
twofish: twofish,
/** @see module:crypto/cipher/blowfish */
blowfish: blowfish,
/** Not implemented */
idea: function() {
throw new Error('IDEA symmetric-key algorithm not implemented');
}
};

View file

@ -1,351 +0,0 @@
/* Modified by Recurity Labs GmbH
*
* Cipher.js
* A block-cipher algorithm implementation on JavaScript
* See Cipher.readme.txt for further information.
*
* Copyright(c) 2009 Atsushi Oka [ http://oka.nu/ ]
* This script file is distributed under the LGPL
*
* ACKNOWLEDGMENT
*
* The main subroutines are written by Michiel van Everdingen.
*
* Michiel van Everdingen
* http://home.versatel.nl/MAvanEverdingen/index.html
*
* All rights for these routines are reserved to Michiel van Everdingen.
*
*/
/**
* @module crypto/cipher/twofish
*/
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//Math
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
var MAXINT = 0xFFFFFFFF;
function rotw(w, n) {
return (w << n | w >>> (32 - n)) & MAXINT;
}
function getW(a, i) {
return a[i] | a[i + 1] << 8 | a[i + 2] << 16 | a[i + 3] << 24;
}
function setW(a, i, w) {
a.splice(i, 4, w & 0xFF, (w >>> 8) & 0xFF, (w >>> 16) & 0xFF, (w >>> 24) & 0xFF);
}
function getB(x, n) {
return (x >>> (n * 8)) & 0xFF;
}
// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Twofish
// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function createTwofish() {
//
var keyBytes = null;
var dataBytes = null;
var dataOffset = -1;
// var dataLength = -1;
var algorithmName = null;
// var idx2 = -1;
//
algorithmName = "twofish";
var tfsKey = [];
var tfsM = [
[],
[],
[],
[]
];
function tfsInit(key) {
keyBytes = key;
var i, a, b, c, d, meKey = [],
moKey = [],
inKey = [];
var kLen;
var sKey = [];
var f01, f5b, fef;
var q0 = [
[8, 1, 7, 13, 6, 15, 3, 2, 0, 11, 5, 9, 14, 12, 10, 4],
[2, 8, 11, 13, 15, 7, 6, 14, 3, 1, 9, 4, 0, 10, 12, 5]
];
var q1 = [
[14, 12, 11, 8, 1, 2, 3, 5, 15, 4, 10, 6, 7, 0, 9, 13],
[1, 14, 2, 11, 4, 12, 3, 7, 6, 13, 10, 5, 15, 9, 0, 8]
];
var q2 = [
[11, 10, 5, 14, 6, 13, 9, 0, 12, 8, 15, 3, 2, 4, 7, 1],
[4, 12, 7, 5, 1, 6, 9, 10, 0, 14, 13, 8, 2, 11, 3, 15]
];
var q3 = [
[13, 7, 15, 4, 1, 2, 6, 14, 9, 11, 3, 0, 8, 5, 12, 10],
[11, 9, 5, 1, 12, 3, 13, 14, 6, 4, 7, 15, 2, 0, 8, 10]
];
var ror4 = [0, 8, 1, 9, 2, 10, 3, 11, 4, 12, 5, 13, 6, 14, 7, 15];
var ashx = [0, 9, 2, 11, 4, 13, 6, 15, 8, 1, 10, 3, 12, 5, 14, 7];
var q = [
[],
[]
];
var m = [
[],
[],
[],
[]
];
function ffm5b(x) {
return x ^ (x >> 2) ^ [0, 90, 180, 238][x & 3];
}
function ffmEf(x) {
return x ^ (x >> 1) ^ (x >> 2) ^ [0, 238, 180, 90][x & 3];
}
function mdsRem(p, q) {
var i, t, u;
for (i = 0; i < 8; i++) {
t = q >>> 24;
q = ((q << 8) & MAXINT) | p >>> 24;
p = (p << 8) & MAXINT;
u = t << 1;
if (t & 128) {
u ^= 333;
}
q ^= t ^ (u << 16);
u ^= t >>> 1;
if (t & 1) {
u ^= 166;
}
q ^= u << 24 | u << 8;
}
return q;
}
function qp(n, x) {
var a, b, c, d;
a = x >> 4;
b = x & 15;
c = q0[n][a ^ b];
d = q1[n][ror4[b] ^ ashx[a]];
return q3[n][ror4[d] ^ ashx[c]] << 4 | q2[n][c ^ d];
}
function hFun(x, key) {
var a = getB(x, 0),
b = getB(x, 1),
c = getB(x, 2),
d = getB(x, 3);
switch (kLen) {
case 4:
a = q[1][a] ^ getB(key[3], 0);
b = q[0][b] ^ getB(key[3], 1);
c = q[0][c] ^ getB(key[3], 2);
d = q[1][d] ^ getB(key[3], 3);
case 3:
a = q[1][a] ^ getB(key[2], 0);
b = q[1][b] ^ getB(key[2], 1);
c = q[0][c] ^ getB(key[2], 2);
d = q[0][d] ^ getB(key[2], 3);
case 2:
a = q[0][q[0][a] ^ getB(key[1], 0)] ^ getB(key[0], 0);
b = q[0][q[1][b] ^ getB(key[1], 1)] ^ getB(key[0], 1);
c = q[1][q[0][c] ^ getB(key[1], 2)] ^ getB(key[0], 2);
d = q[1][q[1][d] ^ getB(key[1], 3)] ^ getB(key[0], 3);
}
return m[0][a] ^ m[1][b] ^ m[2][c] ^ m[3][d];
}
keyBytes = keyBytes.slice(0, 32);
i = keyBytes.length;
while (i !== 16 && i !== 24 && i !== 32) {
keyBytes[i++] = 0;
}
for (i = 0; i < keyBytes.length; i += 4) {
inKey[i >> 2] = getW(keyBytes, i);
}
for (i = 0; i < 256; i++) {
q[0][i] = qp(0, i);
q[1][i] = qp(1, i);
}
for (i = 0; i < 256; i++) {
f01 = q[1][i];
f5b = ffm5b(f01);
fef = ffmEf(f01);
m[0][i] = f01 + (f5b << 8) + (fef << 16) + (fef << 24);
m[2][i] = f5b + (fef << 8) + (f01 << 16) + (fef << 24);
f01 = q[0][i];
f5b = ffm5b(f01);
fef = ffmEf(f01);
m[1][i] = fef + (fef << 8) + (f5b << 16) + (f01 << 24);
m[3][i] = f5b + (f01 << 8) + (fef << 16) + (f5b << 24);
}
kLen = inKey.length / 2;
for (i = 0; i < kLen; i++) {
a = inKey[i + i];
meKey[i] = a;
b = inKey[i + i + 1];
moKey[i] = b;
sKey[kLen - i - 1] = mdsRem(a, b);
}
for (i = 0; i < 40; i += 2) {
a = 0x1010101 * i;
b = a + 0x1010101;
a = hFun(a, meKey);
b = rotw(hFun(b, moKey), 8);
tfsKey[i] = (a + b) & MAXINT;
tfsKey[i + 1] = rotw(a + 2 * b, 9);
}
for (i = 0; i < 256; i++) {
a = b = c = d = i;
switch (kLen) {
case 4:
a = q[1][a] ^ getB(sKey[3], 0);
b = q[0][b] ^ getB(sKey[3], 1);
c = q[0][c] ^ getB(sKey[3], 2);
d = q[1][d] ^ getB(sKey[3], 3);
case 3:
a = q[1][a] ^ getB(sKey[2], 0);
b = q[1][b] ^ getB(sKey[2], 1);
c = q[0][c] ^ getB(sKey[2], 2);
d = q[0][d] ^ getB(sKey[2], 3);
case 2:
tfsM[0][i] = m[0][q[0][q[0][a] ^ getB(sKey[1], 0)] ^ getB(sKey[0], 0)];
tfsM[1][i] = m[1][q[0][q[1][b] ^ getB(sKey[1], 1)] ^ getB(sKey[0], 1)];
tfsM[2][i] = m[2][q[1][q[0][c] ^ getB(sKey[1], 2)] ^ getB(sKey[0], 2)];
tfsM[3][i] = m[3][q[1][q[1][d] ^ getB(sKey[1], 3)] ^ getB(sKey[0], 3)];
}
}
}
function tfsG0(x) {
return tfsM[0][getB(x, 0)] ^ tfsM[1][getB(x, 1)] ^ tfsM[2][getB(x, 2)] ^ tfsM[3][getB(x, 3)];
}
function tfsG1(x) {
return tfsM[0][getB(x, 3)] ^ tfsM[1][getB(x, 0)] ^ tfsM[2][getB(x, 1)] ^ tfsM[3][getB(x, 2)];
}
function tfsFrnd(r, blk) {
var a = tfsG0(blk[0]);
var b = tfsG1(blk[1]);
blk[2] = rotw(blk[2] ^ (a + b + tfsKey[4 * r + 8]) & MAXINT, 31);
blk[3] = rotw(blk[3], 1) ^ (a + 2 * b + tfsKey[4 * r + 9]) & MAXINT;
a = tfsG0(blk[2]);
b = tfsG1(blk[3]);
blk[0] = rotw(blk[0] ^ (a + b + tfsKey[4 * r + 10]) & MAXINT, 31);
blk[1] = rotw(blk[1], 1) ^ (a + 2 * b + tfsKey[4 * r + 11]) & MAXINT;
}
function tfsIrnd(i, blk) {
var a = tfsG0(blk[0]);
var b = tfsG1(blk[1]);
blk[2] = rotw(blk[2], 1) ^ (a + b + tfsKey[4 * i + 10]) & MAXINT;
blk[3] = rotw(blk[3] ^ (a + 2 * b + tfsKey[4 * i + 11]) & MAXINT, 31);
a = tfsG0(blk[2]);
b = tfsG1(blk[3]);
blk[0] = rotw(blk[0], 1) ^ (a + b + tfsKey[4 * i + 8]) & MAXINT;
blk[1] = rotw(blk[1] ^ (a + 2 * b + tfsKey[4 * i + 9]) & MAXINT, 31);
}
function tfsClose() {
tfsKey = [];
tfsM = [
[],
[],
[],
[]
];
}
function tfsEncrypt(data, offset) {
dataBytes = data;
dataOffset = offset;
var blk = [getW(dataBytes, dataOffset) ^ tfsKey[0],
getW(dataBytes, dataOffset + 4) ^ tfsKey[1],
getW(dataBytes, dataOffset + 8) ^ tfsKey[2],
getW(dataBytes, dataOffset + 12) ^ tfsKey[3]
];
for (var j = 0; j < 8; j++) {
tfsFrnd(j, blk);
}
setW(dataBytes, dataOffset, blk[2] ^ tfsKey[4]);
setW(dataBytes, dataOffset + 4, blk[3] ^ tfsKey[5]);
setW(dataBytes, dataOffset + 8, blk[0] ^ tfsKey[6]);
setW(dataBytes, dataOffset + 12, blk[1] ^ tfsKey[7]);
dataOffset += 16;
return dataBytes;
}
function tfsDecrypt(data, offset) {
dataBytes = data;
dataOffset = offset;
var blk = [getW(dataBytes, dataOffset) ^ tfsKey[4],
getW(dataBytes, dataOffset + 4) ^ tfsKey[5],
getW(dataBytes, dataOffset + 8) ^ tfsKey[6],
getW(dataBytes, dataOffset + 12) ^ tfsKey[7]
];
for (var j = 7; j >= 0; j--) {
tfsIrnd(j, blk);
}
setW(dataBytes, dataOffset, blk[2] ^ tfsKey[0]);
setW(dataBytes, dataOffset + 4, blk[3] ^ tfsKey[1]);
setW(dataBytes, dataOffset + 8, blk[0] ^ tfsKey[2]);
setW(dataBytes, dataOffset + 12, blk[1] ^ tfsKey[3]);
dataOffset += 16;
}
// added by Recurity Labs
function tfsFinal() {
return dataBytes;
}
return {
name: "twofish",
blocksize: 128 / 8,
open: tfsInit,
close: tfsClose,
encrypt: tfsEncrypt,
decrypt: tfsDecrypt,
// added by Recurity Labs
finalize: tfsFinal
};
}
// added by Recurity Labs
export default function TF(key) {
this.tf = createTwofish();
this.tf.open(toArray(key), 0);
this.encrypt = function(block) {
return this.tf.encrypt(toArray(block), 0);
};
}
function toArray(typedArray) {
// Array.apply([], typedArray) does not work in PhantomJS 1.9
var result = [];
for (var i = 0; i < typedArray.length; i++) {
result[i] = typedArray[i];
}
return result;
}
TF.keySize = TF.prototype.keySize = 32;
TF.blockSize = TF.prototype.blockSize = 16;

View file

@ -1,232 +0,0 @@
// GPG4Browsers - An OpenPGP implementation in javascript
// Copyright (C) 2011 Recurity Labs GmbH
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// 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,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
// The GPG4Browsers crypto interface
/**
* @requires crypto/cipher
* @requires crypto/public_key
* @requires crypto/random
* @requires type/mpi
* @module crypto/crypto
*/
'use strict';
import random from './random.js';
import cipher from './cipher';
import publicKey from './public_key';
import type_mpi from '../type/mpi.js';
export default {
/**
* Encrypts data using the specified public key multiprecision integers
* 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 {Array<module:type/mpi>} publicMPIs Algorithm dependent multiprecision integers
* @param {module:type/mpi} data Data to be encrypted as 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
*/
publicKeyEncrypt: function(algo, publicMPIs, data) {
var result = (function() {
var m;
switch (algo) {
case 'rsa_encrypt':
case 'rsa_encrypt_sign':
var rsa = new publicKey.rsa();
var n = publicMPIs[0].toBigInteger();
var e = publicMPIs[1].toBigInteger();
m = data.toBigInteger();
return [rsa.encrypt(m, e, n)];
case 'elgamal':
var elgamal = new publicKey.elgamal();
var p = publicMPIs[0].toBigInteger();
var g = publicMPIs[1].toBigInteger();
var y = publicMPIs[2].toBigInteger();
m = data.toBigInteger();
return elgamal.encrypt(m, g, p, y);
default:
return [];
}
})();
return result.map(function(bn) {
var mpi = new type_mpi();
mpi.fromBigInteger(bn);
return mpi;
});
},
/**
* Decrypts data using the specified public key multiprecision integers of the private key,
* 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 {Array<module:type/mpi>} publicMPIs Algorithm dependent multiprecision integers
* of the public key part of the private key
* @param {Array<module:type/mpi>} secretMPIs Algorithm dependent multiprecision integers
* of the private key used
* @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
*/
publicKeyDecrypt: function(algo, keyIntegers, dataIntegers) {
var p;
var bn = (function() {
switch (algo) {
case 'rsa_encrypt_sign':
case 'rsa_encrypt':
var rsa = new publicKey.rsa();
// 0 and 1 are the public key.
var n = keyIntegers[0].toBigInteger();
var e = keyIntegers[1].toBigInteger();
// 2 to 5 are the private key.
var d = keyIntegers[2].toBigInteger();
p = keyIntegers[3].toBigInteger();
var q = keyIntegers[4].toBigInteger();
var u = keyIntegers[5].toBigInteger();
var m = dataIntegers[0].toBigInteger();
return rsa.decrypt(m, n, e, d, p, q, u);
case 'elgamal':
var elgamal = new publicKey.elgamal();
var x = keyIntegers[3].toBigInteger();
var c1 = dataIntegers[0].toBigInteger();
var c2 = dataIntegers[1].toBigInteger();
p = keyIntegers[0].toBigInteger();
return elgamal.decrypt(c1, c2, p, x);
default:
return null;
}
})();
var result = new type_mpi();
result.fromBigInteger(bn);
return result;
},
/** Returns the number of integers comprising the private key of an algorithm
* @param {String} algo The public key algorithm
* @return {Integer} The number of integers.
*/
getPrivateMpiCount: function(algo) {
switch (algo) {
case 'rsa_encrypt':
case 'rsa_encrypt_sign':
case 'rsa_sign':
// Algorithm-Specific Fields for RSA secret keys:
// - multiprecision integer (MPI) of RSA secret exponent d.
// - MPI of RSA secret prime value p.
// - MPI of RSA secret prime value q (p < q).
// - MPI of u, the multiplicative inverse of p, mod q.
return 4;
case 'elgamal':
// Algorithm-Specific Fields for Elgamal secret keys:
// - MPI of Elgamal secret exponent x.
return 1;
case 'dsa':
// Algorithm-Specific Fields for DSA secret keys:
// - MPI of DSA secret exponent x.
return 1;
default:
throw new Error('Unknown algorithm');
}
},
getPublicMpiCount: function(algo) {
// - A series of multiprecision integers comprising the key material:
// Algorithm-Specific Fields for RSA public keys:
// - a multiprecision integer (MPI) of RSA public modulus n;
// - an MPI of RSA public encryption exponent e.
switch (algo) {
case 'rsa_encrypt':
case 'rsa_encrypt_sign':
case 'rsa_sign':
return 2;
// Algorithm-Specific Fields for Elgamal public keys:
// - MPI of Elgamal prime p;
// - MPI of Elgamal group generator g;
// - MPI of Elgamal public key value y (= g**x mod p where x is secret).
case 'elgamal':
return 3;
// Algorithm-Specific Fields for DSA public keys:
// - MPI of DSA prime p;
// - MPI of DSA group order q (q is a prime divisor of p-1);
// - MPI of DSA group generator g;
// - MPI of DSA public-key value y (= g**x mod p where x is secret).
case 'dsa':
return 4;
default:
throw new Error('Unknown algorithm.');
}
},
generateMpi: function(algo, bits) {
switch (algo) {
case 'rsa_encrypt':
case 'rsa_encrypt_sign':
case 'rsa_sign':
//remember "publicKey" refers to the crypto/public_key dir
var rsa = new publicKey.rsa();
return rsa.generate(bits, "10001").then(function(keyObject) {
var output = [];
output.push(keyObject.n);
output.push(keyObject.ee);
output.push(keyObject.d);
output.push(keyObject.p);
output.push(keyObject.q);
output.push(keyObject.u);
return mapResult(output);
});
default:
throw 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;
});
}
},
/**
* generate random byte prefix as string for the specified algorithm
* @param {module:enums.symmetric} algo Algorithm to use (see {@link http://tools.ietf.org/html/rfc4880#section-9.2|RFC 4880 9.2})
* @return {Uint8Array} Random bytes with length equal to the block
* size of the cipher
*/
getPrefixRandom: function(algo) {
return random.getRandomBytes(cipher[algo].blockSize);
},
/**
* Generating a session key for the specified symmetric algorithm
* @param {module:enums.symmetric} algo Algorithm to use (see {@link http://tools.ietf.org/html/rfc4880#section-9.2|RFC 4880 9.2})
* @return {Uint8Array} Random bytes as a string to be used as a key
*/
generateSessionKey: function(algo) {
return random.getRandomBytes(cipher[algo].keySize);
}
};

View file

@ -1,91 +0,0 @@
// OpenPGP.js - An OpenPGP implementation in javascript
// Copyright (C) 2016 Tankred Hase
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// 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,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
/**
* @fileoverview This module wraps native AES-GCM en/decryption for both
* the WebCrypto api as well as node.js' crypto api.
*/
'use strict';
import util from '../util.js';
import config from '../config';
import '../asmcrypto.js';
const webCrypto = util.getWebCrypto(); // no GCM support in IE11, Safari 9
export const ivLength = 12; // size of the IV in bytes
const ALGO = 'AES-GCM';
/**
* Encrypt plaintext input.
* @param {String} cipher The symmetric cipher algorithm to use e.g. 'aes128'
* @param {Uint8Array} plaintext The cleartext input to be encrypted
* @param {Uint8Array} key The encryption key
* @param {Uint8Array} iv The initialization vector (12 bytes)
* @return {Promise<Uint8Array>} The ciphertext output
*/
export function encrypt(cipher, plaintext, key, iv) {
if (cipher.substr(0,3) !== 'aes') {
return Promise.reject(new Error('GCM mode supports only AES cipher'));
}
if (webCrypto && key.length !== 24) { // WebCrypto (no 192 bit support) see: https://www.chromium.org/blink/webcrypto#TOC-AES-support
return webEncrypt(plaintext, key, iv);
}
// asm.js fallback
return Promise.resolve(asmCrypto.AES_GCM.encrypt(plaintext, key, iv));
}
/**
* Decrypt ciphertext input.
* @param {String} cipher The symmetric cipher algorithm to use e.g. 'aes128'
* @param {Uint8Array} ciphertext The ciphertext input to be decrypted
* @param {Uint8Array} key The encryption key
* @param {Uint8Array} iv The initialization vector (12 bytes)
* @return {Promise<Uint8Array>} The plaintext output
*/
export function decrypt(cipher, ciphertext, key, iv) {
if (cipher.substr(0,3) !== 'aes') {
return Promise.reject(new Error('GCM mode supports only AES cipher'));
}
if (webCrypto && key.length !== 24) { // WebCrypto (no 192 bit support) see: https://www.chromium.org/blink/webcrypto#TOC-AES-support
return webDecrypt(ciphertext, key, iv);
}
// asm.js fallback
return Promise.resolve(asmCrypto.AES_GCM.decrypt(ciphertext, key, iv));
}
//////////////////////////
// //
// Helper functions //
// //
//////////////////////////
function webEncrypt(pt, key, iv) {
return webCrypto.importKey('raw', key, { name: ALGO }, false, ['encrypt'])
.then(keyObj => webCrypto.encrypt({ name: ALGO, iv }, keyObj, pt))
.then(ct => new Uint8Array(ct));
}
function webDecrypt(ct, key, iv) {
return webCrypto.importKey('raw', key, { name: ALGO }, false, ['decrypt'])
.then(keyObj => webCrypto.decrypt({ name: ALGO, iv }, keyObj, ct))
.then(pt => new Uint8Array(pt));
}

View file

@ -1,104 +0,0 @@
/**
* @requires crypto/hash/sha
* @requires crypto/hash/md5
* @requires crypto/hash/ripe-md
* @requires util
* @module crypto/hash
*/
'use strict';
import sha from './sha.js';
import '../../asmcrypto.js';
import '../../rusha.js';
import md5 from './md5.js';
import ripemd from './ripe-md.js';
import util from '../../util.js';
const rusha = new Rusha();
export default {
/** @see module:crypto/hash/md5 */
md5: md5,
/** @see module:rusha */
sha1: function(data) {
return util.str2Uint8Array(util.hex2bin(rusha.digest(data)));
},
/** @see module:crypto/hash/sha.sha224 */
sha224: sha.sha224,
/** @see module:asmcrypto */
sha256: asmCrypto.SHA256.bytes,
/** @see module:crypto/hash/sha.sha384 */
sha384: sha.sha384,
/** @see module:crypto/hash/sha.sha512 */
sha512: sha.sha512,
/** @see module:crypto/hash/ripe-md */
ripemd: ripemd,
/**
* Create a hash on the specified data using the specified algorithm
* @param {module:enums.hash} algo Hash algorithm type (see {@link http://tools.ietf.org/html/rfc4880#section-9.4|RFC 4880 9.4})
* @param {Uint8Array} data Data to be hashed
* @return {Uint8Array} hash value
*/
digest: function(algo, data) {
switch (algo) {
case 1:
// - MD5 [HAC]
return this.md5(data);
case 2:
// - SHA-1 [FIPS180]
return this.sha1(data);
case 3:
// - RIPE-MD/160 [HAC]
return this.ripemd(data);
case 8:
// - SHA256 [FIPS180]
return this.sha256(data);
case 9:
// - SHA384 [FIPS180]
return this.sha384(data);
case 10:
// - SHA512 [FIPS180]
return this.sha512(data);
case 11:
// - SHA224 [FIPS180]
return this.sha224(data);
default:
throw new Error('Invalid hash function.');
}
},
/**
* Returns the hash size in bytes of the specified hash algorithm type
* @param {module:enums.hash} algo Hash algorithm type (See {@link http://tools.ietf.org/html/rfc4880#section-9.4|RFC 4880 9.4})
* @return {Integer} Size in bytes of the resulting hash
*/
getHashByteLength: function(algo) {
switch (algo) {
case 1:
// - MD5 [HAC]
return 16;
case 2:
// - SHA-1 [FIPS180]
case 3:
// - RIPE-MD/160 [HAC]
return 20;
case 8:
// - SHA256 [FIPS180]
return 32;
case 9:
// - SHA384 [FIPS180]
return 48;
case 10:
// - SHA512 [FIPS180]
return 64;
case 11:
// - SHA224 [FIPS180]
return 28;
default:
throw new Error('Invalid hash algorithm.');
}
}
};

View file

@ -1,215 +0,0 @@
/**
* A fast MD5 JavaScript implementation
* Copyright (c) 2012 Joseph Myers
* http://www.myersdaily.org/joseph/javascript/md5-text.html
*
* Permission to use, copy, modify, and distribute this software
* and its documentation for any purposes and without
* fee is hereby granted provided that this copyright notice
* appears in all copies.
*
* Of course, this soft is provided "as is" without express or implied
* warranty of any kind.
*/
/**
* @requires util
* @module crypto/hash/md5
*/
'use strict';
import util from '../../util.js';
/**
* MD5 hash
* @param {String} entree string to hash
*/
export default function(entree) {
var hex = md5(util.Uint8Array2str(entree));
var bin = util.str2Uint8Array(util.hex2bin(hex));
return bin;
}
function md5cycle(x, k) {
var a = x[0],
b = x[1],
c = x[2],
d = x[3];
a = ff(a, b, c, d, k[0], 7, -680876936);
d = ff(d, a, b, c, k[1], 12, -389564586);
c = ff(c, d, a, b, k[2], 17, 606105819);
b = ff(b, c, d, a, k[3], 22, -1044525330);
a = ff(a, b, c, d, k[4], 7, -176418897);
d = ff(d, a, b, c, k[5], 12, 1200080426);
c = ff(c, d, a, b, k[6], 17, -1473231341);
b = ff(b, c, d, a, k[7], 22, -45705983);
a = ff(a, b, c, d, k[8], 7, 1770035416);
d = ff(d, a, b, c, k[9], 12, -1958414417);
c = ff(c, d, a, b, k[10], 17, -42063);
b = ff(b, c, d, a, k[11], 22, -1990404162);
a = ff(a, b, c, d, k[12], 7, 1804603682);
d = ff(d, a, b, c, k[13], 12, -40341101);
c = ff(c, d, a, b, k[14], 17, -1502002290);
b = ff(b, c, d, a, k[15], 22, 1236535329);
a = gg(a, b, c, d, k[1], 5, -165796510);
d = gg(d, a, b, c, k[6], 9, -1069501632);
c = gg(c, d, a, b, k[11], 14, 643717713);
b = gg(b, c, d, a, k[0], 20, -373897302);
a = gg(a, b, c, d, k[5], 5, -701558691);
d = gg(d, a, b, c, k[10], 9, 38016083);
c = gg(c, d, a, b, k[15], 14, -660478335);
b = gg(b, c, d, a, k[4], 20, -405537848);
a = gg(a, b, c, d, k[9], 5, 568446438);
d = gg(d, a, b, c, k[14], 9, -1019803690);
c = gg(c, d, a, b, k[3], 14, -187363961);
b = gg(b, c, d, a, k[8], 20, 1163531501);
a = gg(a, b, c, d, k[13], 5, -1444681467);
d = gg(d, a, b, c, k[2], 9, -51403784);
c = gg(c, d, a, b, k[7], 14, 1735328473);
b = gg(b, c, d, a, k[12], 20, -1926607734);
a = hh(a, b, c, d, k[5], 4, -378558);
d = hh(d, a, b, c, k[8], 11, -2022574463);
c = hh(c, d, a, b, k[11], 16, 1839030562);
b = hh(b, c, d, a, k[14], 23, -35309556);
a = hh(a, b, c, d, k[1], 4, -1530992060);
d = hh(d, a, b, c, k[4], 11, 1272893353);
c = hh(c, d, a, b, k[7], 16, -155497632);
b = hh(b, c, d, a, k[10], 23, -1094730640);
a = hh(a, b, c, d, k[13], 4, 681279174);
d = hh(d, a, b, c, k[0], 11, -358537222);
c = hh(c, d, a, b, k[3], 16, -722521979);
b = hh(b, c, d, a, k[6], 23, 76029189);
a = hh(a, b, c, d, k[9], 4, -640364487);
d = hh(d, a, b, c, k[12], 11, -421815835);
c = hh(c, d, a, b, k[15], 16, 530742520);
b = hh(b, c, d, a, k[2], 23, -995338651);
a = ii(a, b, c, d, k[0], 6, -198630844);
d = ii(d, a, b, c, k[7], 10, 1126891415);
c = ii(c, d, a, b, k[14], 15, -1416354905);
b = ii(b, c, d, a, k[5], 21, -57434055);
a = ii(a, b, c, d, k[12], 6, 1700485571);
d = ii(d, a, b, c, k[3], 10, -1894986606);
c = ii(c, d, a, b, k[10], 15, -1051523);
b = ii(b, c, d, a, k[1], 21, -2054922799);
a = ii(a, b, c, d, k[8], 6, 1873313359);
d = ii(d, a, b, c, k[15], 10, -30611744);
c = ii(c, d, a, b, k[6], 15, -1560198380);
b = ii(b, c, d, a, k[13], 21, 1309151649);
a = ii(a, b, c, d, k[4], 6, -145523070);
d = ii(d, a, b, c, k[11], 10, -1120210379);
c = ii(c, d, a, b, k[2], 15, 718787259);
b = ii(b, c, d, a, k[9], 21, -343485551);
x[0] = add32(a, x[0]);
x[1] = add32(b, x[1]);
x[2] = add32(c, x[2]);
x[3] = add32(d, x[3]);
}
function cmn(q, a, b, x, s, t) {
a = add32(add32(a, q), add32(x, t));
return add32((a << s) | (a >>> (32 - s)), b);
}
function ff(a, b, c, d, x, s, t) {
return cmn((b & c) | ((~b) & d), a, b, x, s, t);
}
function gg(a, b, c, d, x, s, t) {
return cmn((b & d) | (c & (~d)), a, b, x, s, t);
}
function hh(a, b, c, d, x, s, t) {
return cmn(b ^ c ^ d, a, b, x, s, t);
}
function ii(a, b, c, d, x, s, t) {
return cmn(c ^ (b | (~d)), a, b, x, s, t);
}
function md51(s) {
var n = s.length,
state = [1732584193, -271733879, -1732584194, 271733878],
i;
for (i = 64; i <= s.length; i += 64) {
md5cycle(state, md5blk(s.substring(i - 64, i)));
}
s = s.substring(i - 64);
var tail = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
for (i = 0; i < s.length; i++) {
tail[i >> 2] |= s.charCodeAt(i) << ((i % 4) << 3);
}
tail[i >> 2] |= 0x80 << ((i % 4) << 3);
if (i > 55) {
md5cycle(state, tail);
for (i = 0; i < 16; i++) {
tail[i] = 0;
}
}
tail[14] = n * 8;
md5cycle(state, tail);
return state;
}
/* there needs to be support for Unicode here,
* unless we pretend that we can redefine the MD-5
* algorithm for multi-byte characters (perhaps
* by adding every four 16-bit characters and
* shortening the sum to 32 bits). Otherwise
* I suggest performing MD-5 as if every character
* was two bytes--e.g., 0040 0025 = @%--but then
* how will an ordinary MD-5 sum be matched?
* There is no way to standardize text to something
* like UTF-8 before transformation; speed cost is
* utterly prohibitive. The JavaScript standard
* itself needs to look at this: it should start
* providing access to strings as preformed UTF-8
* 8-bit unsigned value arrays.
*/
function md5blk(s) { /* I figured global was faster. */
var md5blks = [],
i; /* Andy King said do it this way. */
for (i = 0; i < 64; i += 4) {
md5blks[i >> 2] = s.charCodeAt(i) + (s.charCodeAt(i + 1) << 8) + (s.charCodeAt(i + 2) << 16) + (s.charCodeAt(i + 3) <<
24);
}
return md5blks;
}
var hex_chr = '0123456789abcdef'.split('');
function rhex(n) {
var s = '',
j = 0;
for (; j < 4; j++) {
s += hex_chr[(n >> (j * 8 + 4)) & 0x0F] + hex_chr[(n >> (j * 8)) & 0x0F];
}
return s;
}
function hex(x) {
for (var i = 0; i < x.length; i++) {
x[i] = rhex(x[i]);
}
return x.join('');
}
function md5(s) {
return hex(md51(s));
}
/* this function is much faster,
so if possible we use it. Some IEs
are the only ones I know of that
need the idiotic second function,
generated by an if clause. */
function add32(a, b) {
return (a + b) & 0xFFFFFFFF;
}

View file

@ -1,301 +0,0 @@
/*
* CryptoMX Tools
* Copyright (C) 2004 - 2006 Derek Buitenhuis
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* Modified by Recurity Labs GmbH
*/
/* Modified by ProtonTech AG
*/
/**
* @requires util
* @module crypto/hash/ripe-md
*/
import util from '../../util.js';
var RMDsize = 160;
var X = [];
function ROL(x, n) {
return new Number((x << n) | (x >>> (32 - n)));
}
function F(x, y, z) {
return new Number(x ^ y ^ z);
}
function G(x, y, z) {
return new Number((x & y) | (~x & z));
}
function H(x, y, z) {
return new Number((x | ~y) ^ z);
}
function I(x, y, z) {
return new Number((x & z) | (y & ~z));
}
function J(x, y, z) {
return new Number(x ^ (y | ~z));
}
function mixOneRound(a, b, c, d, e, x, s, roundNumber) {
switch (roundNumber) {
case 0:
a += F(b, c, d) + x + 0x00000000;
break;
case 1:
a += G(b, c, d) + x + 0x5a827999;
break;
case 2:
a += H(b, c, d) + x + 0x6ed9eba1;
break;
case 3:
a += I(b, c, d) + x + 0x8f1bbcdc;
break;
case 4:
a += J(b, c, d) + x + 0xa953fd4e;
break;
case 5:
a += J(b, c, d) + x + 0x50a28be6;
break;
case 6:
a += I(b, c, d) + x + 0x5c4dd124;
break;
case 7:
a += H(b, c, d) + x + 0x6d703ef3;
break;
case 8:
a += G(b, c, d) + x + 0x7a6d76e9;
break;
case 9:
a += F(b, c, d) + x + 0x00000000;
break;
default:
throw new Error("Bogus round number");
break;
}
a = ROL(a, s) + e;
c = ROL(c, 10);
a &= 0xffffffff;
b &= 0xffffffff;
c &= 0xffffffff;
d &= 0xffffffff;
e &= 0xffffffff;
var retBlock = [];
retBlock[0] = a;
retBlock[1] = b;
retBlock[2] = c;
retBlock[3] = d;
retBlock[4] = e;
retBlock[5] = x;
retBlock[6] = s;
return retBlock;
}
function MDinit(MDbuf) {
MDbuf[0] = 0x67452301;
MDbuf[1] = 0xefcdab89;
MDbuf[2] = 0x98badcfe;
MDbuf[3] = 0x10325476;
MDbuf[4] = 0xc3d2e1f0;
}
var ROLs = [
[11, 14, 15, 12, 5, 8, 7, 9, 11, 13, 14, 15, 6, 7, 9, 8],
[7, 6, 8, 13, 11, 9, 7, 15, 7, 12, 15, 9, 11, 7, 13, 12],
[11, 13, 6, 7, 14, 9, 13, 15, 14, 8, 13, 6, 5, 12, 7, 5],
[11, 12, 14, 15, 14, 15, 9, 8, 9, 14, 5, 6, 8, 6, 5, 12],
[9, 15, 5, 11, 6, 8, 13, 12, 5, 12, 13, 14, 11, 8, 5, 6],
[8, 9, 9, 11, 13, 15, 15, 5, 7, 7, 8, 11, 14, 14, 12, 6],
[9, 13, 15, 7, 12, 8, 9, 11, 7, 7, 12, 7, 6, 15, 13, 11],
[9, 7, 15, 11, 8, 6, 6, 14, 12, 13, 5, 14, 13, 13, 7, 5],
[15, 5, 8, 11, 14, 14, 6, 14, 6, 9, 12, 9, 12, 5, 15, 8],
[8, 5, 12, 9, 12, 5, 14, 6, 8, 13, 6, 5, 15, 13, 11, 11]
];
var indexes = [
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15],
[7, 4, 13, 1, 10, 6, 15, 3, 12, 0, 9, 5, 2, 14, 11, 8],
[3, 10, 14, 4, 9, 15, 8, 1, 2, 7, 0, 6, 13, 11, 5, 12],
[1, 9, 11, 10, 0, 8, 12, 4, 13, 3, 7, 15, 14, 5, 6, 2],
[4, 0, 5, 9, 7, 12, 2, 10, 14, 1, 3, 8, 11, 6, 15, 13],
[5, 14, 7, 0, 9, 2, 11, 4, 13, 6, 15, 8, 1, 10, 3, 12],
[6, 11, 3, 7, 0, 13, 5, 10, 14, 15, 8, 12, 4, 9, 1, 2],
[15, 5, 1, 3, 7, 14, 6, 9, 11, 8, 12, 2, 10, 0, 4, 13],
[8, 6, 4, 1, 3, 11, 15, 0, 5, 12, 2, 13, 9, 7, 10, 14],
[12, 15, 10, 4, 1, 5, 8, 7, 6, 2, 13, 14, 0, 3, 9, 11]
];
function compress(MDbuf, X) {
var blockA = [];
var blockB = [];
var retBlock;
var i, j;
for (i = 0; i < 5; i++) {
blockA[i] = new Number(MDbuf[i]);
blockB[i] = new Number(MDbuf[i]);
}
var step = 0;
for (j = 0; j < 5; j++) {
for (i = 0; i < 16; i++) {
retBlock = mixOneRound(
blockA[(step + 0) % 5],
blockA[(step + 1) % 5],
blockA[(step + 2) % 5],
blockA[(step + 3) % 5],
blockA[(step + 4) % 5],
X[indexes[j][i]],
ROLs[j][i],
j);
blockA[(step + 0) % 5] = retBlock[0];
blockA[(step + 1) % 5] = retBlock[1];
blockA[(step + 2) % 5] = retBlock[2];
blockA[(step + 3) % 5] = retBlock[3];
blockA[(step + 4) % 5] = retBlock[4];
step += 4;
}
}
step = 0;
for (j = 5; j < 10; j++) {
for (i = 0; i < 16; i++) {
retBlock = mixOneRound(
blockB[(step + 0) % 5],
blockB[(step + 1) % 5],
blockB[(step + 2) % 5],
blockB[(step + 3) % 5],
blockB[(step + 4) % 5],
X[indexes[j][i]],
ROLs[j][i],
j);
blockB[(step + 0) % 5] = retBlock[0];
blockB[(step + 1) % 5] = retBlock[1];
blockB[(step + 2) % 5] = retBlock[2];
blockB[(step + 3) % 5] = retBlock[3];
blockB[(step + 4) % 5] = retBlock[4];
step += 4;
}
}
blockB[3] += blockA[2] + MDbuf[1];
MDbuf[1] = MDbuf[2] + blockA[3] + blockB[4];
MDbuf[2] = MDbuf[3] + blockA[4] + blockB[0];
MDbuf[3] = MDbuf[4] + blockA[0] + blockB[1];
MDbuf[4] = MDbuf[0] + blockA[1] + blockB[2];
MDbuf[0] = blockB[3];
}
function zeroX(X) {
for (var i = 0; i < 16; i++) {
X[i] = 0;
}
}
function MDfinish(MDbuf, strptr, lswlen, mswlen) {
var X = new Array(16);
zeroX(X);
var j = 0;
for (var i = 0; i < (lswlen & 63); i++) {
X[i >>> 2] ^= (strptr.charCodeAt(j++) & 255) << (8 * (i & 3));
}
X[(lswlen >>> 2) & 15] ^= 1 << (8 * (lswlen & 3) + 7);
if ((lswlen & 63) > 55) {
compress(MDbuf, X);
X = new Array(16);
zeroX(X);
}
X[14] = lswlen << 3;
X[15] = (lswlen >>> 29) | (mswlen << 3);
compress(MDbuf, X);
}
function BYTES_TO_DWORD(fourChars) {
var tmp = (fourChars.charCodeAt(3) & 255) << 24;
tmp |= (fourChars.charCodeAt(2) & 255) << 16;
tmp |= (fourChars.charCodeAt(1) & 255) << 8;
tmp |= (fourChars.charCodeAt(0) & 255);
return tmp;
}
function RMD(message) {
var MDbuf = new Array(RMDsize / 32);
var hashcode = new Array(RMDsize / 8);
var length;
var nbytes;
MDinit(MDbuf);
length = message.length;
var X = new Array(16);
zeroX(X);
var i, j = 0;
for (nbytes = length; nbytes > 63; nbytes -= 64) {
for (i = 0; i < 16; i++) {
X[i] = BYTES_TO_DWORD(message.substr(j, 4));
j += 4;
}
compress(MDbuf, X);
}
MDfinish(MDbuf, message.substr(j), length, 0);
for (i = 0; i < RMDsize / 8; i += 4) {
hashcode[i] = MDbuf[i >>> 2] & 255;
hashcode[i + 1] = (MDbuf[i >>> 2] >>> 8) & 255;
hashcode[i + 2] = (MDbuf[i >>> 2] >>> 16) & 255;
hashcode[i + 3] = (MDbuf[i >>> 2] >>> 24) & 255;
}
return hashcode;
}
export default function RMDstring(message) {
var hashcode = RMD(util.Uint8Array2str(message));
var retString = "";
for (var i = 0; i < RMDsize / 8; i++) {
retString += String.fromCharCode(hashcode[i]);
}
return util.str2Uint8Array(retString);
}

File diff suppressed because it is too large Load diff

View file

@ -1,41 +0,0 @@
/**
* @see module:crypto/crypto
* @module crypto
*/
'use strict';
import cipher from './cipher';
import hash from './hash';
import cfb from './cfb';
import * as gcm from './gcm';
import publicKey from './public_key';
import signature from './signature';
import random from './random';
import pkcs1 from './pkcs1';
import crypto from './crypto.js';
const mod = {
/** @see module:crypto/cipher */
cipher: cipher,
/** @see module:crypto/hash */
hash: hash,
/** @see module:crypto/cfb */
cfb: cfb,
/** @see module:crypto/gcm */
gcm: gcm,
/** @see module:crypto/public_key */
publicKey: publicKey,
/** @see module:crypto/signature */
signature: signature,
/** @see module:crypto/random */
random: random,
/** @see module:crypto/pkcs1 */
pkcs1: pkcs1,
};
for (var i in crypto) {
mod[i] = crypto[i];
}
export default mod;

View file

@ -1,172 +0,0 @@
// GPG4Browsers - An OpenPGP implementation in javascript
// Copyright (C) 2011 Recurity Labs GmbH
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// 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,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
/**
* PKCS1 encoding
* @requires crypto/crypto
* @requires crypto/hash
* @requires crypto/public_key/jsbn
* @requires crypto/random
* @requires util
* @module crypto/pkcs1
*/
'use strict';
import random from './random.js';
import util from '../util.js';
import BigInteger from './public_key/jsbn.js';
import hash from './hash';
/**
* ASN1 object identifiers for hashes (See {@link http://tools.ietf.org/html/rfc4880#section-5.2.2})
*/
var hash_headers = [];
hash_headers[1] = [0x30, 0x20, 0x30, 0x0c, 0x06, 0x08, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x02, 0x05, 0x05, 0x00, 0x04,
0x10
];
hash_headers[2] = [0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x05, 0x00, 0x04, 0x14];
hash_headers[3] = [0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2B, 0x24, 0x03, 0x02, 0x01, 0x05, 0x00, 0x04, 0x14];
hash_headers[8] = [0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00,
0x04, 0x20
];
hash_headers[9] = [0x30, 0x41, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x02, 0x05, 0x00,
0x04, 0x30
];
hash_headers[10] = [0x30, 0x51, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, 0x05,
0x00, 0x04, 0x40
];
hash_headers[11] = [0x30, 0x2d, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x04, 0x05,
0x00, 0x04, 0x1C
];
/**
* Create padding with secure random data
* @private
* @param {Integer} length Length of the padding in bytes
* @return {String} Padding as string
*/
function getPkcs1Padding(length) {
var result = '';
var randomByte;
while (result.length < length) {
randomByte = random.getSecureRandomOctet();
if (randomByte !== 0) {
result += String.fromCharCode(randomByte);
}
}
return result;
}
export default {
eme: {
/**
* create a EME-PKCS1-v1_5 padding (See {@link http://tools.ietf.org/html/rfc4880#section-13.1.1|RFC 4880 13.1.1})
* @param {String} M message to be encoded
* @param {Integer} k the length in octets of the key modulus
* @return {String} EME-PKCS1 padded message
*/
encode: function(M, k) {
var mLen = M.length;
// length checking
if (mLen > k - 11) {
throw new Error('Message too long');
}
// Generate an octet string PS of length k - mLen - 3 consisting of
// pseudo-randomly generated nonzero octets
var PS = getPkcs1Padding(k - mLen - 3);
// Concatenate PS, the message M, and other padding to form an
// encoded message EM of length k octets as EM = 0x00 || 0x02 || PS || 0x00 || M.
var EM = String.fromCharCode(0) +
String.fromCharCode(2) +
PS +
String.fromCharCode(0) +
M;
return EM;
},
/**
* decodes a EME-PKCS1-v1_5 padding (See {@link http://tools.ietf.org/html/rfc4880#section-13.1.2|RFC 4880 13.1.2})
* @param {String} EM encoded message, an octet string
* @return {String} message, an octet string
*/
decode: function(EM) {
// leading zeros truncated by jsbn
if (EM.charCodeAt(0) !== 0) {
EM = String.fromCharCode(0) + EM;
}
var firstOct = EM.charCodeAt(0);
var secondOct = EM.charCodeAt(1);
var i = 2;
while (EM.charCodeAt(i) !== 0 && i < EM.length) {
i++;
}
var psLen = i - 2;
var separator = EM.charCodeAt(i++);
if (firstOct === 0 && secondOct === 2 && psLen >= 8 && separator === 0) {
return EM.substr(i);
} else {
throw new Error('Decryption error');
}
}
},
emsa: {
/**
* create a EMSA-PKCS1-v1_5 padding (See {@link http://tools.ietf.org/html/rfc4880#section-13.1.3|RFC 4880 13.1.3})
* @param {Integer} algo Hash algorithm type used
* @param {String} M message to be encoded
* @param {Integer} emLen intended length in octets of the encoded message
* @returns {String} encoded message
*/
encode: function(algo, M, emLen) {
var i;
// Apply the hash function to the message M to produce a hash value H
var H = util.Uint8Array2str(hash.digest(algo, util.str2Uint8Array(M)));
if (H.length !== hash.getHashByteLength(algo)) {
throw new Error('Invalid hash length');
}
// produce an ASN.1 DER value for the hash function used.
// Let T be the full hash prefix
var T = '';
for (i = 0; i < hash_headers[algo].length; i++) {
T += String.fromCharCode(hash_headers[algo][i]);
}
// add hash value to prefix
T += H;
// and let tLen be the length in octets of T
var tLen = T.length;
if (emLen < tLen + 11) {
throw new Error('Intended encoded message length too short');
}
// an octet string PS consisting of emLen - tLen - 3 octets with hexadecimal value 0xFF
// The length of PS will be at least 8 octets
var PS = '';
for (i = 0; i < (emLen - tLen - 3); i++) {
PS += String.fromCharCode(0xff);
}
// Concatenate PS, the hash prefix T, and other padding to form the
// encoded message EM as EM = 0x00 || 0x01 || PS || 0x00 || T.
var EM = String.fromCharCode(0x00) +
String.fromCharCode(0x01) +
PS +
String.fromCharCode(0x00) +
T;
return new BigInteger(util.hexstrdump(EM), 16);
}
}
};

View file

@ -1,125 +0,0 @@
// GPG4Browsers - An OpenPGP implementation in javascript
// Copyright (C) 2011 Recurity Labs GmbH
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// 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,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
//
// A Digital signature algorithm implementation
/**
* @requires crypto/hash
* @requires crypto/public_key/jsbn
* @requires crypto/random
* @requires util
* @module crypto/public_key/dsa
*/
'use strict';
import BigInteger from './jsbn.js';
import random from '../random.js';
import hashModule from '../hash';
import util from '../../util.js';
import config from '../../config';
export default function DSA() {
// s1 = ((g**s) mod p) mod q
// s1 = ((s**-1)*(sha-1(m)+(s1*x) mod q)
function sign(hashalgo, m, g, p, q, x) {
// If the output size of the chosen hash is larger than the number of
// bits of q, the hash result is truncated to fit by taking the number
// of leftmost bits equal to the number of bits of q. This (possibly
// truncated) hash function result is treated as a number and used
// directly in the DSA signature algorithm.
var hashed_data = util.getLeftNBits(util.Uint8Array2str(hashModule.digest(hashalgo, util.str2Uint8Array(m))), q.bitLength());
var hash = new BigInteger(util.hexstrdump(hashed_data), 16);
// FIPS-186-4, section 4.6:
// The values of r and s shall be checked to determine if r = 0 or s = 0.
// If either r = 0 or s = 0, a new value of k shall be generated, and the
// signature shall be recalculated. It is extremely unlikely that r = 0
// or s = 0 if signatures are generated properly.
var k, s1, s2;
while (true) {
k = random.getRandomBigIntegerInRange(BigInteger.ONE, q.subtract(BigInteger.ONE));
s1 = (g.modPow(k, p)).mod(q);
s2 = (k.modInverse(q).multiply(hash.add(x.multiply(s1)))).mod(q);
if (s1 !== 0 && s2 !== 0) {
break;
}
}
var result = [];
result[0] = s1.toMPI();
result[1] = s2.toMPI();
return result;
}
function select_hash_algorithm(q) {
var usersetting = config.prefer_hash_algorithm;
/*
* 1024-bit key, 160-bit q, SHA-1, SHA-224, SHA-256, SHA-384, or SHA-512 hash
* 2048-bit key, 224-bit q, SHA-224, SHA-256, SHA-384, or SHA-512 hash
* 2048-bit key, 256-bit q, SHA-256, SHA-384, or SHA-512 hash
* 3072-bit key, 256-bit q, SHA-256, SHA-384, or SHA-512 hash
*/
switch (Math.round(q.bitLength() / 8)) {
case 20:
// 1024 bit
if (usersetting !== 2 &&
usersetting > 11 &&
usersetting !== 10 &&
usersetting < 8) {
return 2; // prefer sha1
}
return usersetting;
case 28:
// 2048 bit
if (usersetting > 11 &&
usersetting < 8) {
return 11;
}
return usersetting;
case 32:
// 4096 bit // prefer sha224
if (usersetting > 10 &&
usersetting < 8) {
return 8; // prefer sha256
}
return usersetting;
default:
return null;
}
}
this.select_hash_algorithm = select_hash_algorithm;
function verify(hashalgo, s1, s2, m, p, q, g, y) {
var hashed_data = util.getLeftNBits(util.Uint8Array2str(hashModule.digest(hashalgo, util.str2Uint8Array(m))), q.bitLength());
var hash = new BigInteger(util.hexstrdump(hashed_data), 16);
if (BigInteger.ZERO.compareTo(s1) >= 0 ||
s1.compareTo(q) >= 0 ||
BigInteger.ZERO.compareTo(s2) >= 0 ||
s2.compareTo(q) >= 0) {
return null;
}
var w = s2.modInverse(q);
if (BigInteger.ZERO.compareTo(w) === 0) {
return null;
}
var u1 = hash.multiply(w).mod(q);
var u2 = s1.multiply(w).mod(q);
return g.modPow(u1, p).multiply(y.modPow(u2, p)).mod(p).mod(q);
}
this.sign = sign;
this.verify = verify;
}

View file

@ -1,55 +0,0 @@
// GPG4Browsers - An OpenPGP implementation in javascript
// Copyright (C) 2011 Recurity Labs GmbH
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// 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,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
//
// ElGamal implementation
/**
* @requires crypto/public_key/jsbn
* @requires crypto/random
* @requires util
* @module crypto/public_key/elgamal
*/
'use strict';
import BigInteger from './jsbn.js';
import random from '../random.js';
import util from '../../util.js';
export default function Elgamal() {
function encrypt(m, g, p, y) {
// choose k in {2,...,p-2}
var pMinus2 = p.subtract(BigInteger.TWO);
var k = random.getRandomBigIntegerInRange(BigInteger.ONE, pMinus2);
k = k.mod(pMinus2).add(BigInteger.ONE);
var c = [];
c[0] = g.modPow(k, p);
c[1] = y.modPow(k, p).multiply(m).mod(p);
return c;
}
function decrypt(c1, c2, p, x) {
return (c1.modPow(x, p).modInverse(p)).multiply(c2).mod(p);
//var c = c1.pow(x).modInverse(p); // c0^-a mod p
//return c.multiply(c2).mod(p);
}
// signing and signature verification using Elgamal is not required by OpenPGP.
this.encrypt = encrypt;
this.decrypt = decrypt;
}

View file

@ -1,21 +0,0 @@
/**
* @requires crypto/public_key/dsa
* @requires crypto/public_key/elgamal
* @requires crypto/public_key/rsa
* @module crypto/public_key
*/
'use strict';
/** @see module:crypto/public_key/rsa */
import rsa from './rsa.js';
/** @see module:crypto/public_key/elgamal */
import elgamal from './elgamal.js';
/** @see module:crypto/public_key/dsa */
import dsa from './dsa.js';
export default {
rsa: rsa,
elgamal: elgamal,
dsa: dsa
};

File diff suppressed because it is too large Load diff

View file

@ -1,258 +0,0 @@
// GPG4Browsers - An OpenPGP implementation in javascript
// Copyright (C) 2011 Recurity Labs GmbH
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// 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,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
//
// RSA implementation
/**
* @requires crypto/public_key/jsbn
* @requires crypto/random
* @requires util
* @module crypto/public_key/rsa
*/
'use strict';
import BigInteger from './jsbn.js';
import util from '../../util.js';
import random from '../random.js';
import config from '../../config';
function SecureRandom() {
function nextBytes(byteArray) {
for (var n = 0; n < byteArray.length; n++) {
byteArray[n] = random.getSecureRandomOctet();
}
}
this.nextBytes = nextBytes;
}
var blinder = BigInteger.ZERO;
var unblinder = BigInteger.ZERO;
function blind(m, n, e) {
if (unblinder.bitLength() === n.bitLength()) {
unblinder = unblinder.square().mod(n);
} else {
unblinder = random.getRandomBigIntegerInRange(BigInteger.TWO, n);
}
blinder = unblinder.modInverse(n).modPow(e, n);
return m.multiply(blinder).mod(n);
}
function unblind(t, n) {
return t.multiply(unblinder).mod(n);
}
export default function RSA() {
/**
* This function uses jsbn Big Num library to decrypt RSA
* @param m
* message
* @param n
* RSA public modulus n as BigInteger
* @param e
* RSA public exponent as BigInteger
* @param d
* RSA d as BigInteger
* @param p
* RSA p as BigInteger
* @param q
* RSA q as BigInteger
* @param u
* RSA u as BigInteger
* @return {BigInteger} The decrypted value of the message
*/
function decrypt(m, n, e, d, p, q, u) {
m = blind(m, n, e);
var xp = m.mod(p).modPow(d.mod(p.subtract(BigInteger.ONE)), p);
var xq = m.mod(q).modPow(d.mod(q.subtract(BigInteger.ONE)), q);
var t = xq.subtract(xp);
if (t[0] === 0) {
t = xp.subtract(xq);
t = t.multiply(u).mod(q);
t = q.subtract(t);
} else {
t = t.multiply(u).mod(q);
}
t = t.multiply(p).add(xp);
t = unblind(t, n);
return t;
}
/**
* encrypt message
* @param m message as BigInteger
* @param e public MPI part as BigInteger
* @param n public MPI part as BigInteger
* @return BigInteger
*/
function encrypt(m, e, n) {
return m.modPowInt(e, n);
}
/* Sign and Verify */
function sign(m, d, n) {
return m.modPow(d, n);
}
function verify(x, e, n) {
return x.modPowInt(e, n);
}
// "empty" RSA key constructor
function KeyObject() {
this.n = null;
this.e = 0;
this.ee = null;
this.d = null;
this.p = null;
this.q = null;
this.dmp1 = null;
this.dmq1 = null;
this.u = null;
}
// Generate a new random private key B bits long, using public expt E
function generate(B, E) {
var webCrypto = util.getWebCryptoAll();
//
// Native RSA keygen using Web Crypto
//
if (webCrypto) {
var Euint32 = new Uint32Array([parseInt(E, 16)]); // get integer of exponent
var Euint8 = new Uint8Array(Euint32.buffer); // get bytes of exponent
var keyGenOpt;
var keys;
if (window.crypto && window.crypto.webkitSubtle) {
// outdated spec implemented by Webkit
keyGenOpt = {
name: 'RSA-OAEP',
modulusLength: B, // the specified keysize in bits
publicExponent: Euint8.subarray(0, 3), // take three bytes (max 65537)
hash: {
name: 'SHA-1' // not required for actual RSA keys, but for crypto api 'sign' and 'verify'
}
};
keys = webCrypto.generateKey(keyGenOpt, true, ['encrypt', 'decrypt']);
}
else {
// current standard spec
keyGenOpt = {
name: 'RSASSA-PKCS1-v1_5',
modulusLength: B, // the specified keysize in bits
publicExponent: Euint8.subarray(0, 3), // take three bytes (max 65537)
hash: {
name: 'SHA-1' // not required for actual RSA keys, but for crypto api 'sign' and 'verify'
}
};
keys = webCrypto.generateKey(keyGenOpt, true, ['sign', 'verify']);
}
return keys.then(exportKey).then(function(key) {
if (key instanceof ArrayBuffer) {
// parse raw ArrayBuffer bytes to jwk/json (WebKit/Safari/IE11 quirk)
return decodeKey(JSON.parse(String.fromCharCode.apply(null, new Uint8Array(key))));
}
return decodeKey(key);
});
}
function exportKey(keypair) {
// export the generated keys as JsonWebKey (JWK)
// https://tools.ietf.org/html/draft-ietf-jose-json-web-key-33
return webCrypto.exportKey('jwk', keypair.privateKey);
}
function decodeKey(jwk) {
// map JWK parameters to local BigInteger type system
var key = new KeyObject();
key.n = toBigInteger(jwk.n);
key.ee = new BigInteger(E, 16);
key.d = toBigInteger(jwk.d);
key.p = toBigInteger(jwk.p);
key.q = toBigInteger(jwk.q);
key.u = key.p.modInverse(key.q);
function toBigInteger(base64url) {
var base64 = base64url.replace(/\-/g, '+').replace(/_/g, '/');
var hex = util.hexstrdump(atob(base64));
return new BigInteger(hex, 16);
}
return key;
}
//
// JS code
//
return new Promise(function(resolve) {
var key = new KeyObject();
var rng = new SecureRandom();
var qs = B >> 1;
key.e = parseInt(E, 16);
key.ee = new BigInteger(E, 16);
for (;;) {
for (;;) {
key.p = new BigInteger(B - qs, 1, rng);
if (key.p.subtract(BigInteger.ONE).gcd(key.ee).compareTo(BigInteger.ONE) === 0 && key.p.isProbablePrime(10)) {
break;
}
}
for (;;) {
key.q = new BigInteger(qs, 1, rng);
if (key.q.subtract(BigInteger.ONE).gcd(key.ee).compareTo(BigInteger.ONE) === 0 && key.q.isProbablePrime(10)) {
break;
}
}
if (key.p.compareTo(key.q) <= 0) {
var t = key.p;
key.p = key.q;
key.q = t;
}
var p1 = key.p.subtract(BigInteger.ONE);
var q1 = key.q.subtract(BigInteger.ONE);
var phi = p1.multiply(q1);
if (phi.gcd(key.ee).compareTo(BigInteger.ONE) === 0) {
key.n = key.p.multiply(key.q);
key.d = key.ee.modInverse(phi);
key.dmp1 = key.d.mod(p1);
key.dmq1 = key.d.mod(q1);
key.u = key.p.modInverse(key.q);
break;
}
}
resolve(key);
});
}
this.encrypt = encrypt;
this.decrypt = decrypt;
this.verify = verify;
this.sign = sign;
this.generate = generate;
this.keyObject = KeyObject;
}

View file

@ -1,190 +0,0 @@
// GPG4Browsers - An OpenPGP implementation in javascript
// Copyright (C) 2011 Recurity Labs GmbH
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// 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,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
// The GPG4Browsers crypto interface
/**
* @requires type/mpi
* @requires util
* @module crypto/random
*/
'use strict';
import type_mpi from '../type/mpi.js';
import util from '../util.js';
export default {
/**
* Retrieve secure random byte array of the specified length
* @param {Integer} length Length in bytes to generate
* @return {Uint8Array} Random byte array
*/
getRandomBytes: function(length) {
var result = new Uint8Array(length);
for (var i = 0; i < length; i++) {
result[i] = this.getSecureRandomOctet();
}
return result;
},
/**
* Return a secure random number in the specified range
* @param {Integer} from Min of the random number
* @param {Integer} to Max of the random number (max 32bit)
* @return {Integer} A secure random number
*/
getSecureRandom: function(from, to) {
var randUint = this.getSecureRandomUint();
var bits = ((to - from)).toString(2).length;
while ((randUint & (Math.pow(2, bits) - 1)) > (to - from)) {
randUint = this.getSecureRandomUint();
}
return from + (Math.abs(randUint & (Math.pow(2, bits) - 1)));
},
getSecureRandomOctet: function() {
var buf = new Uint8Array(1);
this.getRandomValues(buf);
return buf[0];
},
getSecureRandomUint: function() {
var buf = new Uint8Array(4);
var dv = new DataView(buf.buffer);
this.getRandomValues(buf);
return dv.getUint32(0);
},
/**
* Helper routine which calls platform specific crypto random generator
* @param {Uint8Array} buf
*/
getRandomValues: function(buf) {
if (!(buf instanceof Uint8Array)) {
throw new Error('Invalid type: buf not an Uint8Array');
}
if (typeof window !== 'undefined' && window.crypto && window.crypto.getRandomValues) {
window.crypto.getRandomValues(buf);
} else if (typeof window !== 'undefined' && typeof window.msCrypto === 'object' && typeof window.msCrypto.getRandomValues === 'function') {
window.msCrypto.getRandomValues(buf);
} else if (this.randomBuffer.buffer) {
this.randomBuffer.get(buf);
} else {
throw new Error('No secure random number generator available.');
}
return buf;
},
/**
* Create a secure random big integer of bits length
* @param {Integer} bits Bit length of the MPI to create
* @return {BigInteger} Resulting big integer
*/
getRandomBigInteger: function(bits) {
if (bits < 1) {
throw new Error('Illegal parameter value: bits < 1');
}
var numBytes = Math.floor((bits + 7) / 8);
var randomBits = util.Uint8Array2str(this.getRandomBytes(numBytes));
if (bits % 8 > 0) {
randomBits = String.fromCharCode(
(Math.pow(2, bits % 8) - 1) &
randomBits.charCodeAt(0)) +
randomBits.substring(1);
}
var mpi = new type_mpi();
mpi.fromBytes(randomBits);
return mpi.toBigInteger();
},
getRandomBigIntegerInRange: function(min, max) {
if (max.compareTo(min) <= 0) {
throw new Error('Illegal parameter value: max <= min');
}
var range = max.subtract(min);
var r = this.getRandomBigInteger(range.bitLength());
while (r.compareTo(range) > 0) {
r = this.getRandomBigInteger(range.bitLength());
}
return min.add(r);
},
randomBuffer: new RandomBuffer()
};
/**
* Buffer for secure random numbers
*/
function RandomBuffer() {
this.buffer = null;
this.size = null;
}
/**
* Initialize buffer
* @param {Integer} size size of buffer
*/
RandomBuffer.prototype.init = function(size) {
this.buffer = new Uint8Array(size);
this.size = 0;
};
/**
* Concat array of secure random numbers to buffer
* @param {Uint8Array} buf
*/
RandomBuffer.prototype.set = function(buf) {
if (!this.buffer) {
throw new Error('RandomBuffer is not initialized');
}
if (!(buf instanceof Uint8Array)) {
throw new Error('Invalid type: buf not an Uint8Array');
}
var freeSpace = this.buffer.length - this.size;
if (buf.length > freeSpace) {
buf = buf.subarray(0, freeSpace);
}
// set buf with offset old size of buffer
this.buffer.set(buf, this.size);
this.size += buf.length;
};
/**
* Take numbers out of buffer and copy to array
* @param {Uint8Array} buf the destination array
*/
RandomBuffer.prototype.get = function(buf) {
if (!this.buffer) {
throw new Error('RandomBuffer is not initialized');
}
if (!(buf instanceof Uint8Array)) {
throw new Error('Invalid type: buf not an Uint8Array');
}
if (this.size < buf.length) {
throw new Error('Random number buffer depleted');
}
for (var i = 0; i < buf.length; i++) {
buf[i] = this.buffer[--this.size];
// clear buffer value
this.buffer[this.size] = 0;
}
};

View file

@ -1,114 +0,0 @@
/**
* @requires util
* @requires crypto/hash
* @requires crypto/pkcs1
* @requires crypto/public_key
* @module crypto/signature */
'use strict';
import util from '../util';
import publicKey from './public_key';
import pkcs1 from './pkcs1.js';
export default {
/**
*
* @param {module:enums.publicKey} algo public Key algorithm
* @param {module:enums.hash} hash_algo Hash algorithm
* @param {Array<module:type/mpi>} msg_MPIs Signature multiprecision integers
* @param {Array<module:type/mpi>} publickey_MPIs Public key multiprecision integers
* @param {Uint8Array} data Data on where the signature was computed on.
* @return {Boolean} true if signature (sig_data was equal to data over hash)
*/
verify: function(algo, hash_algo, msg_MPIs, publickey_MPIs, data) {
var m;
data = util.Uint8Array2str(data);
switch (algo) {
case 1:
// RSA (Encrypt or Sign) [HAC]
case 2:
// RSA Encrypt-Only [HAC]
case 3:
// RSA Sign-Only [HAC]
var rsa = new publicKey.rsa();
var n = publickey_MPIs[0].toBigInteger();
var k = publickey_MPIs[0].byteLength();
var e = publickey_MPIs[1].toBigInteger();
m = msg_MPIs[0].toBigInteger();
var EM = rsa.verify(m, e, n);
var EM2 = pkcs1.emsa.encode(hash_algo, data, k);
return EM.compareTo(EM2) === 0;
case 16:
// Elgamal (Encrypt-Only) [ELGAMAL] [HAC]
throw new Error("signing with Elgamal is not defined in the OpenPGP standard.");
case 17:
// DSA (Digital Signature Algorithm) [FIPS186] [HAC]
var dsa = new publicKey.dsa();
var s1 = msg_MPIs[0].toBigInteger();
var s2 = msg_MPIs[1].toBigInteger();
var p = publickey_MPIs[0].toBigInteger();
var q = publickey_MPIs[1].toBigInteger();
var g = publickey_MPIs[2].toBigInteger();
var y = publickey_MPIs[3].toBigInteger();
m = data;
var dopublic = dsa.verify(hash_algo, s1, s2, m, p, q, g, y);
return dopublic.compareTo(s1) === 0;
default:
throw new Error('Invalid signature algorithm.');
}
},
/**
* Create a signature on data using the specified algorithm
* @param {module:enums.hash} hash_algo hash Algorithm to use (See {@link http://tools.ietf.org/html/rfc4880#section-9.4|RFC 4880 9.4})
* @param {module:enums.publicKey} algo Asymmetric cipher algorithm to use (See {@link http://tools.ietf.org/html/rfc4880#section-9.1|RFC 4880 9.1})
* @param {Array<module:type/mpi>} publicMPIs Public key multiprecision integers
* of the private key
* @param {Array<module:type/mpi>} secretMPIs Private key multiprecision
* integers which is used to sign the data
* @param {Uint8Array} data Data to be signed
* @return {Array<module:type/mpi>}
*/
sign: function(hash_algo, algo, keyIntegers, data) {
data = util.Uint8Array2str(data);
var m;
switch (algo) {
case 1:
// RSA (Encrypt or Sign) [HAC]
case 2:
// RSA Encrypt-Only [HAC]
case 3:
// RSA Sign-Only [HAC]
var rsa = new publicKey.rsa();
var d = keyIntegers[2].toBigInteger();
var n = keyIntegers[0].toBigInteger();
m = pkcs1.emsa.encode(hash_algo,
data, keyIntegers[0].byteLength());
return util.str2Uint8Array(rsa.sign(m, d, n).toMPI());
case 17:
// DSA (Digital Signature Algorithm) [FIPS186] [HAC]
var dsa = new publicKey.dsa();
var p = keyIntegers[0].toBigInteger();
var q = keyIntegers[1].toBigInteger();
var g = keyIntegers[2].toBigInteger();
var x = keyIntegers[4].toBigInteger();
m = data;
var result = dsa.sign(hash_algo, m, g, p, q, x);
return util.str2Uint8Array(result[0].toString() + result[1].toString());
case 16:
// Elgamal (Encrypt-Only) [ELGAMAL] [HAC]
throw new Error('Signing with Elgamal is not defined in the OpenPGP standard.');
default:
throw new Error('Invalid signature algorithm.');
}
}
};

View file

@ -1,368 +0,0 @@
// GPG4Browsers - An OpenPGP implementation in javascript
// Copyright (C) 2011 Recurity Labs GmbH
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// 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,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
/**
* @requires encoding/base64
* @requires enums
* @requires config
* @module encoding/armor
*/
'use strict';
import base64 from './base64.js';
import enums from '../enums.js';
import config from '../config';
/**
* Finds out which Ascii Armoring type is used. Throws error if unknown type.
* @private
* @param {String} text [String] ascii armored text
* @returns {Integer} 0 = MESSAGE PART n of m
* 1 = MESSAGE PART n
* 2 = SIGNED MESSAGE
* 3 = PGP MESSAGE
* 4 = PUBLIC KEY BLOCK
* 5 = PRIVATE KEY BLOCK
* 6 = SIGNATURE
*/
function getType(text) {
var reHeader = /^-----BEGIN PGP (MESSAGE, PART \d+\/\d+|MESSAGE, PART \d+|SIGNED MESSAGE|MESSAGE|PUBLIC KEY BLOCK|PRIVATE KEY BLOCK|SIGNATURE)-----$\n/m;
var header = text.match(reHeader);
if (!header) {
throw new Error('Unknown ASCII armor type');
}
// BEGIN PGP MESSAGE, PART X/Y
// Used for multi-part messages, where the armor is split amongst Y
// parts, and this is the Xth part out of Y.
if (/MESSAGE, PART \d+\/\d+/.test(header[1])) {
return enums.armor.multipart_section;
} else
// BEGIN PGP MESSAGE, PART X
// Used for multi-part messages, where this is the Xth part of an
// unspecified number of parts. Requires the MESSAGE-ID Armor
// Header to be used.
if (/MESSAGE, PART \d+/.test(header[1])) {
return enums.armor.multipart_last;
} else
// BEGIN PGP SIGNED MESSAGE
if (/SIGNED MESSAGE/.test(header[1])) {
return enums.armor.signed;
} else
// BEGIN PGP MESSAGE
// Used for signed, encrypted, or compressed files.
if (/MESSAGE/.test(header[1])) {
return enums.armor.message;
} else
// BEGIN PGP PUBLIC KEY BLOCK
// Used for armoring public keys.
if (/PUBLIC KEY BLOCK/.test(header[1])) {
return enums.armor.public_key;
} else
// BEGIN PGP PRIVATE KEY BLOCK
// Used for armoring private keys.
if (/PRIVATE KEY BLOCK/.test(header[1])) {
return enums.armor.private_key;
} else
// BEGIN PGP SIGNATURE
// Used for detached signatures, OpenPGP/MIME signatures, and
// cleartext signatures. Note that PGP 2.x uses BEGIN PGP MESSAGE
// for detached signatures.
if (/SIGNATURE/.test(header[1])) {
return enums.armor.signature;
}
}
/**
* Calculates a checksum over the given data and returns it base64 encoded
* @param {String} data Data to create a CRC-24 checksum for
* @return {String} Base64 encoded checksum
*/
function getCheckSum(data) {
var c = createcrc24(data);
var bytes = new Uint8Array([c >> 16, (c >> 8) & 0xFF, c & 0xFF]);
return base64.encode(bytes);
}
/**
* Calculates the checksum over the given data and compares it with the
* given base64 encoded checksum
* @param {String} data Data to create a CRC-24 checksum for
* @param {String} checksum Base64 encoded checksum
* @return {Boolean} True if the given checksum is correct; otherwise false
*/
function verifyCheckSum(data, checksum) {
var c = getCheckSum(data);
var d = checksum;
return c[0] === d[0] && c[1] === d[1] && c[2] === d[2] && c[3] === d[3];
}
/**
* Internal function to calculate a CRC-24 checksum over a given string (data)
* @param {String} data Data to create a CRC-24 checksum for
* @return {Integer} The CRC-24 checksum as number
*/
var crc_table = [
0x00000000, 0x00864cfb, 0x018ad50d, 0x010c99f6, 0x0393e6e1, 0x0315aa1a, 0x021933ec, 0x029f7f17, 0x07a18139,
0x0727cdc2, 0x062b5434, 0x06ad18cf, 0x043267d8, 0x04b42b23, 0x05b8b2d5, 0x053efe2e, 0x0fc54e89, 0x0f430272,
0x0e4f9b84, 0x0ec9d77f, 0x0c56a868, 0x0cd0e493, 0x0ddc7d65, 0x0d5a319e, 0x0864cfb0, 0x08e2834b, 0x09ee1abd,
0x09685646, 0x0bf72951, 0x0b7165aa, 0x0a7dfc5c, 0x0afbb0a7, 0x1f0cd1e9, 0x1f8a9d12, 0x1e8604e4, 0x1e00481f,
0x1c9f3708, 0x1c197bf3, 0x1d15e205, 0x1d93aefe, 0x18ad50d0, 0x182b1c2b, 0x192785dd, 0x19a1c926, 0x1b3eb631,
0x1bb8faca, 0x1ab4633c, 0x1a322fc7, 0x10c99f60, 0x104fd39b, 0x11434a6d, 0x11c50696, 0x135a7981, 0x13dc357a,
0x12d0ac8c, 0x1256e077, 0x17681e59, 0x17ee52a2, 0x16e2cb54, 0x166487af, 0x14fbf8b8, 0x147db443, 0x15712db5,
0x15f7614e, 0x3e19a3d2, 0x3e9fef29, 0x3f9376df, 0x3f153a24, 0x3d8a4533, 0x3d0c09c8, 0x3c00903e, 0x3c86dcc5,
0x39b822eb, 0x393e6e10, 0x3832f7e6, 0x38b4bb1d, 0x3a2bc40a, 0x3aad88f1, 0x3ba11107, 0x3b275dfc, 0x31dced5b,
0x315aa1a0,
0x30563856, 0x30d074ad, 0x324f0bba, 0x32c94741, 0x33c5deb7, 0x3343924c, 0x367d6c62, 0x36fb2099, 0x37f7b96f,
0x3771f594, 0x35ee8a83, 0x3568c678, 0x34645f8e, 0x34e21375, 0x2115723b, 0x21933ec0, 0x209fa736, 0x2019ebcd,
0x228694da, 0x2200d821, 0x230c41d7, 0x238a0d2c, 0x26b4f302, 0x2632bff9, 0x273e260f, 0x27b86af4, 0x252715e3,
0x25a15918, 0x24adc0ee, 0x242b8c15, 0x2ed03cb2, 0x2e567049, 0x2f5ae9bf, 0x2fdca544, 0x2d43da53, 0x2dc596a8,
0x2cc90f5e, 0x2c4f43a5, 0x2971bd8b, 0x29f7f170, 0x28fb6886, 0x287d247d, 0x2ae25b6a, 0x2a641791, 0x2b688e67,
0x2beec29c, 0x7c3347a4, 0x7cb50b5f, 0x7db992a9, 0x7d3fde52, 0x7fa0a145, 0x7f26edbe, 0x7e2a7448, 0x7eac38b3,
0x7b92c69d, 0x7b148a66, 0x7a181390, 0x7a9e5f6b, 0x7801207c, 0x78876c87, 0x798bf571, 0x790db98a, 0x73f6092d,
0x737045d6, 0x727cdc20, 0x72fa90db, 0x7065efcc, 0x70e3a337, 0x71ef3ac1, 0x7169763a, 0x74578814, 0x74d1c4ef,
0x75dd5d19, 0x755b11e2, 0x77c46ef5, 0x7742220e, 0x764ebbf8, 0x76c8f703, 0x633f964d, 0x63b9dab6, 0x62b54340,
0x62330fbb,
0x60ac70ac, 0x602a3c57, 0x6126a5a1, 0x61a0e95a, 0x649e1774, 0x64185b8f, 0x6514c279, 0x65928e82, 0x670df195,
0x678bbd6e, 0x66872498, 0x66016863, 0x6cfad8c4, 0x6c7c943f, 0x6d700dc9, 0x6df64132, 0x6f693e25, 0x6fef72de,
0x6ee3eb28, 0x6e65a7d3, 0x6b5b59fd, 0x6bdd1506, 0x6ad18cf0, 0x6a57c00b, 0x68c8bf1c, 0x684ef3e7, 0x69426a11,
0x69c426ea, 0x422ae476, 0x42aca88d, 0x43a0317b, 0x43267d80, 0x41b90297, 0x413f4e6c, 0x4033d79a, 0x40b59b61,
0x458b654f, 0x450d29b4, 0x4401b042, 0x4487fcb9, 0x461883ae, 0x469ecf55, 0x479256a3, 0x47141a58, 0x4defaaff,
0x4d69e604, 0x4c657ff2, 0x4ce33309, 0x4e7c4c1e, 0x4efa00e5, 0x4ff69913, 0x4f70d5e8, 0x4a4e2bc6, 0x4ac8673d,
0x4bc4fecb, 0x4b42b230, 0x49ddcd27, 0x495b81dc, 0x4857182a, 0x48d154d1, 0x5d26359f, 0x5da07964, 0x5cace092,
0x5c2aac69, 0x5eb5d37e, 0x5e339f85, 0x5f3f0673, 0x5fb94a88, 0x5a87b4a6, 0x5a01f85d, 0x5b0d61ab, 0x5b8b2d50,
0x59145247, 0x59921ebc, 0x589e874a, 0x5818cbb1, 0x52e37b16, 0x526537ed, 0x5369ae1b, 0x53efe2e0, 0x51709df7,
0x51f6d10c,
0x50fa48fa, 0x507c0401, 0x5542fa2f, 0x55c4b6d4, 0x54c82f22, 0x544e63d9, 0x56d11cce, 0x56575035, 0x575bc9c3,
0x57dd8538
];
function createcrc24(input) {
var crc = 0xB704CE;
for (var index = 0; index < input.length; index++) {
crc = (crc << 8) ^ crc_table[((crc >> 16) ^ input[index]) & 0xff];
}
return crc & 0xffffff;
}
/**
* Splits a message into two parts, the headers and the body. This is an internal function
* @param {String} text OpenPGP armored message part
* @returns {Object} An object with attribute "headers" containing the headers
* and an attribute "body" containing the body.
*/
function splitHeaders(text) {
// empty line with whitespace characters
var reEmptyLine = /^[ \f\r\t\u00a0\u2000-\u200a\u202f\u205f\u3000]*\n/m;
var headers = '';
var body = text;
var matchResult = reEmptyLine.exec(text);
if (matchResult !== null) {
headers = text.slice(0, matchResult.index);
body = text.slice(matchResult.index + matchResult[0].length);
} else {
throw new Error('Mandatory blank line missing between armor headers and armor data');
}
headers = headers.split('\n');
// remove empty entry
headers.pop();
return { headers: headers, body: body };
}
/**
* Verify armored headers. RFC4880, section 6.3: "OpenPGP should consider improperly formatted
* Armor Headers to be corruption of the ASCII Armor."
* @private
* @param {Array<String>} headers Armor headers
*/
function verifyHeaders(headers) {
for (var i = 0; i < headers.length; i++) {
if (!/^([^\s:]|[^\s:][^:]*[^\s:]): .+$/.test(headers[i])) {
throw new Error('Improperly formatted armor header: ' + headers[i]);
}
}
}
/**
* Splits a message into two parts, the body and the checksum. This is an internal function
* @param {String} text OpenPGP armored message part
* @returns {Object} An object with attribute "body" containing the body
* and an attribute "checksum" containing the checksum.
*/
function splitChecksum(text) {
text = text.trim();
var body = text;
var checksum = "";
var lastEquals = text.lastIndexOf("=");
if (lastEquals >= 0 && lastEquals !== text.length - 1) { // '=' as the last char means no checksum
body = text.slice(0, lastEquals);
checksum = text.slice(lastEquals + 1).substr(0, 4);
}
return { body: body, checksum: checksum };
}
/**
* DeArmor an OpenPGP armored message; verify the checksum and return
* the encoded bytes
* @param {String} text OpenPGP armored message
* @returns {Object} An object with attribute "text" containing the message text,
* an attribute "data" containing the bytes and "type" for the ASCII armor type
* @static
*/
function dearmor(text) {
var reSplit = /^-----[^-]+-----$\n/m;
// remove trailing whitespace at end of line
text = text.replace(/[\t\r ]+\n/g, '\n');
var type = getType(text);
text = text.trim() + "\n";
var splittext = text.split(reSplit);
// IE has a bug in split with a re. If the pattern matches the beginning of the
// string it doesn't create an empty array element 0. So we need to detect this
// so we know the index of the data we are interested in.
var indexBase = 1;
var result, checksum, msg;
if (text.search(reSplit) !== splittext[0].length) {
indexBase = 0;
}
if (type !== 2) {
msg = splitHeaders(splittext[indexBase]);
var msg_sum = splitChecksum(msg.body);
result = {
data: base64.decode(msg_sum.body),
headers: msg.headers,
type: type
};
checksum = msg_sum.checksum;
} else {
// Reverse dash-escaping for msg
msg = splitHeaders(splittext[indexBase].replace(/^- /mg, ''));
var sig = splitHeaders(splittext[indexBase + 1].replace(/^- /mg, ''));
verifyHeaders(sig.headers);
var sig_sum = splitChecksum(sig.body);
result = {
text: msg.body.replace(/\n$/, '').replace(/\n/g, "\r\n"),
data: base64.decode(sig_sum.body),
headers: msg.headers,
type: type
};
checksum = sig_sum.checksum;
}
if (!verifyCheckSum(result.data, checksum) && (checksum || config.checksum_required)) {
// will NOT throw error if checksum is empty AND checksum is not required (GPG compatibility)
throw new Error("Ascii armor integrity check on message failed: '" + checksum + "' should be '" +
getCheckSum(result.data) + "'");
}
verifyHeaders(result.headers);
return result;
}
/**
* Armor an OpenPGP binary packet block
* @param {Integer} messagetype type of the message
* @param body
* @param {Integer} partindex
* @param {Integer} parttotal
* @returns {String} Armored text
* @static
*/
function armor(messagetype, body, partindex, parttotal) {
var result = [];
switch (messagetype) {
case enums.armor.multipart_section:
result.push("-----BEGIN PGP MESSAGE, PART " + partindex + "/" + parttotal + "-----\r\n");
result.push(base64.encode(body));
result.push("\r\n=" + getCheckSum(body) + "\r\n");
result.push("-----END PGP MESSAGE, PART " + partindex + "/" + parttotal + "-----\r\n");
break;
case enums.armor.multipart_last:
result.push("-----BEGIN PGP MESSAGE, PART " + partindex + "-----\r\n");
result.push(base64.encode(body));
result.push("\r\n=" + getCheckSum(body) + "\r\n");
result.push("-----END PGP MESSAGE, PART " + partindex + "-----\r\n");
break;
case enums.armor.signed:
result.push("\r\n-----BEGIN PGP SIGNED MESSAGE-----\r\n");
result.push("Hash: " + body.hash + "\r\n\r\n");
result.push(body.text.replace(/\n-/g, "\n- -"));
result.push("\r\n-----BEGIN PGP SIGNATURE-----\r\n");
result.push(base64.encode(body.data));
result.push("\r\n=" + getCheckSum(body.data) + "\r\n");
result.push("-----END PGP SIGNATURE-----\r\n");
break;
case enums.armor.message:
result.push("-----BEGIN PGP MESSAGE-----\r\n");
result.push(base64.encode(body));
result.push("\r\n=" + getCheckSum(body) + "\r\n");
result.push("-----END PGP MESSAGE-----\r\n");
break;
case enums.armor.public_key:
result.push("-----BEGIN PGP PUBLIC KEY BLOCK-----\r\n");
result.push(base64.encode(body));
result.push("\r\n=" + getCheckSum(body) + "\r\n");
result.push("-----END PGP PUBLIC KEY BLOCK-----\r\n\r\n");
break;
case enums.armor.private_key:
result.push("-----BEGIN PGP PRIVATE KEY BLOCK-----\r\n");
result.push(base64.encode(body));
result.push("\r\n=" + getCheckSum(body) + "\r\n");
result.push("-----END PGP PRIVATE KEY BLOCK-----\r\n");
break;
case enums.armor.signature:
result.push("-----BEGIN PGP SIGNATURE-----\r\n");
result.push(base64.encode(body));
result.push("\r\n=" + getCheckSum(body) + "\r\n");
result.push("-----END PGP SIGNATURE-----\r\n");
break;
}
return result.join('');
}
export default {
encode: armor,
decode: dearmor
};

View file

@ -1,114 +0,0 @@
/* OpenPGP radix-64/base64 string encoding/decoding
* Copyright 2005 Herbert Hanewinkel, www.haneWIN.de
* version 1.0, check www.haneWIN.de for the latest version
*
* This software is provided as-is, without express or implied warranty.
* Permission to use, copy, modify, distribute or sell this software, with or
* without fee, for any purpose and by any individual or organization, is hereby
* granted, provided that the above copyright notice and this paragraph appear
* in all copies. Distribution as a part of an application or binary must
* include the above copyright notice in the documentation and/or other materials
* provided with the application or distribution.
*/
/**
* @module encoding/base64
*/
'use strict';
var b64s = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
/**
* Convert binary array to radix-64
* @param {Uint8Array} t Uint8Array to convert
* @returns {string} radix-64 version of input string
* @static
*/
function s2r(t, o) {
// TODO check btoa alternative
var a, c, n;
var r = o ? o : [],
l = 0,
s = 0;
var tl = t.length;
for (n = 0; n < tl; n++) {
c = t[n];
if (s === 0) {
r.push(b64s.charAt((c >> 2) & 63));
a = (c & 3) << 4;
} else if (s === 1) {
r.push(b64s.charAt((a | (c >> 4) & 15)));
a = (c & 15) << 2;
} else if (s === 2) {
r.push(b64s.charAt(a | ((c >> 6) & 3)));
l += 1;
if ((l % 60) === 0) {
r.push("\n");
}
r.push(b64s.charAt(c & 63));
}
l += 1;
if ((l % 60) === 0) {
r.push("\n");
}
s += 1;
if (s === 3) {
s = 0;
}
}
if (s > 0) {
r.push(b64s.charAt(a));
l += 1;
if ((l % 60) === 0) {
r.push("\n");
}
r.push('=');
l += 1;
}
if (s === 1) {
if ((l % 60) === 0) {
r.push("\n");
}
r.push('=');
}
if (o)
{
return;
}
return r.join('');
}
/**
* Convert radix-64 to binary array
* @param {String} t radix-64 string to convert
* @returns {Uint8Array} binary array version of input string
* @static
*/
function r2s(t) {
// TODO check atob alternative
var c, n;
var r = [],
s = 0,
a = 0;
var tl = t.length;
for (n = 0; n < tl; n++) {
c = b64s.indexOf(t.charAt(n));
if (c >= 0) {
if (s) {
r.push(a | (c >> (6 - s)) & 255);
}
s = (s + 2) & 7;
a = (c << s) & 255;
}
}
return new Uint8Array(r);
}
export default {
encode: s2r,
decode: r2s
};

View file

@ -1,328 +0,0 @@
'use strict';
/**
* @module enums
*/
export default {
/** A string to key specifier type
* @enum {Integer}
* @readonly
*/
s2k: {
simple: 0,
salted: 1,
iterated: 3,
gnu: 101
},
/** {@link http://tools.ietf.org/html/rfc4880#section-9.1|RFC4880, section 9.1}
* @enum {Integer}
* @readonly
*/
publicKey: {
rsa_encrypt_sign: 1,
rsa_encrypt: 2,
rsa_sign: 3,
elgamal: 16,
dsa: 17
},
/** {@link http://tools.ietf.org/html/rfc4880#section-9.2|RFC4880, section 9.2}
* @enum {Integer}
* @readonly
*/
symmetric: {
plaintext: 0,
/** Not implemented! */
idea: 1,
tripledes: 2,
cast5: 3,
blowfish: 4,
aes128: 7,
aes192: 8,
aes256: 9,
twofish: 10
},
/** {@link http://tools.ietf.org/html/rfc4880#section-9.3|RFC4880, section 9.3}
* @enum {Integer}
* @readonly
*/
compression: {
uncompressed: 0,
/** RFC1951 */
zip: 1,
/** RFC1950 */
zlib: 2,
bzip2: 3
},
/** {@link http://tools.ietf.org/html/rfc4880#section-9.4|RFC4880, section 9.4}
* @enum {Integer}
* @readonly
*/
hash: {
md5: 1,
sha1: 2,
ripemd: 3,
sha256: 8,
sha384: 9,
sha512: 10,
sha224: 11
},
/** A list of packet types and numeric tags associated with them.
* @enum {Integer}
* @readonly
*/
packet: {
publicKeyEncryptedSessionKey: 1,
signature: 2,
symEncryptedSessionKey: 3,
onePassSignature: 4,
secretKey: 5,
publicKey: 6,
secretSubkey: 7,
compressed: 8,
symmetricallyEncrypted: 9,
marker: 10,
literal: 11,
trust: 12,
userid: 13,
publicSubkey: 14,
userAttribute: 17,
symEncryptedIntegrityProtected: 18,
modificationDetectionCode: 19,
symEncryptedAEADProtected: 20 // see IETF draft: https://tools.ietf.org/html/draft-ford-openpgp-format-00#section-2.1
},
/** Data types in the literal packet
* @enum {Integer}
* @readonly
*/
literal: {
/** Binary data 'b' */
binary: 'b'.charCodeAt(),
/** Text data 't' */
text: 't'.charCodeAt(),
/** Utf8 data 'u' */
utf8: 'u'.charCodeAt()
},
/** One pass signature packet type
* @enum {Integer}
* @readonly
*/
signature: {
/** 0x00: Signature of a binary document. */
binary: 0,
/** 0x01: Signature of a canonical text document.<br/>
* Canonicalyzing the document by converting line endings. */
text: 1,
/** 0x02: Standalone signature.<br/>
* This signature is a signature of only its own subpacket contents.
* It is calculated identically to a signature over a zero-lengh
* binary document. Note that it doesn't make sense to have a V3
* standalone signature. */
standalone: 2,
/** 0x10: Generic certification of a User ID and Public-Key packet.<br/>
* The issuer of this certification does not make any particular
* assertion as to how well the certifier has checked that the owner
* of the key is in fact the person described by the User ID. */
cert_generic: 16,
/** 0x11: Persona certification of a User ID and Public-Key packet.<br/>
* The issuer of this certification has not done any verification of
* the claim that the owner of this key is the User ID specified. */
cert_persona: 17,
/** 0x12: Casual certification of a User ID and Public-Key packet.<br/>
* The issuer of this certification has done some casual
* verification of the claim of identity. */
cert_casual: 18,
/** 0x13: Positive certification of a User ID and Public-Key packet.<br/>
* The issuer of this certification has done substantial
* verification of the claim of identity.<br/>
* <br/>
* Most OpenPGP implementations make their "key signatures" as 0x10
* certifications. Some implementations can issue 0x11-0x13
* certifications, but few differentiate between the types. */
cert_positive: 19,
/** 0x30: Certification revocation signature<br/>
* This signature revokes an earlier User ID certification signature
* (signature class 0x10 through 0x13) or direct-key signature
* (0x1F). It should be issued by the same key that issued the
* revoked signature or an authorized revocation key. The signature
* is computed over the same data as the certificate that it
* revokes, and should have a later creation date than that
* certificate. */
cert_revocation: 48,
/** 0x18: Subkey Binding Signature<br/>
* This signature is a statement by the top-level signing key that
* indicates that it owns the subkey. This signature is calculated
* directly on the primary key and subkey, and not on any User ID or
* other packets. A signature that binds a signing subkey MUST have
* an Embedded Signature subpacket in this binding signature that
* contains a 0x19 signature made by the signing subkey on the
* primary key and subkey. */
subkey_binding: 24,
/** 0x19: Primary Key Binding Signature<br/>
* This signature is a statement by a signing subkey, indicating
* that it is owned by the primary key and subkey. This signature
* is calculated the same way as a 0x18 signature: directly on the
* primary key and subkey, and not on any User ID or other packets.<br/>
* <br/>
* When a signature is made over a key, the hash data starts with the
* octet 0x99, followed by a two-octet length of the key, and then body
* of the key packet. (Note that this is an old-style packet header for
* a key packet with two-octet length.) A subkey binding signature
* (type 0x18) or primary key binding signature (type 0x19) then hashes
* the subkey using the same format as the main key (also using 0x99 as
* the first octet). */
key_binding: 25,
/** 0x1F: Signature directly on a key<br/>
* This signature is calculated directly on a key. It binds the
* information in the Signature subpackets to the key, and is
* appropriate to be used for subpackets that provide information
* about the key, such as the Revocation Key subpacket. It is also
* appropriate for statements that non-self certifiers want to make
* about the key itself, rather than the binding between a key and a
* name. */
key: 31,
/** 0x20: Key revocation signature<br/>
* The signature is calculated directly on the key being revoked. A
* revoked key is not to be used. Only revocation signatures by the
* key being revoked, or by an authorized revocation key, should be
* considered valid revocation signatures.a */
key_revocation: 32,
/** 0x28: Subkey revocation signature<br/>
* The signature is calculated directly on the subkey being revoked.
* A revoked subkey is not to be used. Only revocation signatures
* by the top-level signature key that is bound to this subkey, or
* by an authorized revocation key, should be considered valid
* revocation signatures.<br/>
* <br/>
* Key revocation signatures (types 0x20 and 0x28)
* hash only the key being revoked. */
subkey_revocation: 40,
/** 0x40: Timestamp signature.<br/>
* This signature is only meaningful for the timestamp contained in
* it. */
timestamp: 64,
/** 0x50: Third-Party Confirmation signature.<br/>
* This signature is a signature over some other OpenPGP Signature
* packet(s). It is analogous to a notary seal on the signed data.
* A third-party signature SHOULD include Signature Target
* subpacket(s) to give easy identification. Note that we really do
* mean SHOULD. There are plausible uses for this (such as a blind
* party that only sees the signature, not the key or source
* document) that cannot include a target subpacket. */
third_party: 80
},
/** Signature subpacket type
* @enum {Integer}
* @readonly
*/
signatureSubpacket: {
signature_creation_time: 2,
signature_expiration_time: 3,
exportable_certification: 4,
trust_signature: 5,
regular_expression: 6,
revocable: 7,
key_expiration_time: 9,
placeholder_backwards_compatibility: 10,
preferred_symmetric_algorithms: 11,
revocation_key: 12,
issuer: 16,
notation_data: 20,
preferred_hash_algorithms: 21,
preferred_compression_algorithms: 22,
key_server_preferences: 23,
preferred_key_server: 24,
primary_user_id: 25,
policy_uri: 26,
key_flags: 27,
signers_user_id: 28,
reason_for_revocation: 29,
features: 30,
signature_target: 31,
embedded_signature: 32
},
/** Key flags
* @enum {Integer}
* @readonly
*/
keyFlags: {
/** 0x01 - This key may be used to certify other keys. */
certify_keys: 1,
/** 0x02 - This key may be used to sign data. */
sign_data: 2,
/** 0x04 - This key may be used to encrypt communications. */
encrypt_communication: 4,
/** 0x08 - This key may be used to encrypt storage. */
encrypt_storage: 8,
/** 0x10 - The private component of this key may have been split
* by a secret-sharing mechanism. */
split_private_key: 16,
/** 0x20 - This key may be used for authentication. */
authentication: 32,
/** 0x80 - The private component of this key may be in the
* possession of more than one person. */
shared_private_key: 128
},
/** Key status
* @enum {Integer}
* @readonly
*/
keyStatus: {
invalid: 0,
expired: 1,
revoked: 2,
valid: 3,
no_self_cert: 4
},
/** Armor type
* @enum {Integer}
* @readonly
*/
armor: {
multipart_section: 0,
multipart_last: 1,
signed: 2,
message: 3,
public_key: 4,
private_key: 5,
signature: 6
},
/** Asserts validity and converts from string/integer to integer. */
write: function(type, e) {
if (typeof e === 'number') {
e = this.read(type, e);
}
if (type[e] !== undefined) {
return type[e];
} else {
throw new Error('Invalid enum value.');
}
},
/** Converts from an integer to string. */
read: function(type, e) {
for (var i in type) {
if (type[i] === parseInt(e)) {
return i;
}
}
throw new Error('Invalid enum value.');
}
};

View file

@ -1,86 +0,0 @@
// OpenPGP.js - An OpenPGP implementation in javascript
// Copyright (C) 2015 Tankred Hase
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// 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,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
/**
* @fileoverview This class implements a client for the OpenPGP HTTP Keyserver Protocol (HKP)
* in order to lookup and upload keys on standard public key servers.
*/
'use strict';
import config from './config';
/**
* Initialize the HKP client and configure it with the key server url and fetch function.
* @constructor
* @param {String} keyServerBaseUrl (optional) The HKP key server base url including
* the protocol to use e.g. https://pgp.mit.edu
*/
export default function HKP(keyServerBaseUrl) {
this._baseUrl = keyServerBaseUrl ? keyServerBaseUrl : config.keyserver;
this._fetch = window.fetch;
}
/**
* Search for a public key on the key server either by key ID or part of the user ID.
* @param {String} options.keyID The long public key ID.
* @param {String} options.query This can be any part of the key user ID such as name
* or email address.
* @return {Promise<String>} The ascii armored public key.
*/
HKP.prototype.lookup = function(options) {
var uri = this._baseUrl + '/pks/lookup?op=get&options=mr&search=',
fetch = this._fetch;
if (options.keyId) {
uri += '0x' + encodeURIComponent(options.keyId);
} else if (options.query) {
uri += encodeURIComponent(options.query);
} else {
throw new Error('You must provide a query parameter!');
}
return fetch(uri).then(function(response) {
if (response.status === 200) {
return response.text();
}
}).then(function(publicKeyArmored) {
if (!publicKeyArmored || publicKeyArmored.indexOf('-----END PGP PUBLIC KEY BLOCK-----') < 0) {
return;
}
return publicKeyArmored.trim();
});
};
/**
* Upload a public key to the server.
* @param {String} publicKeyArmored An ascii armored public key to be uploaded.
* @return {Promise}
*/
HKP.prototype.upload = function(publicKeyArmored) {
var uri = this._baseUrl + '/pks/add',
fetch = this._fetch;
return fetch(uri, {
method: 'post',
headers: {
'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'
},
body: 'keytext=' + encodeURIComponent(publicKeyArmored)
});
};

View file

@ -1,120 +0,0 @@
'use strict';
/**
* Export high level api as default.
* Usage:
*
* import openpgp from 'openpgp.js'
* openpgp.encryptMessage(keys, text)
*/
import * as openpgp from './openpgp';
export default openpgp;
/**
* Export each high level api function seperately.
* Usage:
*
* import { encryptMessage } from 'openpgp.js'
* encryptMessage(keys, text)
*/
export * from './openpgp';
/**
* @see module:key
* @name module:openpgp.key
*/
import * as keyMod from './key';
export const key = keyMod;
/**
* @see module:signature
* @name module:openpgp.signature
*/
import * as signatureMod from './signature';
export const signature = signatureMod;
/**
* @see module:message
* @name module:openpgp.message
*/
import * as messageMod from './message';
export const message = messageMod;
/**
* @see module:cleartext
* @name module:openpgp.cleartext
*/
import * as cleartextMod from './cleartext';
export const cleartext = cleartextMod;
/**
* @see module:util
* @name module:openpgp.util
*/
export { default as util } from './util';
/**
* @see module:packet
* @name module:openpgp.packet
*/
export { default as packet } from './packet';
/**
* @see module:type/mpi
* @name module:openpgp.MPI
*/
export { default as MPI } from './type/mpi';
/**
* @see module:type/s2k
* @name module:openpgp.S2K
*/
export { default as S2K } from './type/s2k';
/**
* @see module:type/keyid
* @name module:openpgp.Keyid
*/
export { default as Keyid } from './type/keyid';
/**
* @see module:encoding/armor
* @name module:openpgp.armor
*/
export { default as armor } from './encoding/armor';
/**
* @see module:enums
* @name module:openpgp.enums
*/
export { default as enums } from './enums';
/**
* @see module:config/config
* @name module:openpgp.config
*/
export { default as config } from './config/config';
/**
* @see module:crypto
* @name module:openpgp.crypto
*/
export { default as crypto } from './crypto';
/**
* @see module:keyring
* @name module:openpgp.Keyring
*/
export { default as Keyring } from './keyring';
/**
* @see module:worker/async_proxy
* @name module:openpgp.AsyncProxy
*/
export { default as AsyncProxy } from './worker/async_proxy';
/**
* @see module:hkp
* @name module:openpgp.HKP
*/
export { default as HKP } from './hkp';

File diff suppressed because it is too large Load diff

View file

@ -1,12 +0,0 @@
'use strict';
/**
* @see module:keyring/keyring
* @module keyring
*/
import Keyring from './keyring.js';
import localstore from './localstore.js';
Keyring.localstore = localstore;
export default Keyring;

View file

@ -1,227 +0,0 @@
// GPG4Browsers - An OpenPGP implementation in javascript
// Copyright (C) 2011 Recurity Labs GmbH
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// 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,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
/**
* The class that deals with storage of the keyring. Currently the only option is to use HTML5 local storage.
* @requires enums
* @requires key
* @requires util
* @module keyring/keyring
*/
'use strict';
import * as keyModule from '../key.js';
import LocalStore from './localstore.js';
/**
* Initialization routine for the keyring. This method reads the
* keyring from HTML5 local storage and initializes this instance.
* @constructor
* @param {class} [storeHandler] class implementing loadPublic(), loadPrivate(), storePublic(), and storePrivate() methods
*/
export default class Keyring
{
constructor(storeHandler) {
this.storeHandler = storeHandler || new LocalStore();
this.publicKeys = new KeyArray(this.storeHandler.loadPublic());
this.privateKeys = new KeyArray(this.storeHandler.loadPrivate());
}
/**
* Calls the storeHandler to save the keys
*/
store() {
this.storeHandler.storePublic(this.publicKeys.keys);
this.storeHandler.storePrivate(this.privateKeys.keys);
}
/**
* Clear the keyring - erase all the keys
*/
clear() {
this.publicKeys.keys = [];
this.privateKeys.keys = [];
}
/**
* Searches the keyring for keys having the specified key id
* @param {String} keyId provided as string of lowercase hex number
* withouth 0x prefix (can be 16-character key ID or fingerprint)
* @param {Boolean} deep if true search also in subkeys
* @returns {Array<module:key.Key>|null} keys found or null
*/
getKeysForId(keyId, deep) {
var result = [];
result = result.concat(this.publicKeys.getForId(keyId, deep) || []);
result = result.concat(this.privateKeys.getForId(keyId, deep) || []);
return result.length ? result : null;
}
/**
* Removes keys having the specified key id from the keyring
* @param {String} keyId provided as string of lowercase hex number
* withouth 0x prefix (can be 16-character key ID or fingerprint)
* @returns {Array<module:key.Key>|null} keys found or null
*/
removeKeysForId(keyId) {
var result = [];
result = result.concat(this.publicKeys.removeForId(keyId) || []);
result = result.concat(this.privateKeys.removeForId(keyId) || []);
return result.length ? result : null;
}
/**
* Get all public and private keys
* @returns {Array<module:key.Key>} all keys
*/
getAllKeys() {
return this.publicKeys.keys.concat(this.privateKeys.keys);
}
}
/**
* Checks a key to see if it matches the specified email address
* @private
* @param {String} email email address to search for
* @param {module:key.Key} key The key to be checked.
* @returns {Boolean} True if the email address is defined in the specified key
*/
function emailCheck(email, key) {
email = email.toLowerCase();
// escape email before using in regular expression
var emailEsc = email.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
var emailRegex = new RegExp('<' + emailEsc + '>');
var userIds = key.getUserIds();
for (var i = 0; i < userIds.length; i++) {
var userId = userIds[i].toLowerCase();
if (email === userId || emailRegex.test(userId)) {
return true;
}
}
return false;
}
/**
* Checks a key to see if it matches the specified keyid
* @private
* @param {String} keyId provided as string of lowercase hex number
* withouth 0x prefix (can be 16-character key ID or fingerprint)
* @param {module:packet/secret_key|public_key|public_subkey|secret_subkey} keypacket The keypacket to be checked
* @returns {Boolean} True if keypacket has the specified keyid
*/
function keyIdCheck(keyId, keypacket) {
if (keyId.length === 16) {
return keyId === keypacket.getKeyId().toHex();
} else {
return keyId === keypacket.getFingerprint();
}
}
/**
* Array of keys
* @param {Array<module:key.Key>} keys The keys to store in this array
*/
class KeyArray
{
constructor(keys) {
this.keys = keys;
}
/**
* Searches all keys in the KeyArray matching the address or address part of the user ids
* @param {String} email email address to search for
* @returns {Array<module:key.Key>} The public keys associated with provided email address.
*/
getForAddress(email) {
var results = [];
for (var i = 0; i < this.keys.length; i++) {
if (emailCheck(email, this.keys[i])) {
results.push(this.keys[i]);
}
}
return results;
}
/**
* Searches the KeyArray for a key having the specified key id
* @param {String} keyId provided as string of lowercase hex number
* withouth 0x prefix (can be 16-character key ID or fingerprint)
* @param {Boolean} deep if true search also in subkeys
* @returns {module:key.Key|null} key found or null
*/
getForId(keyId, deep) {
for (var i = 0; i < this.keys.length; i++) {
if (keyIdCheck(keyId, this.keys[i].primaryKey)) {
return this.keys[i];
}
if (deep && this.keys[i].subKeys) {
for (var j = 0; j < this.keys[i].subKeys.length; j++) {
if (keyIdCheck(keyId, this.keys[i].subKeys[j].subKey)) {
return this.keys[i];
}
}
}
}
return null;
}
/**
* Imports a key from an ascii armored message
* @param {String} armored message to read the keys/key from
* @returns {Array<Error>|null} array of error objects or null
*/
importKey(armored) {
var imported = keyModule.readArmored(armored);
var that = this;
imported.keys.forEach(function(key) {
// check if key already in key array
var keyidHex = key.primaryKey.getKeyId().toHex();
var keyFound = that.getForId(keyidHex);
if (keyFound) {
keyFound.update(key);
} else {
that.push(key);
}
});
return imported.err ? imported.err : null;
}
/**
* Add key to KeyArray
* @param {module:key.Key} key The key that will be added to the keyring
* @returns {Number} The new length of the KeyArray
*/
push(key) {
return this.keys.push(key);
}
/**
* Removes a key with the specified keyid from the keyring
* @param {String} keyId provided as string of lowercase hex number
* withouth 0x prefix (can be 16-character key ID or fingerprint)
* @returns {module:key.Key|null} The key object which has been removed or null
*/
removeForId(keyId) {
for (let i = 0; i < this.keys.length; i++) {
if (keyIdCheck(keyId, this.keys[i].primaryKey)) {
return this.keys.splice(i, 1)[0];
}
}
return null;
}
}

View file

@ -1,105 +0,0 @@
// GPG4Browsers - An OpenPGP implementation in javascript
// Copyright (C) 2011 Recurity Labs GmbH
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// 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,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
/**
* The class that deals with storage of the keyring. Currently the only option is to use HTML5 local storage.
* @requires config
* @module keyring/localstore
* @param {String} prefix prefix for itemnames in localstore
*/
'use strict';
import * as keyModule from '../key.js';
import util from '../util.js';
function loadKeys(storage, itemname) {
var armoredKeys = JSON.parse(storage.getItem(itemname));
var keys = [];
if (armoredKeys !== null && armoredKeys.length !== 0) {
var key;
for (var i = 0; i < armoredKeys.length; i++) {
key = keyModule.readArmored(armoredKeys[i]);
if (!key.err) {
keys.push(key.keys[0]);
}
}
}
return keys;
}
function storeKeys(storage, itemname, keys) {
var armoredKeys = [];
if (keys.length) {
for (var i = 0; i < keys.length; i++) {
armoredKeys.push(keys[i].armor());
}
storage.setItem(itemname, JSON.stringify(armoredKeys));
} else {
storage.removeItem(itemname);
}
}
export default class LocalStore
{
constructor(prefix) {
prefix = prefix || 'openpgp-';
this.publicKeysItem = prefix + this.publicKeysItem;
this.privateKeysItem = prefix + this.privateKeysItem;
this.storage = window.localStorage;
}
/**
* Load the public keys from HTML5 local storage.
* @return {Array<module:key~Key>} array of keys retrieved from localstore
*/
loadPublic() {
return loadKeys(this.storage, this.publicKeysItem);
}
/**
* Load the private keys from HTML5 local storage.
* @return {Array<module:key~Key>} array of keys retrieved from localstore
*/
loadPrivate() {
return loadKeys(this.storage, this.privateKeysItem);
}
/**
* Saves the current state of the public keys to HTML5 local storage.
* The key array gets stringified using JSON
* @param {Array<module:key~Key>} keys array of keys to save in localstore
*/
storePublic(keys) {
storeKeys(this.storage, this.publicKeysItem, keys);
}
/**
* Saves the current state of the private keys to HTML5 local storage.
* The key array gets stringified using JSON
* @param {Array<module:key~Key>} keys array of keys to save in localstore
*/
storePrivate(keys) {
storeKeys(this.storage, this.privateKeysItem, keys);
}
}
/*
* Declare the localstore itemnames
*/
LocalStore.prototype.publicKeysItem = 'public-keys';
LocalStore.prototype.privateKeysItem = 'private-keys';

View file

@ -1,598 +0,0 @@
// GPG4Browsers - An OpenPGP implementation in javascript
// Copyright (C) 2011 Recurity Labs GmbH
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// 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,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
/**
* @requires config
* @requires crypto
* @requires encoding/armor
* @requires enums
* @requires packet
* @module message
*/
'use strict';
import util from './util.js';
import packet from './packet';
import enums from './enums.js';
import armor from './encoding/armor.js';
import config from './config';
import crypto from './crypto';
import * as sigModule from './signature.js';
import * as keyModule from './key.js';
/**
* @class
* @classdesc Class that represents an OpenPGP message.
* Can be an encrypted message, signed message, compressed message or literal message
* @param {module:packet/packetlist} packetlist The packets that form this message
* See {@link http://tools.ietf.org/html/rfc4880#section-11.3}
*/
export function Message(packetlist) {
if (!(this instanceof Message)) {
return new Message(packetlist);
}
this.packets = packetlist || new packet.List();
}
/**
* Returns the key IDs of the keys to which the session key is encrypted
* @return {Array<module:type/keyid>} array of keyid objects
*/
Message.prototype.getEncryptionKeyIds = function() {
var keyIds = [];
var pkESKeyPacketlist = this.packets.filterByTag(enums.packet.publicKeyEncryptedSessionKey);
pkESKeyPacketlist.forEach(function(packet) {
keyIds.push(packet.publicKeyId);
});
return keyIds;
};
/**
* Returns the key IDs of the keys that signed the message
* @return {Array<module:type/keyid>} array of keyid objects
*/
Message.prototype.getSigningKeyIds = function() {
var keyIds = [];
var msg = this.unwrapCompressed();
// search for one pass signatures
var onePassSigList = msg.packets.filterByTag(enums.packet.onePassSignature);
onePassSigList.forEach(function(packet) {
keyIds.push(packet.signingKeyId);
});
// if nothing found look for signature packets
if (!keyIds.length) {
var signatureList = msg.packets.filterByTag(enums.packet.signature);
signatureList.forEach(function(packet) {
keyIds.push(packet.issuerKeyId);
});
}
return keyIds;
};
/**
* Decrypt the message. Either a private key, a session key, or a password must be specified.
* @param {Key} privateKey (optional) private key with decrypted secret data
* @param {Object} sessionKey (optional) session key in the form: { data:Uint8Array, algorithm:String }
* @param {String} password (optional) password used to decrypt
* @return {Message} new message with decrypted content
*/
Message.prototype.decrypt = function(privateKey, sessionKey, password) {
return Promise.resolve().then(() => {
const keyObj = sessionKey || this.decryptSessionKey(privateKey, password);
if (!keyObj || !util.isUint8Array(keyObj.data) || !util.isString(keyObj.algorithm)) {
throw new Error('Invalid session key for decryption.');
}
const symEncryptedPacketlist = this.packets.filterByTag(
enums.packet.symmetricallyEncrypted,
enums.packet.symEncryptedIntegrityProtected,
enums.packet.symEncryptedAEADProtected
);
if (symEncryptedPacketlist.length === 0) {
return;
}
const symEncryptedPacket = symEncryptedPacketlist[0];
return symEncryptedPacket.decrypt(keyObj.algorithm, keyObj.data).then(() => {
const resultMsg = new Message(symEncryptedPacket.packets);
symEncryptedPacket.packets = new packet.List(); // remove packets after decryption
return resultMsg;
});
});
};
/**
* Decrypt an encrypted session key either with a private key or a password.
* @param {Key} privateKey (optional) private key with decrypted secret data
* @param {String} password (optional) password used to decrypt
* @return {Object} object with sessionKey, algorithm in the form:
* { data:Uint8Array, algorithm:String }
*/
Message.prototype.decryptSessionKey = function(privateKey, password) {
var keyPacket;
if (password) {
var symEncryptedSessionKeyPacketlist = this.packets.filterByTag(enums.packet.symEncryptedSessionKey);
var symLength = symEncryptedSessionKeyPacketlist.length;
for (var i = 0; i < symLength; i++) {
keyPacket = symEncryptedSessionKeyPacketlist[i];
try {
keyPacket.decrypt(password);
break;
}
catch(err) {
if (i === (symLength - 1)) {
throw err;
}
}
}
if (!keyPacket) {
throw new Error('No symmetrically encrypted session key packet found.');
}
} else if (privateKey) {
var encryptionKeyIds = this.getEncryptionKeyIds();
if (!encryptionKeyIds.length) {
// nothing to decrypt
return;
}
var privateKeyPacket = privateKey.getKeyPacket(encryptionKeyIds);
if (!privateKeyPacket.isDecrypted) {
throw new Error('Private key is not decrypted.');
}
var pkESKeyPacketlist = this.packets.filterByTag(enums.packet.publicKeyEncryptedSessionKey);
for (var j = 0; j < pkESKeyPacketlist.length; j++) {
if (pkESKeyPacketlist[j].publicKeyId.equals(privateKeyPacket.getKeyId())) {
keyPacket = pkESKeyPacketlist[j];
keyPacket.decrypt(privateKeyPacket);
break;
}
}
} else {
throw new Error('No key or password specified.');
}
if (keyPacket) {
return {
data: keyPacket.sessionKey,
algorithm: keyPacket.sessionKeyAlgorithm
};
}
};
/**
* Get literal data that is the body of the message
* @return {(Uint8Array|null)} literal body of the message as Uint8Array
*/
Message.prototype.getLiteralData = function() {
var literal = this.packets.findPacket(enums.packet.literal);
return literal && literal.data || null;
};
/**
* Get filename from literal data packet
* @return {(String|null)} filename of literal data packet as string
*/
Message.prototype.getFilename = function() {
var literal = this.packets.findPacket(enums.packet.literal);
return literal && literal.getFilename() || null;
};
/**
* Get literal data as text
* @return {(String|null)} literal body of the message interpreted as text
*/
Message.prototype.getText = function() {
var literal = this.packets.findPacket(enums.packet.literal);
if (literal) {
return literal.getText();
} else {
return null;
}
};
/**
* Encrypt the message either with public keys, passwords, or both at once.
* @param {Array<Key>} keys (optional) public key(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 }
* @return {Message} new message with encrypted content
*/
Message.prototype.encrypt = function(keys, passwords, sessionKey) {
let symAlgo, msg, symEncryptedPacket;
return Promise.resolve().then(() => {
if (sessionKey) {
if (!util.isUint8Array(sessionKey.data) || !util.isString(sessionKey.algorithm)) {
throw new Error('Invalid session key for encryption.');
}
symAlgo = sessionKey.algorithm;
sessionKey = sessionKey.data;
} else if (keys && keys.length) {
symAlgo = enums.read(enums.symmetric, keyModule.getPreferredSymAlgo(keys));
} else if (passwords && passwords.length) {
symAlgo = enums.read(enums.symmetric, config.encryption_cipher);
} else {
throw new Error('No keys, passwords, or session key provided.');
}
if (!sessionKey) {
sessionKey = crypto.generateSessionKey(symAlgo);
}
msg = encryptSessionKey(sessionKey, symAlgo, keys, passwords);
if (config.aead_protect) {
symEncryptedPacket = new packet.SymEncryptedAEADProtected();
} else if (config.integrity_protect) {
symEncryptedPacket = new packet.SymEncryptedIntegrityProtected();
} else {
symEncryptedPacket = new packet.SymmetricallyEncrypted();
}
symEncryptedPacket.packets = this.packets;
return symEncryptedPacket.encrypt(symAlgo, sessionKey);
}).then(() => {
msg.packets.push(symEncryptedPacket);
symEncryptedPacket.packets = new packet.List(); // remove packets after encryption
return {
message: msg,
sessionKey: {
data: sessionKey,
algorithm: symAlgo
}
};
});
};
/**
* Encrypt a session key either with public keys, passwords, or both at once.
* @param {Uint8Array} sessionKey session key for encryption
* @param {String} symAlgo session key algorithm
* @param {Array<Key>} publicKeys (optional) public key(s) for message encryption
* @param {Array<String>} passwords (optional) for message encryption
* @return {Message} new message with encrypted content
*/
export function encryptSessionKey(sessionKey, symAlgo, publicKeys, passwords) {
var packetlist = new packet.List();
if (publicKeys) {
publicKeys.forEach(function(key) {
var encryptionKeyPacket = key.getEncryptionKeyPacket();
if (encryptionKeyPacket) {
var pkESKeyPacket = new packet.PublicKeyEncryptedSessionKey();
pkESKeyPacket.publicKeyId = encryptionKeyPacket.getKeyId();
pkESKeyPacket.publicKeyAlgorithm = encryptionKeyPacket.algorithm;
pkESKeyPacket.sessionKey = sessionKey;
pkESKeyPacket.sessionKeyAlgorithm = symAlgo;
pkESKeyPacket.encrypt(encryptionKeyPacket);
delete pkESKeyPacket.sessionKey; // delete plaintext session key after encryption
packetlist.push(pkESKeyPacket);
} else {
throw new Error('Could not find valid key packet for encryption in key ' + key.primaryKey.getKeyId().toHex());
}
});
}
if (passwords) {
passwords.forEach(function(password) {
var symEncryptedSessionKeyPacket = new packet.SymEncryptedSessionKey();
symEncryptedSessionKeyPacket.sessionKey = sessionKey;
symEncryptedSessionKeyPacket.sessionKeyAlgorithm = symAlgo;
symEncryptedSessionKeyPacket.encrypt(password);
delete symEncryptedSessionKeyPacket.sessionKey; // delete plaintext session key after encryption
packetlist.push(symEncryptedSessionKeyPacket);
});
}
return new Message(packetlist);
}
/**
* Sign the message (the literal data packet of the message)
* @param {Array<module:key~Key>} privateKey private keys with decrypted secret key data for signing
* @param {Signature} signature (optional) any existing detached signature to add to the message
* @return {module:message~Message} new message with signed content
*/
Message.prototype.sign = function(privateKeys=[], signature=null) {
var packetlist = new packet.List();
var literalDataPacket = this.packets.findPacket(enums.packet.literal);
if (!literalDataPacket) {
throw new Error('No literal data packet to sign.');
}
var literalFormat = enums.write(enums.literal, literalDataPacket.format);
var signatureType = literalFormat === enums.literal.binary ?
enums.signature.binary : enums.signature.text;
var i, signingKeyPacket, existingSigPacketlist, onePassSig;
if (signature) {
existingSigPacketlist = signature.packets.filterByTag(enums.packet.signature);
if (existingSigPacketlist.length) {
for (i = existingSigPacketlist.length - 1; i >= 0; i--) {
var sigPacket = existingSigPacketlist[i];
onePassSig = new packet.OnePassSignature();
onePassSig.type = signatureType;
onePassSig.hashAlgorithm = config.prefer_hash_algorithm;
onePassSig.publicKeyAlgorithm = sigPacket.publicKeyAlgorithm;
onePassSig.signingKeyId = sigPacket.issuerKeyId;
if (!privateKeys.length && i === 0) {
onePassSig.flags = 1;
}
packetlist.push(onePassSig);
}
}
}
for (i = 0; i < privateKeys.length; i++) {
if (privateKeys[i].isPublic()) {
throw new Error('Need private key for signing');
}
onePassSig = new packet.OnePassSignature();
onePassSig.type = signatureType;
//TODO get preferred hashg algo from key signature
onePassSig.hashAlgorithm = config.prefer_hash_algorithm;
signingKeyPacket = privateKeys[i].getSigningKeyPacket();
if (!signingKeyPacket) {
throw new Error('Could not find valid key packet for signing in key ' + privateKeys[i].primaryKey.getKeyId().toHex());
}
onePassSig.publicKeyAlgorithm = signingKeyPacket.algorithm;
onePassSig.signingKeyId = signingKeyPacket.getKeyId();
if (i === privateKeys.length - 1) {
onePassSig.flags = 1;
}
packetlist.push(onePassSig);
}
packetlist.push(literalDataPacket);
for (i = privateKeys.length - 1; i >= 0; i--) {
var signaturePacket = new packet.Signature();
signaturePacket.signatureType = signatureType;
signaturePacket.hashAlgorithm = config.prefer_hash_algorithm;
signaturePacket.publicKeyAlgorithm = signingKeyPacket.algorithm;
if (!signingKeyPacket.isDecrypted) {
throw new Error('Private key is not decrypted.');
}
signaturePacket.sign(signingKeyPacket, literalDataPacket);
packetlist.push(signaturePacket);
}
if (signature) {
packetlist.concat(existingSigPacketlist);
}
return new Message(packetlist);
};
/**
* Create a detached signature for the message (the literal data packet of the message)
* @param {Array<module:key~Key>} privateKey private keys with decrypted secret key data for signing
* @param {Signature} signature (optional) any existing detached signature
* @return {module:signature~Signature} new detached signature of message content
*/
Message.prototype.signDetached = function(privateKeys=[], signature=null) {
var packetlist = new packet.List();
var literalDataPacket = this.packets.findPacket(enums.packet.literal);
if (!literalDataPacket) {
throw new Error('No literal data packet to sign.');
}
var literalFormat = enums.write(enums.literal, literalDataPacket.format);
var signatureType = literalFormat === enums.literal.binary ?
enums.signature.binary : enums.signature.text;
for (var i = 0; i < privateKeys.length; i++) {
var signingKeyPacket = privateKeys[i].getSigningKeyPacket();
var signaturePacket = new packet.Signature();
signaturePacket.signatureType = signatureType;
signaturePacket.hashAlgorithm = config.prefer_hash_algorithm;
signaturePacket.publicKeyAlgorithm = signingKeyPacket.algorithm;
if (!signingKeyPacket.isDecrypted) {
throw new Error('Private key is not decrypted.');
}
signaturePacket.sign(signingKeyPacket, literalDataPacket);
packetlist.push(signaturePacket);
}
if (signature) {
var existingSigPacketlist = signature.packets.filterByTag(enums.packet.signature);
packetlist.concat(existingSigPacketlist);
}
return new sigModule.Signature(packetlist);
};
/**
* Verify message signatures
* @param {Array<module:key~Key>} keys array of keys to verify signatures
* @return {Array<({keyid: module:type/keyid, valid: Boolean})>} list of signer's keyid and validity of signature
*/
Message.prototype.verify = function(keys) {
var msg = this.unwrapCompressed();
var literalDataList = msg.packets.filterByTag(enums.packet.literal);
if (literalDataList.length !== 1) {
throw new Error('Can only verify message with one literal data packet.');
}
var signatureList = msg.packets.filterByTag(enums.packet.signature);
return createVerificationObjects(signatureList, literalDataList, keys);
};
/**
* Verify detached message signature
* @param {Array<module:key~Key>} keys array of keys to verify signatures
* @param {Signature}
* @return {Array<({keyid: module:type/keyid, valid: Boolean})>} list of signer's keyid and validity of signature
*/
Message.prototype.verifyDetached = function(signature, keys) {
var msg = this.unwrapCompressed();
var literalDataList = msg.packets.filterByTag(enums.packet.literal);
if (literalDataList.length !== 1) {
throw new Error('Can only verify message with one literal data packet.');
}
var signatureList = signature.packets;
return createVerificationObjects(signatureList, literalDataList, keys);
};
/**
* Create list of objects containing signer's keyid and validity of signature
* @param {Array<module:packet/signature>} signatureList array of signature packets
* @param {Array<module:packet/literal>} literalDataList array of literal data packets
* @param {Array<module:key~Key>} keys array of keys to verify signatures
* @return {Array<({keyid: module:type/keyid, valid: Boolean})>} list of signer's keyid and validity of signature
*/
function createVerificationObjects(signatureList, literalDataList, keys) {
var result = [];
for (var i = 0; i < signatureList.length; i++) {
var keyPacket = null;
for (var j = 0; j < keys.length; j++) {
keyPacket = keys[j].getSigningKeyPacket(signatureList[i].issuerKeyId, config.verify_expired_keys);
if (keyPacket) {
break;
}
}
var verifiedSig = {};
if (keyPacket) {
//found a key packet that matches keyId of signature
verifiedSig.keyid = signatureList[i].issuerKeyId;
verifiedSig.valid = signatureList[i].verify(keyPacket, literalDataList[0]);
} else {
verifiedSig.keyid = signatureList[i].issuerKeyId;
verifiedSig.valid = null;
}
var packetlist = new packet.List();
packetlist.push(signatureList[i]);
verifiedSig.signature = new sigModule.Signature(packetlist);
result.push(verifiedSig);
}
return result;
}
/**
* Unwrap compressed message
* @return {module:message~Message} message Content of compressed message
*/
Message.prototype.unwrapCompressed = function() {
var compressed = this.packets.filterByTag(enums.packet.compressed);
if (compressed.length) {
return new Message(compressed[0].packets);
} else {
return this;
}
};
/**
* Returns ASCII armored text of message
* @return {String} ASCII armor
*/
Message.prototype.armor = function() {
return armor.encode(enums.armor.message, this.packets.write());
};
/**
* reads an OpenPGP armored message and returns a message object
* @param {String} armoredText text to be parsed
* @return {module:message~Message} new message object
* @static
*/
export function readArmored(armoredText) {
//TODO how do we want to handle bad text? Exception throwing
//TODO don't accept non-message armored texts
var input = armor.decode(armoredText).data;
return read(input);
}
/**
* reads an OpenPGP message as byte array and returns a message object
* @param {Uint8Array} input binary message
* @return {Message} new message object
* @static
*/
export function read(input) {
var packetlist = new packet.List();
packetlist.read(input);
return new Message(packetlist);
}
/**
* Create a message object from signed content and a detached armored signature.
* @param {String} content An 8 bit ascii string containing e.g. a MIME subtree with text nodes or attachments
* @param {String} detachedSignature The detached ascii armored PGP signature
*/
export function readSignedContent(content, detachedSignature) {
var literalDataPacket = new packet.Literal();
literalDataPacket.setBytes(util.str2Uint8Array(content), enums.read(enums.literal, enums.literal.binary));
var packetlist = new packet.List();
packetlist.push(literalDataPacket);
var input = armor.decode(detachedSignature).data;
packetlist.read(input);
return new Message(packetlist);
}
/**
* creates new message object from text
* @param {String} text
* @param {String} filename (optional)
* @return {module:message~Message} new message object
* @static
*/
export function fromText(text, filename) {
var literalDataPacket = new packet.Literal();
// text will be converted to UTF8
literalDataPacket.setText(text);
if (filename !== undefined) {
literalDataPacket.setFilename(filename);
}
var literalDataPacketlist = new packet.List();
literalDataPacketlist.push(literalDataPacket);
return new Message(literalDataPacketlist);
}
/**
* creates new message object from binary data
* @param {Uint8Array} bytes
* @param {String} filename (optional)
* @return {module:message~Message} new message object
* @static
*/
export function fromBinary(bytes, filename) {
if (!util.isUint8Array(bytes)) {
throw new Error('Data must be in the form of a Uint8Array');
}
var literalDataPacket = new packet.Literal();
if (filename) {
literalDataPacket.setFilename(filename);
}
literalDataPacket.setBytes(bytes, enums.read(enums.literal, enums.literal.binary));
if (filename !== undefined) {
literalDataPacket.setFilename(filename);
}
var literalDataPacketlist = new packet.List();
literalDataPacketlist.push(literalDataPacket);
return new Message(literalDataPacketlist);
}

View file

@ -1,567 +0,0 @@
// OpenPGP.js - An OpenPGP implementation in javascript
// Copyright (C) 2016 Tankred Hase
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// 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,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
/**
* @requires message
* @requires cleartext
* @requires key
* @requires config
* @requires util
* @module openpgp
*/
/**
* @fileoverview The openpgp base module should provide all of the functionality
* to consume the openpgp.js library. All additional classes are documented
* for extending and developing on top of the base library.
*/
'use strict';
import * as messageLib from './message.js';
import * as cleartext from './cleartext.js';
import * as key from './key.js';
import config from './config/config.js';
import util from './util';
import AsyncProxy from './worker/async_proxy.js';
//////////////////////////
// //
// Web Worker setup //
// //
//////////////////////////
let asyncProxy; // instance of the asyncproxy
/**
* Set the path for the web worker script and create an instance of the async proxy
* @param {String} path relative path to the worker scripts, default: 'openpgp.worker.js'
* @param {Object} worker alternative to path parameter: web worker initialized with 'openpgp.worker.js'
*/
export function initWorker({ path='openpgp.worker.js', worker } = {}) {
if (worker || typeof window !== 'undefined' && window.Worker) {
asyncProxy = new AsyncProxy({ path, worker, config });
return true;
}
}
/**
* Returns a reference to the async proxy if the worker was initialized with openpgp.initWorker()
* @return {module:worker/async_proxy~AsyncProxy|null} the async proxy or null if not initialized
*/
export function getWorker() {
return asyncProxy;
}
/**
* Cleanup the current instance of the web worker.
*/
export function destroyWorker() {
asyncProxy = undefined;
}
//////////////////////
// //
// Key handling //
// //
//////////////////////
/**
* Generates a new OpenPGP key pair. Currently only supports RSA keys. Primary and subkey will be of same type.
* @param {Array<Object>} userIds array of user IDs e.g. [{ name:'Phil Zimmermann', email:'phil@openpgp.org' }]
* @param {String} passphrase (optional) The passphrase used to encrypt the resulting private key
* @param {Number} numBits (optional) number of bits for the key creation. (should be 2048 or 4096)
* @param {Boolean} unlocked (optional) If the returned secret part of the generated key is unlocked
* @param {Number} keyExpirationTime (optional) The number of seconds after the key creation time that the key expires
* @return {Promise<Object>} The generated key object in the form:
* { key:Key, privateKeyArmored:String, publicKeyArmored:String }
* @static
*/
export function generateKey({ userIds=[], passphrase, numBits=2048, unlocked=false, keyExpirationTime=0 } = {}) {
const options = formatUserIds({ userIds, passphrase, numBits, unlocked, keyExpirationTime });
if (!util.getWebCryptoAll() && asyncProxy) { // use web worker if web crypto apis are not supported
return asyncProxy.delegate('generateKey', options);
}
return key.generate(options).then(newKey => ({
key: newKey,
privateKeyArmored: newKey.armor(),
publicKeyArmored: newKey.toPublic().armor()
})).catch(onError.bind(null, 'Error generating keypair'));
}
/**
* Reformats signature packets for a key and rewraps key object.
* @param {Array<Object>} userIds array of user IDs e.g. [{ name:'Phil Zimmermann', email:'phil@openpgp.org' }]
* @param {String} passphrase (optional) The passphrase used to encrypt the resulting private key
* @param {Boolean} unlocked (optional) If the returned secret part of the generated key is unlocked
* @param {Number} keyExpirationTime (optional) The number of seconds after the key creation time that the key expires
* @return {Promise<Object>} The generated key object in the form:
* { key:Key, privateKeyArmored:String, publicKeyArmored:String }
* @static
*/
export function reformatKey({ privateKey, userIds=[], passphrase="", unlocked=false, keyExpirationTime=0 } = {}) {
const options = formatUserIds({ privateKey, userIds, passphrase, unlocked, keyExpirationTime });
if (asyncProxy) {
return asyncProxy.delegate('reformatKey', options);
}
return key.reformat(options).then(newKey => ({
key: newKey,
privateKeyArmored: newKey.armor(),
publicKeyArmored: newKey.toPublic().armor()
})).catch(onError.bind(null, 'Error reformatting keypair'));
}
/**
* Unlock a private key with your passphrase.
* @param {Key} privateKey the private key that is to be decrypted
* @param {String} passphrase the user's passphrase chosen during key generation
* @return {Key} the unlocked private key
*/
export function decryptKey({ privateKey, passphrase }) {
if (asyncProxy) { // use web worker if available
return asyncProxy.delegate('decryptKey', { privateKey, passphrase });
}
return execute(() => {
if (!privateKey.decrypt(passphrase)) {
throw new Error('Invalid passphrase');
}
return {
key: privateKey
};
}, 'Error decrypting private key');
}
///////////////////////////////////////////
// //
// Message encryption and decryption //
// //
///////////////////////////////////////////
/**
* Encrypts message text/data with public keys, passwords or both at once. At least either public keys or passwords
* must be specified. If private keys are specified, those will be used to sign the message.
* @param {String|Uint8Array} data text/data to be encrypted as JavaScript binary string or Uint8Array
* @param {Key|Array<Key>} publicKeys (optional) array of keys or single key, used to encrypt the message
* @param {Key|Array<Key>} privateKeys (optional) private keys for signing. If omitted message will not be signed
* @param {String|Array<String>} passwords (optional) array of passwords or a single password to encrypt the message
* @param {Object} sessionKey (optional) session key in the form: { data:Uint8Array, algorithm:String }
* @param {String} filename (optional) a filename for the literal data packet
* @param {Boolean} armor (optional) if the return values should be ascii armored or the message/signature objects
* @param {Boolean} detached (optional) if the signature should be detached (if true, signature will be added to returned object)
* @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
* @return {Promise<Object>} encrypted (and optionally signed message) in the form:
* {data: ASCII armored message if 'armor' is true,
* message: full Message object if 'armor' is false, signature: detached signature if 'detached' is true}
* @static
*/
export function encrypt({ data, publicKeys, privateKeys, passwords, sessionKey, filename, armor=true, detached=false, signature=null, returnSessionKey=false}) {
checkData(data); publicKeys = toArray(publicKeys); privateKeys = toArray(privateKeys); passwords = toArray(passwords);
if (!nativeAEAD() && asyncProxy) { // use web worker if web crypto apis are not supported
return asyncProxy.delegate('encrypt', { data, publicKeys, privateKeys, passwords, sessionKey, filename, armor, detached, signature, returnSessionKey });
}
var result = {};
return Promise.resolve().then(() => {
let message = createMessage(data, filename);
if (!privateKeys) {
privateKeys = [];
}
if (privateKeys.length || signature) { // sign the message only if private keys or signature is specified
if (detached) {
var detachedSignature = message.signDetached(privateKeys, signature);
if (armor) {
result.signature = detachedSignature.armor();
} else {
result.signature = detachedSignature;
}
} else {
message = message.sign(privateKeys, signature);
}
}
return message.encrypt(publicKeys, passwords, sessionKey);
}).then(encrypted => {
if (armor) {
result.data = encrypted.message.armor();
} else {
result.message = encrypted.message;
}
if (returnSessionKey) {
result.sessionKey = encrypted.sessionKey;
}
return result;
}).catch(onError.bind(null, 'Error encrypting message'));
}
/**
* Decrypts a message with the user's private key, a session key or a password. Either a private key,
* a session key or a password must be specified.
* @param {Message} message the message object with the encrypted data
* @param {Key} privateKey (optional) private key with decrypted secret key data or session key
* @param {Key|Array<Key>} publicKeys (optional) array of public keys or single key, to verify signatures
* @param {Object} sessionKey (optional) session key in the form: { data:Uint8Array, algorithm:String }
* @param {String} password (optional) single password to decrypt the message
* @param {String} format (optional) return data format either as 'utf8' or 'binary'
* @param {Signature} signature (optional) detached signature for verification
* @return {Promise<Object>} decrypted and verified message in the form:
* { data:Uint8Array|String, filename:String, signatures:[{ keyid:String, valid:Boolean }] }
* @static
*/
export function decrypt({ message, privateKey, publicKeys, sessionKey, password, format='utf8', signature=null }) {
checkMessage(message); publicKeys = toArray(publicKeys);
if (!nativeAEAD() && asyncProxy) { // use web worker if web crypto apis are not supported
return asyncProxy.delegate('decrypt', { message, privateKey, publicKeys, sessionKey, password, format, signature });
}
return message.decrypt(privateKey, sessionKey, password).then(message => {
const result = parseMessage(message, format);
if (!publicKeys) {
publicKeys = [];
}
if (signature) {
//detached signature
result.signatures = message.verifyDetached(signature, publicKeys);
} else {
result.signatures = message.verify(publicKeys);
}
return result;
}).catch(onError.bind(null, 'Error decrypting message'));
}
//////////////////////////////////////////
// //
// Message signing and verification //
// //
//////////////////////////////////////////
/**
* Signs a cleartext message.
* @param {String | Uint8Array} data cleartext input to be signed
* @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} detached (optional) if the return value should contain a detached signature
* @return {Promise<Object>} signed cleartext in the form:
* {data: ASCII armored message if 'armor' is true,
* message: full Message object if 'armor' is false, signature: detached signature if 'detached' is true}
* @static
*/
export function sign({ data, privateKeys, armor=true, detached=false}) {
checkData(data);
privateKeys = toArray(privateKeys);
if (asyncProxy) { // use web worker if available
return asyncProxy.delegate('sign', { data, privateKeys, armor, detached });
}
var result = {};
return execute(() => {
var message;
if (util.isString(data)) {
message = new cleartext.CleartextMessage(data);
} else {
message = messageLib.fromBinary(data);
}
if (detached) {
var signature = message.signDetached(privateKeys);
if (armor) {
result.signature = signature.armor();
} else {
result.signature = signature;
}
} else {
message = message.sign(privateKeys);
if (armor) {
result.data = message.armor();
} else {
result.message = message;
}
}
return result;
}, 'Error signing cleartext message');
}
/**
* Verifies signatures of cleartext signed message
* @param {Key|Array<Key>} publicKeys array of publicKeys or single key, to verify signatures
* @param {CleartextMessage} message cleartext message object with signatures
* @param {Signature} signature (optional) detached signature for verification
* @return {Promise<Object>} cleartext with status of verified signatures in the form of:
* { data:String, signatures: [{ keyid:String, valid:Boolean }] }
* @static
*/
export function verify({ message, publicKeys, signature=null }) {
checkCleartextOrMessage(message);
publicKeys = toArray(publicKeys);
if (asyncProxy) { // use web worker if available
return asyncProxy.delegate('verify', { message, publicKeys, signature });
}
var result = {};
return execute(() => {
if (cleartext.CleartextMessage.prototype.isPrototypeOf(message)) {
result.data = message.getText();
} else {
result.data = message.getLiteralData();
}
if (signature) {
//detached signature
result.signatures = message.verifyDetached(signature, publicKeys);
} else {
result.signatures = message.verify(publicKeys);
}
return result;
}, 'Error verifying cleartext signed message');
}
///////////////////////////////////////////////
// //
// Session key encryption and decryption //
// //
///////////////////////////////////////////////
/**
* Encrypt a symmetric session key with public keys, passwords, or both at once. At least either public keys
* or passwords must be specified.
* @param {Uint8Array} data the session key to be encrypted e.g. 16 random bytes (for aes128)
* @param {String} algorithm algorithm of the symmetric session key e.g. 'aes128' or 'aes256'
* @param {Key|Array<Key>} publicKeys (optional) array of public keys or single key, used to encrypt the key
* @param {String|Array<String>} passwords (optional) passwords for the message
* @return {Promise<Message>} the encrypted session key packets contained in a message object
* @static
*/
export function encryptSessionKey({ data, algorithm, publicKeys, passwords }) {
checkBinary(data); checkString(algorithm, 'algorithm'); publicKeys = toArray(publicKeys); passwords = toArray(passwords);
if (asyncProxy) { // use web worker if available
return asyncProxy.delegate('encryptSessionKey', { data, algorithm, publicKeys, passwords });
}
return execute(() => ({
message: messageLib.encryptSessionKey(data, algorithm, publicKeys, passwords)
}), 'Error encrypting session key');
}
/**
* Decrypt a symmetric session key with a private key or password. Either a private key or
* a password must be specified.
* @param {Message} message a message object containing the encrypted session key packets
* @param {Key} privateKey (optional) private key with decrypted secret key data
* @param {String} password (optional) a single password to decrypt the session key
* @return {Promise<Object|undefined>} decrypted session key and algorithm in object form:
* { data:Uint8Array, algorithm:String }
* or 'undefined' if no key packets found
* @static
*/
export function decryptSessionKey({ message, privateKey, password }) {
checkMessage(message);
if (asyncProxy) { // use web worker if available
return asyncProxy.delegate('decryptSessionKey', { message, privateKey, password });
}
return execute(() => message.decryptSessionKey(privateKey, password), 'Error decrypting session key');
}
//////////////////////////
// //
// Helper functions //
// //
//////////////////////////
/**
* Input validation
*/
function checkString(data, name) {
if (!util.isString(data)) {
throw new Error('Parameter [' + (name || 'data') + '] must be of type String');
}
}
function checkBinary(data, name) {
if (!util.isUint8Array(data)) {
throw new Error('Parameter [' + (name || 'data') + '] must be of type Uint8Array');
}
}
function checkData(data, name) {
if (!util.isUint8Array(data) && !util.isString(data)) {
throw new Error('Parameter [' + (name || 'data') + '] must be of type String or Uint8Array');
}
}
function checkMessage(message) {
if (!messageLib.Message.prototype.isPrototypeOf(message)) {
throw new Error('Parameter [message] needs to be of type Message');
}
}
function checkCleartextOrMessage(message) {
if (!cleartext.CleartextMessage.prototype.isPrototypeOf(message) && !messageLib.Message.prototype.isPrototypeOf(message)) {
throw new Error('Parameter [message] needs to be of type Message or CleartextMessage');
}
}
/**
* Format user ids for internal use.
*/
function formatUserIds(options) {
if (!options.userIds) {
return options;
}
options.userIds = toArray(options.userIds); // normalize to array
options.userIds = options.userIds.map(id => {
if (util.isString(id) && !util.isUserId(id)) {
throw new Error('Invalid user id format');
}
if (util.isUserId(id)) {
return id; // user id is already in correct format... no conversion necessary
}
// name and email address can be empty but must be of the correct type
id.name = id.name || '';
id.email = id.email || '';
if (!util.isString(id.name) || (id.email && !util.isEmailAddress(id.email))) {
throw new Error('Invalid user id format');
}
id.name = id.name.trim();
if (id.name.length > 0) {
id.name += ' ';
}
return id.name + '<' + id.email + '>';
});
return options;
}
/**
* Normalize parameter to an array if it is not undefined.
* @param {Object} param the parameter to be normalized
* @return {Array<Object>|undefined} the resulting array or undefined
*/
function toArray(param) {
if (param && !util.isArray(param)) {
param = [param];
}
return param;
}
/**
* Creates a message obejct either from a Uint8Array or a string.
* @param {String|Uint8Array} data the payload for the message
* @param {String} filename the literal data packet's filename
* @return {Message} a message object
*/
function createMessage(data, filename) {
let msg;
if (util.isUint8Array(data)) {
msg = messageLib.fromBinary(data, filename);
} else if (util.isString(data)) {
msg = messageLib.fromText(data, filename);
} else {
throw new Error('Data must be of type String or Uint8Array');
}
return msg;
}
/**
* Parse the message given a certain format.
* @param {Message} message the message object to be parse
* @param {String} format the output format e.g. 'utf8' or 'binary'
* @return {Object} the parse data in the respective format
*/
function parseMessage(message, format) {
if (format === 'binary') {
return {
data: message.getLiteralData(),
filename: message.getFilename()
};
} else if (format === 'utf8') {
return {
data: message.getText(),
filename: message.getFilename()
};
} else {
throw new Error('Invalid format');
}
}
/**
* Command pattern that wraps synchronous code into a promise.
* @param {function} cmd The synchronous function with a return value
* to be wrapped in a promise
* @param {String} message A human readable error Message
* @return {Promise} The promise wrapped around cmd
*/
function execute(cmd, message) {
// wrap the sync cmd in a promise
const promise = new Promise(resolve => resolve(cmd()));
// handler error globally
return promise.catch(onError.bind(null, message));
}
/**
* Global error handler that logs the stack trace and rethrows a high lvl error message.
* @param {String} message A human readable high level error Message
* @param {Error} error The internal error that caused the failure
*/
function onError(message, error) {
// update error message
error.message = message + ': ' + error.message;
throw error;
}
/**
* Check for AES-GCM support and configuration by the user. Only browsers that
* implement the current WebCrypto specification support native AES-GCM.
* @return {Boolean} If authenticated encryption should be used
*/
function nativeAEAD() {
return util.getWebCrypto() && config.aead_protect;
}

View file

@ -1,82 +0,0 @@
/**
* @requires enums
* @module packet
*/
'use strict';
import enums from '../enums.js';
import * as packets from './all_packets.js'; // re-import module to parse packets from tag
/** @see module:packet/compressed */
export { default as Compressed } from './compressed.js';
/** @see module:packet/sym_encrypted_integrity_protected */
export { default as SymEncryptedIntegrityProtected } from './sym_encrypted_integrity_protected.js';
/** @see module:packet/sym_encrypted_aead_protected */
export { default as SymEncryptedAEADProtected } from './sym_encrypted_aead_protected.js';
/** @see module:packet/public_key_encrypted_session_key */
export { default as PublicKeyEncryptedSessionKey } from './public_key_encrypted_session_key.js';
/** @see module:packet/sym_encrypted_session_key */
export { default as SymEncryptedSessionKey } from './sym_encrypted_session_key.js';
/** @see module:packet/literal */
export { default as Literal } from './literal.js';
/** @see module:packet/public_key */
export { default as PublicKey } from './public_key.js';
/** @see module:packet/symmetrically_encrypted */
export { default as SymmetricallyEncrypted } from './symmetrically_encrypted.js';
/** @see module:packet/marker */
export { default as Marker } from './marker.js';
/** @see module:packet/public_subkey */
export { default as PublicSubkey } from './public_subkey.js';
/** @see module:packet/user_attribute */
export { default as UserAttribute } from './user_attribute.js';
/** @see module:packet/one_pass_signature */
export { default as OnePassSignature } from './one_pass_signature.js';
/** @see module:packet/secret_key */
export { default as SecretKey } from './secret_key.js';
/** @see module:packet/userid */
export { default as Userid } from './userid.js';
/** @see module:packet/secret_subkey */
export { default as SecretSubkey } from './secret_subkey.js';
/** @see module:packet/signature */
export { default as Signature } from './signature.js';
/** @see module:packet/trust */
export { default as Trust } from './trust.js';
/**
* Allocate a new packet
* @param {String} tag property name from {@link module:enums.packet}
* @returns {Object} new packet object with type based on tag
*/
export function newPacketFromTag(tag) {
return new packets[packetClassFromTagName(tag)]();
}
/**
* Allocate a new packet from structured packet clone
* See {@link http://www.w3.org/html/wg/drafts/html/master/infrastructure.html#safe-passing-of-structured-data}
* @param {Object} packetClone packet clone
* @returns {Object} new packet object with data from packet clone
*/
export function fromStructuredClone(packetClone) {
var tagName = enums.read(enums.packet, packetClone.tag);
var packet = newPacketFromTag(tagName);
for (var attr in packetClone) {
if (packetClone.hasOwnProperty(attr)) {
packet[attr] = packetClone[attr];
}
}
if (packet.postCloneTypeFix) {
packet.postCloneTypeFix();
}
return packet;
}
/**
* Convert tag name to class name
* @param {String} tag property name from {@link module:enums.packet}
* @returns {String}
*/
function packetClassFromTagName(tag) {
return tag.substr(0, 1).toUpperCase() + tag.substr(1);
}

Some files were not shown because too many files have changed in this diff Show more