UNPKG

@talex/electron-windows-store

Version:
242 lines (213 loc) 22.5 kB
'use strict' const fs = require('fs-extra') const path = require('path') const mockery = require('mockery') const ChildProcessMock = require('../fixtures/child_process') const sign = require('../../lib/sign') const utils = require('../../lib/utils') describe('Sign', () => { const tmpDir = path.join(require('os').tmpdir(), 'electron-windows-store-cert-test') let passedArgs = [] let passedProcess = [] const cpMock = { spawn(_process, _args) { passedProcess.push(_process) passedArgs.push(_args) return new ChildProcessMock() } } before(() => { fs.ensureDirSync(tmpDir) }) after(() => { fs.removeSync(tmpDir) }) afterEach(() => { mockery.deregisterAll() passedArgs = [] passedProcess = [] }) describe('signappx()', () => { it('should attempt to sign the current app', function (done) { const programMock = { inputDirectory: '/fakepath/to/input', outputDirectory: '/fakepath/to/output', windowsKit: '/fakepath/to/windows/kit/bin', packageName: 'testapp', devCert: 'fakepath/to/devcert.pfx' } mockery.registerMock('child_process', cpMock) sign.signAppx(programMock) .then(() => { const expectedScript = path.join(programMock.windowsKit, 'signtool.exe') const expectedPfxFile = programMock.devCert const expectedAppx = path.join(programMock.outputDirectory, `${programMock.packageName}.appx`) const expectedParams = ['sign', '-f', expectedPfxFile, '-fd', 'SHA256', '-v', expectedAppx] passedProcess.length.should.equal(1) passedProcess[0].should.equal(expectedScript) passedArgs[0].should.deep.equal(expectedParams) done() }) }) it('should pass along the certificate password', function () { const programMock = { inputDirectory: '/fakepath/to/input', outputDirectory: '/fakepath/to/output', windowsKit: '/fakepath/to/windows/kit/bin', packageName: 'testapp', devCert: 'fakepath/to/devcert.p12', certPass: '12345' } mockery.registerMock('child_process', cpMock) return sign.signAppx(programMock) .then(() => { const expectedScript = path.join(programMock.windowsKit, 'signtool.exe') const expectedPfxFile = programMock.devCert const expectedAppx = path.join(programMock.outputDirectory, `${programMock.packageName}.appx`) const expectedParams = ['sign', '-f', expectedPfxFile, '-fd', 'SHA256', '-v', '-p', '12345', expectedAppx] passedProcess.length.should.equal(1) passedProcess[0].should.equal(expectedScript) passedArgs[0].should.deep.equal(expectedParams) }) }) it('should reject if no certificate is present', function () { const programMock = {} return sign.signAppx(programMock).should.be.rejected }) }) describe('makeCert()', () => { it('should not attempt to import certificate when install === false', function (done) { mockery.registerMock('child_process', cpMock) sign.makeCert({ publisherName: 'CN=Test', certFilePath: tmpDir, install: false, program: { windowsKit: '/fake/kit' } }) .then(() => { passedArgs.every((args) => { return args.every(arg => arg.indexOf('Import-PfxCertificate') === -1) }).should.equal(true) done() }) .catch(() => {}) }) }) describe('isValidPublisherName()', () => { const windowsSdkPath = process.arch === 'x64' ? 'C:\\Program Files (x86)\\Windows Kits\\10\\bin\\x64' : 'C:\\Program Files\\Windows Kits\\10\\bin\\x64'; const makecertExe = path.join(windowsSdkPath, 'makecert.exe') const pvkFileName = path.resolve(__dirname, 'bogus-private-key.pvk'); const skipMakeCertExecution = !fs.existsSync(makecertExe) || !fs.existsSync(pvkFileName) const scenarios = [{ publisherName: '' }, { publisherName: 'CN=' }, { publisherName: 'CN=-' }, { publisherName: 'cn=lower, ou=case' }, { publisherName: 'CN=first.last' }, { publisherName: 'CN="Pointlessly quoted"' }, { publisherName: 'CN=no,o=spaces' }, { publisherName: 'CN=" Leading and Trailing Spaces "' }, { publisherName: 'CN=Common Name,O=Some organization' }, { publisherName: 'O="Quoted comma, Inc."' }, { publisherName: 'CN=!@#$^&*()[]{}<>|\/.~\'-=,O="Symbols are Cool, LLC"' }, { publisherName: 'OU=Sales+CN=J. Smith,O=Multi-valued' }, { publisherName: 'CN=Duplicate+CN=Attribute' }, { publisherName: 'OU=Trailing plus+', }, { publisherName: 'CN=trailing comma,', }, { publisherName: 'CN="Escaped\\ and\\ quoted\\ spaces"' }, { publisherName: 'CN=First M Last, O="Acme, Inc."' }, { publisherName: 'CN=Marshall T. Rose, O=Dover Beach Consulting, L=Santa Clara,ST=California, C=US' }, { publisherName: 'CN=FTAM Service, CN=Bells, OU=Computer Science,\nO=University College London, C=GB' }, { publisherName: 'CN=Markus Kuhn, O=University of Erlangen, T=Mr., C=DE' }, { publisherName: 'CN=Steve Kille,\n O=ISODE Consortium,\n C=GB' }, { publisherName: 'CN=Christian Huitema; O=INRIA; C=FR' }, { publisherName: 'CN=This is a really long distinguished name: 2048 chars!........................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................' }, { publisherName: 'CN=Even longer: 4096 chars 0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678' }, { publisherName: 'CN=Long enough for anyone: 8192 chars 012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123' }, { publisherName: 'CN=L. Eagle, O="Sue, Grabbit and Runn", C=GB' }, { publisherName: 'O=No CN' }, { publisherName: 'SERIALNUMBER=1' }, { publisherName: 'DC=A,CN=B,OU=C,O=D,STREET=123 Main St.,L=Big City,ST=Nowhere,C=XX,SN=Surname,GN=Given name,E=nobody@example.com,S=E,T=F,G=G,I=1.2.3.4' }, { publisherName: 'CN="+"', }, { publisherName: 'CN=X+' }, { publisherName: 'X', expectInvalid: true }, { publisherName: 'CN=X,UID=userId', expectInvalid: true }, { publisherName: 'CN=\ Escaped leading space"', expectInvalid: true }, { publisherName: 'CN="Quotation \\" Mark"', expectInvalid: true }, { publisherName: 'CN=X,DNQ=qualifier', expectInvalid: true }, { // According to RFC1779 and RFC2243 this should be legal but MakeCert.exe does not seem to accept it publisherName: 'CN=Sue\\, Grabbit and Runn', expectInvalid: true }] scenarios.forEach((scenario) => { const actualResult = sign.isValidPublisherName(scenario.publisherName) let nameToPrint = scenario.publisherName.replace(/\n/g, '\\n') if (nameToPrint.length > 60) nameToPrint = nameToPrint.slice(0,61) + '...' // Compare pre-determined checks (previously confirmed with makecert.exe) it(`return ${scenario.expectInvalid ? 'false' : 'true'} for ${nameToPrint}`, () => { actualResult.should.equal(!scenario.expectInvalid, scenario.publisherName) }) // Run makecert.exe and check whether or not it fails with this publisherName if (!skipMakeCertExecution) { const rnd = Date.now() + '-' + Math.floor(Math.random()*10000) const crtFileName = path.join(tmpDir, `makecert-${rnd}.crt`) const makecertArgs = ['-r', '-h', '0', '-n', scenario.publisherName, '-eku', '1.3.6.1.5.5.7.3.3', '-pe', '-sv', pvkFileName, crtFileName] it(`makecert.exe should ${scenario.expectInvalid ? 'fail' : 'succeed'} for ${nameToPrint}`, () => { return utils.executeChildProcess(makecertExe, makecertArgs) .then(() => { return true }) .catch(() => { return false }) .should.eventually.equal(!scenario.expectInvalid) }) } }) if (skipMakeCertExecution) { it.skip('should be re-tested against actual MakeCert.exe from SDK') } }) })