Source code

Revision control

Copy as Markdown

Other Tools

Test Info:

<!DOCTYPE HTML>
<html>
<head>
<script type="application/javascript" src="pc.js"></script>
</head>
<body>
<pre id="test">
<script type="application/javascript">
createHTML({
bug: "1172785",
title: "Certificate management"
});
function badCertificate(config, expectedError, message) {
return RTCPeerConnection.generateCertificate(config)
.then(() => ok(false, message),
e => is(e.name, expectedError, message));
}
// Checks a handful of obviously bad options to RTCCertificate.create(). Most
// of the checking is done by the WebCrypto code underpinning this, hence the
// baffling error codes, but a sanity check is still in order.
function checkBadParameters() {
return Promise.all([
badCertificate({
name: "RSASSA-PKCS1-v1_5",
hash: "SHA-256",
modulusLength: 1023,
publicExponent: new Uint8Array([1, 0, 1])
}, "NotSupportedError", "1023-bit is too small to succeed"),
badCertificate({
name: "RSASSA-PKCS1-v1_5",
hash: "SHA-384",
modulusLength: 2048,
publicExponent: new Uint8Array([1, 0, 1])
}, "NotSupportedError", "SHA-384 isn't supported yet"),
// A SyntaxError happens in the "generate key operation" step, but
// webrtc-pc does not say to reject the promise if this step fails.
// It does say to throw NotSupportedError if we have passed "an
// algorithm that the user agent cannot or will not use to generate a
// certificate".
badCertificate({
name: "ECDH",
namedCurve: "P-256"
}, "NotSupportedError", "ECDH is rejected because the usage is neither \"deriveKey\" or \"deriveBits\""),
badCertificate({
name: "not a valid algorithm"
}, "NotSupportedError", "not a valid algorithm"),
badCertificate("ECDSA", "NotSupportedError", "a bare name is not enough"),
badCertificate({
name: "ECDSA",
namedCurve: "not a curve"
}, "NotSupportedError", "ECDSA with an unknown curve")
]);
}
function createDB() {
var openDB = indexedDB.open("genericstore");
openDB.onupgradeneeded = e => {
var db = e.target.result;
db.createObjectStore("data");
};
return new Promise(resolve => {
openDB.onsuccess = e => resolve(e.target.result);
});
}
function resultPromise(tx, op) {
return new Promise((resolve, reject) => {
op.onsuccess = e => resolve(e.target.result);
op.onerror = () => reject(op.error);
tx.onabort = () => reject(tx.error);
});
}
function store(db, value) {
var tx = db.transaction("data", "readwrite");
var store = tx.objectStore("data");
return resultPromise(tx, store.put(value, "value"));
}
function retrieve(db) {
var tx = db.transaction("data", "readonly");
var store = tx.objectStore("data");
return resultPromise(tx, store.get("value"));
}
// Creates a database, stores a value, retrieves it.
function storeAndRetrieve(value) {
return createDB().then(db => {
return store(db, value)
.then(() => retrieve(db))
.then(retrieved => {
db.close();
return retrieved;
});
});
}
var test;
runNetworkTest(function (options) {
var expiredCert;
return Promise.resolve()
.then(() => RTCPeerConnection.generateCertificate({
name: "ECDSA",
namedCurve: "P-256",
expires: 1 // smallest possible expiration window
}))
.then(cert => {
ok(!isNaN(cert.expires), 'cert has expiration time');
info('Expires at ' + new Date(cert.expires));
expiredCert = cert;
})
.then(() => checkBadParameters())
.then(() => {
var delay = expiredCert.expires - Date.now();
// Hopefully this delay is never needed.
if (delay > 0) {
return new Promise(r => setTimeout(r, delay));
}
return Promise.resolve();
})
.then(() => {
ok(expiredCert.expires <= Date.now(), 'Cert should be at or past expiration');
try {
new RTCPeerConnection({ certificates: [expiredCert] });
ok(false, 'Constructing peer connection with an expired cert is not allowed');
} catch(e) {
is(e.name, 'InvalidAccessError',
'Constructing peer connection with an expired certs is not allowed');
}
})
.then(() => Promise.all([
RTCPeerConnection.generateCertificate({
name: "ECDSA",
namedCurve: "P-256"
}),
RTCPeerConnection.generateCertificate({
name: "RSASSA-PKCS1-v1_5",
hash: "SHA-256",
modulusLength: 2048,
publicExponent: new Uint8Array([1, 0, 1])
})
]))
// A round trip through indexedDB should not do anything.
.then(storeAndRetrieve)
.then(certs => {
try {
new RTCPeerConnection({ certificates: certs });
ok(false, 'Constructing peer connection with multiple certs is not allowed');
} catch(e) {
is(e.name, 'NotSupportedError',
'Constructing peer connection with multiple certs is not allowed');
}
return certs;
})
.then(certs => {
test = new PeerConnectionTest({
config_local: {
certificates: [certs[0]]
},
config_remote: {
certificates: [certs[1]]
}
});
test.setMediaConstraints([{audio: true}], [{audio: true}]);
return test.run();
})
.catch(e => {
console.log('test failure', e);
ok(false, 'test failed: ' + e);
});
});
</script>
</pre>
</body>
</html>