<!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"), badCertificate({ name: "ECDH", namedCurve: "P-256" }, "DataError", "otherwise valid ECDH config is rejected"), badCertificate({ name: "not a valid algorithm" }, "SyntaxError", "not a valid algorithm"), badCertificate("ECDSA", "SyntaxError", "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)); } }) .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, 'InvalidParameterError', '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>