2017-05-13 22:36:07 +02:00
|
|
|
const Logger = require('./logger');
|
|
|
|
const publicKey = require('raw-loader!../../resources/public-key.pem');
|
|
|
|
const kdbxweb = require('kdbxweb');
|
|
|
|
|
|
|
|
const SignatureVerifier = {
|
|
|
|
logger: new Logger('signature-verifier'),
|
|
|
|
|
2017-05-14 00:24:06 +02:00
|
|
|
verify(data, signature, pk) {
|
2017-05-13 22:36:07 +02:00
|
|
|
return new Promise((resolve, reject) => {
|
2017-05-14 16:58:42 +02:00
|
|
|
const algo = {name: 'RSASSA-PKCS1-v1_5', hash: {name: 'SHA-256'}};
|
2017-05-13 22:36:07 +02:00
|
|
|
try {
|
2017-05-14 00:24:06 +02:00
|
|
|
if (!pk) {
|
|
|
|
pk = this.getPublicKey();
|
|
|
|
}
|
|
|
|
signature = kdbxweb.ByteUtils.base64ToBytes(signature);
|
2017-05-14 16:58:42 +02:00
|
|
|
let subtle = window.crypto.subtle;
|
|
|
|
let keyFormat = 'spki';
|
|
|
|
if (subtle) {
|
|
|
|
pk = kdbxweb.ByteUtils.base64ToBytes(pk);
|
|
|
|
} else {
|
|
|
|
// TODO: remove this shit after Safari 10.2 with spki support goes live
|
|
|
|
subtle = window.crypto.webkitSubtle;
|
|
|
|
keyFormat = 'jwk';
|
|
|
|
pk = this.spkiToJwk(pk);
|
|
|
|
}
|
|
|
|
subtle.importKey(
|
|
|
|
keyFormat, pk,
|
|
|
|
algo,
|
2017-05-13 22:36:07 +02:00
|
|
|
false, ['verify']
|
|
|
|
).then(cryptoKey => {
|
2017-05-14 16:58:42 +02:00
|
|
|
subtle.verify(algo, cryptoKey,
|
2017-05-13 22:36:07 +02:00
|
|
|
kdbxweb.ByteUtils.arrayToBuffer(signature),
|
|
|
|
kdbxweb.ByteUtils.arrayToBuffer(data)
|
|
|
|
).then(isValid => {
|
|
|
|
resolve(isValid);
|
|
|
|
}).catch(e => {
|
|
|
|
this.logger.error('Verify error', e);
|
|
|
|
reject();
|
|
|
|
});
|
|
|
|
}).catch(e => {
|
|
|
|
this.logger.error('ImportKey error', e);
|
|
|
|
reject();
|
|
|
|
});
|
|
|
|
} catch (e) {
|
|
|
|
this.logger.error('Signature verification error', e);
|
|
|
|
reject();
|
|
|
|
}
|
|
|
|
});
|
2017-05-14 00:24:06 +02:00
|
|
|
},
|
|
|
|
|
2017-05-14 16:58:42 +02:00
|
|
|
spkiToJwk(key) {
|
|
|
|
// This is terribly wrong but we don't want to handle complete ASN1 format here
|
|
|
|
const n = key
|
|
|
|
.replace('MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA', '')
|
|
|
|
.replace('IDAQAB', '')
|
|
|
|
.replace(/\+/g, '-')
|
|
|
|
.replace(/\//g, '_');
|
|
|
|
return kdbxweb.ByteUtils.stringToBytes(JSON.stringify({
|
|
|
|
kty: 'RSA',
|
|
|
|
alg: 'RS256',
|
|
|
|
e: 'AQAB',
|
|
|
|
n: n,
|
|
|
|
ext: true
|
|
|
|
}));
|
|
|
|
},
|
|
|
|
|
2017-05-14 00:24:06 +02:00
|
|
|
getPublicKey() {
|
|
|
|
return publicKey
|
|
|
|
.match(/-+BEGIN PUBLIC KEY-+([\s\S]+?)-+END PUBLIC KEY-+/)[1]
|
|
|
|
.replace(/\s+/g, '');
|
2017-05-13 22:36:07 +02:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
module.exports = SignatureVerifier;
|