'use strict';
const assertEq = chrome.test.assertEq;
const assertTrue = chrome.test.assertTrue;
const assertLastError = chrome.test.assertLastError;
const callbackPass = chrome.test.callbackPass;
chrome.test.setExceptionHandler(function(message, exc) {
throw exc;
});
window.addEventListener('error', function(errorEvent) {
chrome.test.fail(`Unhandled exception: ${errorEvent.error}`);
});
let l1LeafCert = null;
const INVALID_CERT = new Uint8Array([1, 2, 3, 4, 5]);
let supportedAlgorithms = ['RSASSA_PKCS1_v1_5_SHA1'];
let supportedLegacyHashes = ['SHA1'];
function getInvalidClientCertificateInfos() {
const badDer = {
certificateChain: [INVALID_CERT.buffer],
supportedAlgorithms: ['RSASSA_PKCS1_v1_5_SHA256']
};
const emptyChain = {
certificateChain: [],
supportedAlgorithms: ['RSASSA_PKCS1_v1_5_SHA256']
};
const noAlgorithms = {
certificateChain: [l1LeafCert.buffer],
supportedAlgorithms: []
};
return [
badDer,
emptyChain,
noAlgorithms,
];
}
function getInvalidLegacyCertificateInfos() {
const badDer = {
certificate: INVALID_CERT.buffer,
supportedHashes: ['SHA256']
};
const noHashes = {certificate: l1LeafCert.buffer, supportedHashes: []};
return [
badDer,
noHashes,
];
}
function registerAsCertificateProvider() {
function reportCertificates(request) {
assertTrue(Number.isInteger(request.certificatesRequestId));
const validCert = {
certificateChain: [l1LeafCert.buffer],
supportedAlgorithms: supportedAlgorithms
};
chrome.certificateProvider.setCertificates(
{
certificatesRequestId: request.certificatesRequestId,
clientCertificates: [validCert, ...getInvalidClientCertificateInfos()]
},
() => {
chrome.test.succeed();
});
}
chrome.certificateProvider.onCertificatesUpdateRequested.addListener(
reportCertificates);
}
function registerAsLegacyCertificateProvider() {
function checkResult(rejectedCerts) {
assertEq(2, rejectedCerts.length);
const rejectedCertsBytes = rejectedCerts.map(
arrayBuffer => JSON.stringify(new Uint8Array(arrayBuffer)));
assertTrue(rejectedCertsBytes.includes(JSON.stringify(INVALID_CERT)));
assertTrue(rejectedCertsBytes.includes(JSON.stringify(l1LeafCert)));
}
function reportCertificates(reportCallback) {
const validCertInfo = {
certificate: l1LeafCert.buffer,
supportedHashes: supportedLegacyHashes
};
reportCallback(
[validCertInfo, ...getInvalidLegacyCertificateInfos()],
callbackPass(checkResult));
}
chrome.certificateProvider.onCertificatesRequested.addListener(
callbackPass(reportCertificates));
}
function setCertificates() {
const validCert = {
certificateChain: [l1LeafCert.buffer],
supportedAlgorithms: supportedAlgorithms
};
return new Promise(resolve => {
chrome.certificateProvider.setCertificates(
{clientCertificates: [
validCert, ...getInvalidClientCertificateInfos()]},
() => {
const success = !chrome.runtime.lastError;
resolve(success);
});
});
}
function setInvalidCertificates() {
return new Promise(resolve => {
chrome.certificateProvider.setCertificates(
{clientCertificates: getInvalidClientCertificateInfos()}, () => {
const success = !chrome.runtime.lastError;
resolve(success);
});
});
}
function unsetCertificates() {
return new Promise(resolve => {
chrome.certificateProvider.setCertificates({clientCertificates: []}, () => {
const success = !chrome.runtime.lastError;
resolve(success);
});
});
}
let signatureRequestAlgorithm;
let signatureRequestData;
let signatureCallback;
function registerForSignatureRequests() {
chrome.certificateProvider.onSignatureRequested.addListener(function(
request) {
assertTrue(Number.isInteger(request.signRequestId));
assertEq(l1LeafCert.buffer, request.certificate);
assertTrue(supportedAlgorithms.includes(request.algorithm));
signatureCallback = (signature) => {
chrome.certificateProvider.reportSignature(
{signRequestId: request.signRequestId}, () => {
assertLastError('Neither the result nor an error supplied.');
});
chrome.certificateProvider.reportSignature(
{signRequestId: request.signRequestId, signature: signature});
};
signatureRequestAlgorithm = request.algorithm;
signatureRequestData = request.input;
chrome.test.sendMessage('signature request received');
});
}
function registerForLegacySignatureRequests() {
chrome.certificateProvider.onSignDigestRequested.addListener(function(
request, callback) {
assertEq(l1LeafCert.buffer, request.certificate);
assertTrue(supportedLegacyHashes.includes(request.hash));
signatureCallback = callback;
signatureRequestAlgorithm = request.hash;
signatureRequestData = request.digest;
chrome.test.sendMessage('signature request received');
});
}
function replyWithSignature(signature) {
signatureCallback(signature.buffer);
}
function replyWithSignatureSecondTime() {
const signature = new Uint8Array([1, 2, 3]);
try {
signatureCallback(signature.buffer);
} catch (e) {
return false;
}
return true;
}
function initialize(cert) {
l1LeafCert = cert;
}