mirror of https://github.com/keeweb/keeweb
fix #1252: public key rotation
parent
2913a0421d
commit
0cd401c45d
|
@ -0,0 +1,9 @@
|
|||
-----BEGIN PUBLIC KEY-----
|
||||
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAnRq2k3TTx0ewTe6wDr6Q
|
||||
VeB5diwiIWzsJD+ApfZu1KNPedcAgslAfjpNsYF1if6cYsPMJH70xJ2np6RQBl1V
|
||||
PdwShOuxkD7m0BD5Hw/Aar8Hdp5cvAdOOMdBO+0DbGeUMy+z66s+oUCJmqVp19T6
|
||||
PkkxbhN08rgtT7v+aFvrbqbO/vlsskbJpH2K2io+e1XmRGPnSr9q4KSqfGbTfe5g
|
||||
LwDIOFd66Z4mb5Utb5wWpsy6Gjh06Yf257AccGD3A1bkTNOyeeX0tqciYBePWMk0
|
||||
icP/aZ6hnErfhnUKf3tOgPLppSHiGcaSKekhChZ2xLUs3U64JwrXSmwHj+TzdO3S
|
||||
0QIDAQAB
|
||||
-----END PUBLIC KEY-----
|
|
@ -191,10 +191,10 @@ class PluginManager extends Model {
|
|||
const galleryPlugin = gallery
|
||||
? gallery.plugins.find(pl => pl.manifest.name === desc.manifest.name)
|
||||
: null;
|
||||
const expectedPublicKey = galleryPlugin
|
||||
? galleryPlugin.manifest.publicKey
|
||||
: SignatureVerifier.getPublicKey();
|
||||
enabled = desc.manifest.publicKey === expectedPublicKey;
|
||||
const expectedPublicKeys = galleryPlugin
|
||||
? [galleryPlugin.manifest.publicKey]
|
||||
: SignatureVerifier.getPublicKeys();
|
||||
enabled = expectedPublicKeys.includes(desc.manifest.publicKey);
|
||||
}
|
||||
return plugin
|
||||
.install(enabled, true)
|
||||
|
|
|
@ -106,7 +106,7 @@ class Plugin extends Model {
|
|||
}
|
||||
if (
|
||||
!this.skipSignatureValidation &&
|
||||
manifest.publicKey !== SignatureVerifier.getPublicKey()
|
||||
!SignatureVerifier.getPublicKeys().includes(manifest.publicKey)
|
||||
) {
|
||||
return 'Public key mismatch';
|
||||
}
|
||||
|
|
|
@ -1,19 +1,26 @@
|
|||
import kdbxweb from 'kdbxweb';
|
||||
import { Logger } from 'util/logger';
|
||||
import publicKey from 'public-key.pem';
|
||||
import publicKeyData from 'public-key.pem';
|
||||
import publicKeyDataNew from 'public-key-new.pem';
|
||||
|
||||
const SignatureVerifier = {
|
||||
logger: new Logger('signature-verifier'),
|
||||
|
||||
publicKey: null,
|
||||
publicKeys: null,
|
||||
|
||||
verify(data, signature, pk) {
|
||||
if (!pk) {
|
||||
const pks = this.getPublicKeys();
|
||||
return this.verify(data, signature, pks[0]).then(isValid => {
|
||||
if (isValid || !pks[1]) {
|
||||
return isValid;
|
||||
}
|
||||
return this.verify(data, signature, pks[1]);
|
||||
});
|
||||
}
|
||||
return new Promise((resolve, reject) => {
|
||||
const algo = { name: 'RSASSA-PKCS1-v1_5', hash: { name: 'SHA-256' } };
|
||||
try {
|
||||
if (!pk) {
|
||||
pk = this.getPublicKey();
|
||||
}
|
||||
if (typeof signature === 'string') {
|
||||
signature = kdbxweb.ByteUtils.base64ToBytes(signature);
|
||||
}
|
||||
|
@ -54,13 +61,13 @@ const SignatureVerifier = {
|
|||
});
|
||||
},
|
||||
|
||||
getPublicKey() {
|
||||
if (!this.publicKey) {
|
||||
this.publicKey = publicKey
|
||||
.match(/-+BEGIN PUBLIC KEY-+([\s\S]+?)-+END PUBLIC KEY-+/)[1]
|
||||
.replace(/\s+/g, '');
|
||||
getPublicKeys() {
|
||||
if (!this.publicKeys) {
|
||||
this.publicKeys = [publicKeyData, publicKeyDataNew].map(pk =>
|
||||
pk.match(/-+BEGIN PUBLIC KEY-+([\s\S]+?)-+END PUBLIC KEY-+/)[1].replace(/\s+/g, '')
|
||||
);
|
||||
}
|
||||
return this.publicKey;
|
||||
return this.publicKeys;
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -70,6 +70,7 @@ function config(grunt, mode = 'production') {
|
|||
'argon2-wasm': 'argon2-browser/dist/argon2.wasm',
|
||||
templates: path.join(rootDir, 'app/templates'),
|
||||
'public-key.pem': path.join(rootDir, 'app/resources/public-key.pem'),
|
||||
'public-key-new.pem': path.join(rootDir, 'app/resources/public-key-new.pem'),
|
||||
'demo.kdbx': path.join(rootDir, 'app/resources/Demo.kdbx')
|
||||
}
|
||||
},
|
||||
|
|
|
@ -14,6 +14,7 @@ Release notes
|
|||
`+` #498: CSV import
|
||||
`*` #156: using ServiceWorker instead of AppCache
|
||||
`+` #564: Steam OTP support
|
||||
`+` #1252: public key rotation
|
||||
`*` devtools are now opened with alt-cmd-I
|
||||
`-` fix #764: multiple attachments display
|
||||
`-` fix multi-line fields display in history
|
||||
|
|
Loading…
Reference in New Issue