test_peerConnection_certificates.html (5727B)
1 <!DOCTYPE HTML> 2 <html> 3 <head> 4 <script type="application/javascript" src="pc.js"></script> 5 </head> 6 <body> 7 <pre id="test"> 8 <script type="application/javascript"> 9 createHTML({ 10 bug: "1172785", 11 title: "Certificate management" 12 }); 13 14 function badCertificate(config, expectedError, message) { 15 return RTCPeerConnection.generateCertificate(config) 16 .then(() => ok(false, message), 17 e => is(e.name, expectedError, message)); 18 } 19 20 // Checks a handful of obviously bad options to RTCCertificate.create(). Most 21 // of the checking is done by the WebCrypto code underpinning this, hence the 22 // baffling error codes, but a sanity check is still in order. 23 function checkBadParameters() { 24 return Promise.all([ 25 badCertificate({ 26 name: "RSASSA-PKCS1-v1_5", 27 hash: "SHA-256", 28 modulusLength: 1023, 29 publicExponent: new Uint8Array([1, 0, 1]) 30 }, "NotSupportedError", "1023-bit is too small to succeed"), 31 32 badCertificate({ 33 name: "RSASSA-PKCS1-v1_5", 34 hash: "SHA-384", 35 modulusLength: 2048, 36 publicExponent: new Uint8Array([1, 0, 1]) 37 }, "NotSupportedError", "SHA-384 isn't supported yet"), 38 39 // A SyntaxError happens in the "generate key operation" step, but 40 // webrtc-pc does not say to reject the promise if this step fails. 41 // It does say to throw NotSupportedError if we have passed "an 42 // algorithm that the user agent cannot or will not use to generate a 43 // certificate". 44 badCertificate({ 45 name: "ECDH", 46 namedCurve: "P-256" 47 }, "NotSupportedError", "ECDH is rejected because the usage is neither \"deriveKey\" or \"deriveBits\""), 48 49 badCertificate({ 50 name: "not a valid algorithm" 51 }, "NotSupportedError", "not a valid algorithm"), 52 53 badCertificate("ECDSA", "NotSupportedError", "a bare name is not enough"), 54 55 badCertificate({ 56 name: "ECDSA", 57 namedCurve: "not a curve" 58 }, "NotSupportedError", "ECDSA with an unknown curve") 59 ]); 60 } 61 62 function createDB() { 63 var openDB = indexedDB.open("genericstore"); 64 openDB.onupgradeneeded = e => { 65 var db = e.target.result; 66 db.createObjectStore("data"); 67 }; 68 return new Promise(resolve => { 69 openDB.onsuccess = e => resolve(e.target.result); 70 }); 71 } 72 73 function resultPromise(tx, op) { 74 return new Promise((resolve, reject) => { 75 op.onsuccess = e => resolve(e.target.result); 76 op.onerror = () => reject(op.error); 77 tx.onabort = () => reject(tx.error); 78 }); 79 } 80 81 function store(db, value) { 82 var tx = db.transaction("data", "readwrite"); 83 var store = tx.objectStore("data"); 84 return resultPromise(tx, store.put(value, "value")); 85 } 86 87 function retrieve(db) { 88 var tx = db.transaction("data", "readonly"); 89 var store = tx.objectStore("data"); 90 return resultPromise(tx, store.get("value")); 91 } 92 93 // Creates a database, stores a value, retrieves it. 94 function storeAndRetrieve(value) { 95 return createDB().then(db => { 96 return store(db, value) 97 .then(() => retrieve(db)) 98 .then(retrieved => { 99 db.close(); 100 return retrieved; 101 }); 102 }); 103 } 104 105 var test; 106 runNetworkTest(function (options) { 107 var expiredCert; 108 return Promise.resolve() 109 .then(() => RTCPeerConnection.generateCertificate({ 110 name: "ECDSA", 111 namedCurve: "P-256", 112 expires: 1 // smallest possible expiration window 113 })) 114 .then(cert => { 115 ok(!isNaN(cert.expires), 'cert has expiration time'); 116 info('Expires at ' + new Date(cert.expires)); 117 expiredCert = cert; 118 }) 119 120 .then(() => checkBadParameters()) 121 122 .then(() => { 123 var delay = expiredCert.expires - Date.now(); 124 // Hopefully this delay is never needed. 125 if (delay > 0) { 126 return new Promise(r => setTimeout(r, delay)); 127 } 128 return Promise.resolve(); 129 }) 130 .then(() => { 131 ok(expiredCert.expires <= Date.now(), 'Cert should be at or past expiration'); 132 try { 133 new RTCPeerConnection({ certificates: [expiredCert] }); 134 ok(false, 'Constructing peer connection with an expired cert is not allowed'); 135 } catch(e) { 136 is(e.name, 'InvalidAccessError', 137 'Constructing peer connection with an expired certs is not allowed'); 138 } 139 }) 140 141 .then(() => Promise.all([ 142 RTCPeerConnection.generateCertificate({ 143 name: "ECDSA", 144 namedCurve: "P-256" 145 }), 146 RTCPeerConnection.generateCertificate({ 147 name: "RSASSA-PKCS1-v1_5", 148 hash: "SHA-256", 149 modulusLength: 2048, 150 publicExponent: new Uint8Array([1, 0, 1]) 151 }) 152 ])) 153 154 // A round trip through indexedDB should not do anything. 155 .then(storeAndRetrieve) 156 .then(certs => { 157 try { 158 new RTCPeerConnection({ certificates: certs }); 159 ok(false, 'Constructing peer connection with multiple certs is not allowed'); 160 } catch(e) { 161 is(e.name, 'NotSupportedError', 162 'Constructing peer connection with multiple certs is not allowed'); 163 } 164 return certs; 165 }) 166 .then(certs => { 167 test = new PeerConnectionTest({ 168 config_local: { 169 certificates: [certs[0]] 170 }, 171 config_remote: { 172 certificates: [certs[1]] 173 } 174 }); 175 test.setMediaConstraints([{audio: true}], [{audio: true}]); 176 return test.run(); 177 }) 178 .catch(e => { 179 console.log('test failure', e); 180 ok(false, 'test failed: ' + e); 181 }); 182 }); 183 </script> 184 </pre> 185 </body> 186 </html>