test_cert_utf8.js (3163B)
1 // -*- Mode: javascript; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- 2 // This Source Code Form is subject to the terms of the Mozilla Public 3 // License, v. 2.0. If a copy of the MPL was not distributed with this 4 // file, You can obtain one at http://mozilla.org/MPL/2.0/. 5 6 "use strict"; 7 8 do_get_profile(); 9 10 const gCertDB = Cc["@mozilla.org/security/x509certdb;1"].getService( 11 Ci.nsIX509CertDB 12 ); 13 14 function run_test() { 15 // This certificate has a number of placeholder byte sequences that we can 16 // replace with invalid UTF-8 to ensure that we handle these cases safely. 17 let certificateToAlterFile = do_get_file( 18 "test_cert_utf8/certificateToAlter.pem", 19 false 20 ); 21 let certificateBytesToAlter = atob( 22 pemToBase64(readFile(certificateToAlterFile)) 23 ); 24 testUTF8InField("issuerName", "ISSUER CN", certificateBytesToAlter); 25 testUTF8InField("issuerOrganization", "ISSUER O", certificateBytesToAlter); 26 testUTF8InField( 27 "issuerOrganizationUnit", 28 "ISSUER OU", 29 certificateBytesToAlter 30 ); 31 testUTF8InField("issuerCommonName", "ISSUER CN", certificateBytesToAlter); 32 testUTF8InField("organization", "SUBJECT O", certificateBytesToAlter); 33 testUTF8InField("organizationalUnit", "SUBJECT OU", certificateBytesToAlter); 34 testUTF8InField("subjectName", "SUBJECT CN", certificateBytesToAlter); 35 testUTF8InField("displayName", "SUBJECT CN", certificateBytesToAlter); 36 testUTF8InField("commonName", "SUBJECT CN", certificateBytesToAlter); 37 testUTF8InField( 38 "emailAddress", 39 "SUBJECT EMAILADDRESS", 40 certificateBytesToAlter 41 ); 42 } 43 44 // Every (issuer, serial number) pair must be unique. If NSS ever encounters two 45 // different (in terms of encoding) certificates with the same values for this 46 // pair, it will refuse to import it (even as a temporary certificate). Since 47 // we're creating a number of different certificates, we need to ensure this 48 // pair is always unique. The easiest way to do this is to change the issuer 49 // distinguished name each time. To make sure this doesn't introduce additional 50 // UTF8 issues, always use a printable ASCII value. 51 var gUniqueIssuerCounter = 32; 52 53 function testUTF8InField(field, replacementPrefix, certificateBytesToAlter) { 54 let toReplace = `${replacementPrefix} REPLACE ME`; 55 let replacement = ""; 56 for (let i = 0; i < toReplace.length; i++) { 57 replacement += "\xEB"; 58 } 59 let bytes = certificateBytesToAlter.replace(toReplace, replacement); 60 let uniqueIssuerReplacement = 61 "ALWAYS MAKE ME UNIQU" + String.fromCharCode(gUniqueIssuerCounter); 62 bytes = bytes.replace("ALWAYS MAKE ME UNIQUE", uniqueIssuerReplacement); 63 Assert.less( 64 gUniqueIssuerCounter, 65 127, 66 "should have enough ASCII replacements to make a unique issuer DN" 67 ); 68 gUniqueIssuerCounter++; 69 let cert = gCertDB.constructX509(stringToArray(bytes)); 70 notEqual(cert[field], null, `accessing nsIX509Cert.${field} shouldn't fail`); 71 notEqual( 72 cert.getEmailAddresses(), 73 null, 74 "calling nsIX509Cert.getEmailAddresses() shouldn't assert" 75 ); 76 ok( 77 !cert.containsEmailAddress("test@test.test"), 78 "calling nsIX509Cert.containsEmailAddress() shouldn't assert" 79 ); 80 }