| <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN"> |
| <html> |
| <head> |
| <script src="../../resources/js-test.js"></script> |
| </head> |
| <body> |
| <script> |
| description("Tests RTCPeerConnection.generateCertificate RSA/ECDSA."); |
| |
| // Constants |
| var minuteInMs = 60 * 1000; |
| var dayInMs = 24 * 60 * minuteInMs; |
| |
| // Signature of the last generateCertificate call. |
| var generateCallString = null; |
| // Global variables so that the "should..." methods can evaluate them. |
| var certRSA = null; |
| var certECDSA = null; |
| var certExpiresNegativeOneDay = null; |
| var certExpiresZero = null; |
| var certExpiresPositiveOneDay = null; |
| var fingerprints = null; |
| |
| // 1: RSA-2048 using public exponent = 65537. |
| function generate1RSA() |
| { |
| generateCallString = 'generateCertificate({ name: "RSASSA-PKCS1-v1_5", modulusLength: 2048, publicExponent: new Uint8Array([1, 0, 1]), hash: "SHA-256" })'; |
| RTCPeerConnection.generateCertificate({ name: "RSASSA-PKCS1-v1_5", modulusLength: 2048, publicExponent: new Uint8Array([1, 0, 1]), hash: "SHA-256" }) |
| .then(generate1RSASuccessful, generate1RSAFailed); |
| } |
| function generate1RSASuccessful(certificate) |
| { |
| certRSA = certificate; |
| testPassed(generateCallString); |
| certificateSanityCheck('certRSA'); |
| generate2ECDSA(); |
| } |
| function generate1RSAFailed() |
| { |
| testFailed(generateCallString); |
| generate2ECDSA(); |
| } |
| |
| // 2: ECDSA using NIST P-256. |
| function generate2ECDSA() |
| { |
| generateCallString = 'generateCertificate({ name: "ECDSA", namedCurve: "P-256" })'; |
| RTCPeerConnection.generateCertificate({ name: "ECDSA", namedCurve: "P-256" }) |
| .then(generate2ECDSASuccessful, generate2ECDSAFailed); |
| } |
| function generate2ECDSASuccessful(certificate) |
| { |
| certECDSA = certificate; |
| testPassed(generateCallString); |
| certificateSanityCheck('certECDSA'); |
| generate3ExpiresNegativeOneDay(); |
| } |
| function generate2ECDSAFailed() |
| { |
| testFailed(generateCallString); |
| generate3ExpiresNegativeOneDay(); |
| } |
| |
| // 3-5: Verify that the |expires| attribute works (generate ECDSA because its faster). |
| function generate3ExpiresNegativeOneDay() |
| { |
| generateCallString = 'generateCertificate({ name: "ECDSA", namedCurve: "P-256", expires:-dayInMs })'; |
| RTCPeerConnection.generateCertificate({ name: "ECDSA", namedCurve: "P-256", expires:-dayInMs }) |
| .then(function(certificate) { certExpiresNegativeOneDay = certificate; generate4ExpiresZero(); }, generate4ExpiresZero); |
| } |
| function generate4ExpiresZero() |
| { |
| generateCallString = 'generateCertificate({ name: "ECDSA", namedCurve: "P-256", expires:0 })'; |
| RTCPeerConnection.generateCertificate({ name: "ECDSA", namedCurve: "P-256", expires:0 }) |
| .then(function(certificate) { certExpiresZero = certificate; generate5ExpiresPositiveOneDay(); }, generate5ExpiresPositiveOneDay); |
| } |
| function generate5ExpiresPositiveOneDay() |
| { |
| generateCallString = 'generateCertificate({ name: "ECDSA", namedCurve: "P-256", expires:dayInMs })'; // +1 day |
| RTCPeerConnection.generateCertificate({ name: "ECDSA", namedCurve: "P-256", expires:dayInMs }) |
| .then(function(certificate) { certExpiresPositiveOneDay = certificate; generate3to5ExpiresResolved(); }, generate3to5ExpiresResolved); |
| } |
| function generate3to5ExpiresResolved() |
| { |
| // A negative |expires| value is not a DOMTimeStamp, it should be ignored and |
| // generate a certificate that has not expired. |
| certificateSanityCheck('certExpiresNegativeOneDay'); |
| |
| // Check that the zero expiration certificate was generated but has expired. |
| shouldBeNonNull('certExpiresZero'); |
| shouldBeTrue('new Date().getTime() >= certExpiresZero.expires'); |
| |
| // Check that the +1 day expiration certificate expires in approximately 1 day (+/- 1 minute). |
| shouldBeNonNull('certExpiresPositiveOneDay'); |
| shouldBeTrue('Math.abs(certExpiresPositiveOneDay.expires - (new Date().getTime() + dayInMs)) <= minuteInMs'); |
| |
| finishJSTest(); |
| } |
| |
| // Helper functions. |
| function certificateSanityCheck(certVariableName) |
| { |
| shouldBeNonNull(certVariableName); |
| shouldBeTrue('new Date().getTime() < ' + certVariableName + '.expires'); |
| shouldBeTrue(certVariableName + '.getFingerprints().length == 1'); |
| shouldBeTrue(certVariableName + '.getFingerprints()[0].algorithm === "sha-256"'); |
| shouldBeTrue('isFingerprintValue(' + certVariableName + '.getFingerprints()[0].value)'); |
| // Fingerprints are dictionaries, a copy should be returned each time. |
| shouldBeTrue(certVariableName + '.getFingerprints()[0] != ' + certVariableName + '.getFingerprints()[0]'); |
| } |
| function isFingerprintValue(fingerprint) { |
| // / Begin regex |
| // ^ Start of line |
| // (?: Non-capturing parenthesis |
| // [a-z0-9]{2} 2 lowercase alphanumeric characters |
| // \: The : character |
| // )+ End of parenthesis, match 1 or more times |
| // [a-z0-9]{2} 2 lowercase alphanumeric characters |
| // $ End of line |
| // / End of regex |
| return /^(?:[a-z0-9]{2}\:)+[a-z0-9]{2}$/.test(fingerprint); |
| } |
| |
| // Run each generate test sequentially. The ith generate method will make sure |
| // the (i+1)st generate method is executed when its promise's callbacks are |
| // invoked. generate2ECDSA's callback methods mark the end of the async tests. |
| generate1RSA(); |
| |
| window.jsTestIsAsync = true; |
| window.successfullyParsed = true; |
| </script> |
| </body> |
| </html> |