test_certDB_import.js (5124B)
1 // -*- indent-tabs-mode: nil; js-indent-level: 2 -*- 2 // Any copyright is dedicated to the Public Domain. 3 // http://creativecommons.org/publicdomain/zero/1.0/ 4 "use strict"; 5 6 // Tests the various nsIX509CertDB import methods. 7 8 do_get_profile(); 9 10 const gCertDB = Cc["@mozilla.org/security/x509certdb;1"].getService( 11 Ci.nsIX509CertDB 12 ); 13 14 const CA_CERT_COMMON_NAME = "importedCA"; 15 const TEST_EMAIL_ADDRESS = "test@example.com"; 16 17 let gCACertImportDialogCount = 0; 18 19 // Mock implementation of nsICertificateDialogs. 20 const gCertificateDialogs = { 21 confirmDownloadCACert: (ctx, cert, trust) => { 22 gCACertImportDialogCount++; 23 equal( 24 cert.commonName, 25 CA_CERT_COMMON_NAME, 26 "CA cert to import should have the correct CN" 27 ); 28 trust.value = Ci.nsIX509CertDB.TRUSTED_EMAIL; 29 return true; 30 }, 31 setPKCS12FilePassword: () => { 32 // This is only relevant to exporting. 33 ok(false, "setPKCS12FilePassword() should not have been called"); 34 }, 35 getPKCS12FilePassword: () => { 36 // We don't test anything that calls this method yet. 37 ok(false, "getPKCS12FilePassword() should not have been called"); 38 }, 39 40 QueryInterface: ChromeUtils.generateQI(["nsICertificateDialogs"]), 41 }; 42 43 // Implements nsIInterfaceRequestor. Mostly serves to mock nsIPrompt. 44 const gInterfaceRequestor = { 45 alert: (title, text) => { 46 // We don't test anything that calls this method yet. 47 ok(false, `alert() should not have been called: ${text}`); 48 }, 49 50 getInterface: iid => { 51 if (iid.equals(Ci.nsIPrompt)) { 52 return this; 53 } 54 55 throw Components.Exception("", Cr.NS_ERROR_NO_INTERFACE); 56 }, 57 }; 58 59 function getCertAsByteArray(certPath) { 60 let certFile = do_get_file(certPath, false); 61 let certBytes = readFile(certFile); 62 63 let byteArray = []; 64 for (let i = 0; i < certBytes.length; i++) { 65 byteArray.push(certBytes.charCodeAt(i)); 66 } 67 68 return byteArray; 69 } 70 71 function commonFindCertBy(propertyName, value) { 72 for (let cert of gCertDB.getCerts()) { 73 if (cert[propertyName] == value) { 74 return cert; 75 } 76 } 77 return null; 78 } 79 80 function findCertByCommonName(commonName) { 81 return commonFindCertBy("commonName", commonName); 82 } 83 84 function findCertByEmailAddress(emailAddress) { 85 return commonFindCertBy("emailAddress", emailAddress); 86 } 87 88 function testImportCACert() { 89 // Sanity check the CA cert is missing. 90 equal( 91 findCertByCommonName(CA_CERT_COMMON_NAME), 92 null, 93 "CA cert should not be in the database before import" 94 ); 95 96 // Import and check for success. 97 let caArray = getCertAsByteArray("test_certDB_import/importedCA.pem"); 98 gCertDB.importCertificates( 99 caArray, 100 caArray.length, 101 Ci.nsIX509Cert.CA_CERT, 102 gInterfaceRequestor 103 ); 104 equal( 105 gCACertImportDialogCount, 106 1, 107 "Confirmation dialog for the CA cert should only be shown once" 108 ); 109 110 let caCert = findCertByCommonName(CA_CERT_COMMON_NAME); 111 notEqual(caCert, null, "CA cert should now be found in the database"); 112 ok( 113 gCertDB.isCertTrusted( 114 caCert, 115 Ci.nsIX509Cert.CA_CERT, 116 Ci.nsIX509CertDB.TRUSTED_EMAIL 117 ), 118 "CA cert should be trusted for e-mail" 119 ); 120 } 121 122 function testImportEmptyCertPackage() { 123 // Because this is an empty cert package, nothing will be imported. We know it succeeded if no errors are thrown. 124 let byteArray = [ 125 0x30, 0x0f, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x86, 0xf8, 0x42, 0x02, 126 0x05, 0xa0, 0x02, 0x30, 0x00, 127 ]; 128 gCertDB.importCertificates( 129 byteArray, 130 byteArray.length, 131 Ci.nsIX509Cert.CA_CERT, 132 gInterfaceRequestor 133 ); 134 } 135 136 function testImportEmptyUserCert() { 137 // Because this is an empty cert package, nothing will be imported. We know it succeeded if no errors are thrown. 138 let byteArray = [ 139 0x30, 0x0f, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x86, 0xf8, 0x42, 0x02, 140 0x05, 0xa0, 0x02, 0x30, 0x00, 141 ]; 142 gCertDB.importUserCertificate( 143 byteArray, 144 byteArray.length, 145 gInterfaceRequestor 146 ); 147 } 148 149 function run_test() { 150 let certificateDialogsCID = MockRegistrar.register( 151 "@mozilla.org/nsCertificateDialogs;1", 152 gCertificateDialogs 153 ); 154 registerCleanupFunction(() => { 155 MockRegistrar.unregister(certificateDialogsCID); 156 }); 157 158 // Sanity check the e-mail cert is missing. 159 equal( 160 findCertByEmailAddress(TEST_EMAIL_ADDRESS), 161 null, 162 "E-mail cert should not be in the database before import" 163 ); 164 165 // Import the CA cert so that the e-mail import succeeds. 166 testImportCACert(); 167 testImportEmptyCertPackage(); 168 testImportEmptyUserCert(); 169 170 // Import the e-mail cert and check for success. 171 let emailArray = getCertAsByteArray("test_certDB_import/emailEE.pem"); 172 gCertDB.importEmailCertificate( 173 emailArray, 174 emailArray.length, 175 gInterfaceRequestor 176 ); 177 let emailCert = findCertByEmailAddress(TEST_EMAIL_ADDRESS); 178 notEqual(emailCert, null, "E-mail cert should now be found in the database"); 179 let bundle = Services.strings.createBundle( 180 "chrome://pipnss/locale/pipnss.properties" 181 ); 182 equal( 183 emailCert.tokenName, 184 bundle.GetStringFromName("PrivateTokenDescription"), 185 "cert's tokenName should be the expected localized value" 186 ); 187 }