// -*- Mode: javascript; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. "use strict"; do_get_profile(); const gCertDB = Cc["@mozilla.org/security/x509certdb;1"].getService( Ci.nsIX509CertDB ); function run_test() { // This certificate has a number of placeholder byte sequences that we can // replace with invalid UTF-8 to ensure that we handle these cases safely. let certificateToAlterFile = do_get_file( "test_cert_utf8/certificateToAlter.pem", false ); let certificateBytesToAlter = atob( pemToBase64(readFile(certificateToAlterFile)) ); testUTF8InField("issuerName", "ISSUER CN", certificateBytesToAlter); testUTF8InField("issuerOrganization", "ISSUER O", certificateBytesToAlter); testUTF8InField( "issuerOrganizationUnit", "ISSUER OU", certificateBytesToAlter ); testUTF8InField("issuerCommonName", "ISSUER CN", certificateBytesToAlter); testUTF8InField("organization", "SUBJECT O", certificateBytesToAlter); testUTF8InField("organizationalUnit", "SUBJECT OU", certificateBytesToAlter); testUTF8InField("subjectName", "SUBJECT CN", certificateBytesToAlter); testUTF8InField("displayName", "SUBJECT CN", certificateBytesToAlter); testUTF8InField("commonName", "SUBJECT CN", certificateBytesToAlter); testUTF8InField( "emailAddress", "SUBJECT EMAILADDRESS", certificateBytesToAlter ); } // Every (issuer, serial number) pair must be unique. If NSS ever encounters two // different (in terms of encoding) certificates with the same values for this // pair, it will refuse to import it (even as a temporary certificate). Since // we're creating a number of different certificates, we need to ensure this // pair is always unique. The easiest way to do this is to change the issuer // distinguished name each time. To make sure this doesn't introduce additional // UTF8 issues, always use a printable ASCII value. var gUniqueIssuerCounter = 32; function testUTF8InField(field, replacementPrefix, certificateBytesToAlter) { let toReplace = `${replacementPrefix} REPLACE ME`; let replacement = ""; for (let i = 0; i < toReplace.length; i++) { replacement += "\xEB"; } let bytes = certificateBytesToAlter.replace(toReplace, replacement); let uniqueIssuerReplacement = "ALWAYS MAKE ME UNIQU" + String.fromCharCode(gUniqueIssuerCounter); bytes = bytes.replace("ALWAYS MAKE ME UNIQUE", uniqueIssuerReplacement); Assert.less( gUniqueIssuerCounter, 127, "should have enough ASCII replacements to make a unique issuer DN" ); gUniqueIssuerCounter++; let cert = gCertDB.constructX509(stringToArray(bytes)); notEqual(cert[field], null, `accessing nsIX509Cert.${field} shouldn't fail`); notEqual( cert.getEmailAddresses(), null, "calling nsIX509Cert.getEmailAddresses() shouldn't assert" ); ok( !cert.containsEmailAddress("test@test.test"), "calling nsIX509Cert.containsEmailAddress() shouldn't assert" ); }