cryptoprng.spec.js 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  1. /*
  2. * Copyright 2018 Scytl Secure Electronic Voting SA
  3. *
  4. * All rights reserved
  5. *
  6. * See our extended copyright notice in *file 'Copyright.txt' which is part of this source code package
  7. */
  8. describe('cryptoPRNG...', function() {
  9. 'use strict';
  10. describe('should be able to ..', function() {
  11. var privateKeyPem =
  12. '-----BEGIN RSA PRIVATE KEY-----MIIEowIBAAKCAQEAglypZU45bnf2opnRI+Y51VqouBpvDT33xIB/OtbwKzwVpi+JrjBFtfk33tE9t/dSRs79CK94HRhCWcOiLa2qWPrjeZ9SBiEyScrhIvRZVBF41zBgwQNuRvJCsKmAqlZaFNJDZxEP4repmlBn1CfVFmfrXmOKqwP5F7l9ZtucveRzsfmF1yVPFkW8TMuB3YqMiyymyqHlS8ujCsu5I8tpgPbwuxdMOY94fNhSXrYkY8IuX1g1zdq/Z1jluOaR/UqK4UpnbuJaH/F0VgDNiWh6cTD0DFGEk0b70i5wU4Q3L/S6XZQRvSuADoCbhwBKuFL5pW5n865oLVb5S3wuVdWaGwIDAQABAoIBAC/tn34Wf3kE9BGeGc1oFLVDaqqdVVz5/oEpeR2J7q0GnzMFYUpAhzC7WvY52cYsUPyll1Q9Jx0TUTmteo/uvKWQQFfz4nVMeS+2PoXabolBDzuWlsv/1eiRo0FOYHa/3siu8YcQN9X0DpAkpbfTmT1uoZOHZ3EuucMmOFu7vGn38Grw8bSxpR0uvTtnb8ygC+aB51y38RMyhzQQanrM8FMeAfDAy6IB0Yo7b0c50Cxa6Ax4nqn9LXyGakr5WeAMkgTIOA/GId9SZD4e5eRpq+628pOeR4O9datFltgl6r1+A4ii2VrJsDqeatGtODlX6KRKqwFHoGIa2TjgSZLuorECgYEAxeSZDOOgFsI5mB7RkRzZaQ9znJ15sgdyZiAFZAOUah4hSGdAXNAnZTlrdacduXEu3EfkpuPToX7xZSv5FRYwfBwMwCLeytlGLPjQzWejZGbo4+KqgzWb9fECDYVtDPlJ/+yLih9nt67BHweJKxYydl18rVigdVyy22X86NijSykCgYEAqKPUrXZAo+TJvmTw4tgsibJgvXBYBhmsej8mGNQw+Nyp2gV28sgm61ifIeXKS8teq+MFwGA6cHQedbsCqhMHokdhESZmlbWxhSFLihQcewBxwvrBwbaxI23yXRzwMewznZFL032PpcbqrmwFmcSSEZ3nmbvTH6ShqLW+pzDNp6MCgYBQLzdgxJ7qedqSa/JohTMG4e7rh9d2rpPJE7J7ewPZF8pOpx+qO+Gqn2COdJ+Ts2vUcAETKn9nEaPIZc/wnmQY9dioxbhWo0FPGaaphBPtq9Ez/XUv4zoFppk5V1X/isdUPsmvttf00oeIBiqrXbwmv+yz5JRn2Z7TTXjz9Ev+OQKBgQCUuoCMRzl1EgcXIqEL/0kwW6BUEqufHa9u1Ri9Vw6lvL8T6DPipMEmWK9nzuid9gtVns/ovTVtDgv7GuabplLaPQePf4WDzY11c0rSyS/hDyBFrK+LL5uEOqhAlJAGB2HyOj1clWVF+GvrTpuV5LZKUS/79pmZU7G7QCaX/0Ow7wKBgC/kDH7cmWQnWvvJ5izrx/7PogQVPOLELeUIGLu/hjsSdDKiFCxCUZ948+9NuG+DnpXDWzw//r8mPBRRGGsqFws5Aipp7yjQ3kRDCCzGelPCVhHyfmKqA+8ewXPulKS3/wIyHIvaXmsuAtTfurHtpRyzjKmCBK1Y6WQ3trIXvo7s-----END RSA PRIVATE KEY-----';
  13. afterEach(function() {
  14. cryptoPRNG._privateKeyPem = '';
  15. cryptoPRNG._pinEntropy = 0;
  16. cryptoPRNG._usePrivateKeyEntropy = false;
  17. });
  18. it('not execute entropy collector if pinEntropy is not a number',
  19. function() {
  20. cryptolib('cryptoprng', function() {
  21. spyOn(cryptoPRNG, '_noWindow').and.returnValue(false);
  22. spyOn(cryptoPRNG, '_getCrypto').and.returnValue(null);
  23. spyOn(cryptoPRNG.Collectors, 'getPrivateKeyCollector')
  24. .and.callThrough();
  25. cryptoPRNG.setDataForPrivateKeyEntropyCollector(
  26. privateKeyPem, 'x10');
  27. cryptoPRNG.startEntropyCollection();
  28. cryptoPRNG.stopEntropyCollectionAndCreatePRNG();
  29. expect(cryptoPRNG.Collectors.getPrivateKeyCollector)
  30. .not.toHaveBeenCalled();
  31. });
  32. });
  33. it('execute entropy collector only if pinEntropy is bigger than 0',
  34. function() {
  35. cryptolib('cryptoprng', function() {
  36. spyOn(cryptoPRNG, '_noWindow').and.returnValue(false);
  37. spyOn(cryptoPRNG, '_getCrypto').and.returnValue(null);
  38. spyOn(cryptoPRNG.Collectors, 'getPrivateKeyCollector')
  39. .and.callThrough();
  40. cryptoPRNG.setDataForPrivateKeyEntropyCollector(privateKeyPem, 0);
  41. cryptoPRNG.startEntropyCollection();
  42. cryptoPRNG.stopEntropyCollectionAndCreatePRNG();
  43. expect(cryptoPRNG.Collectors.getPrivateKeyCollector)
  44. .not.toHaveBeenCalled();
  45. });
  46. });
  47. it('execute entropy collector only if private key is not empty',
  48. function() {
  49. cryptolib('cryptoprng', function() {
  50. spyOn(cryptoPRNG, '_noWindow').and.returnValue(false);
  51. spyOn(cryptoPRNG, '_getCrypto').and.returnValue(null);
  52. spyOn(cryptoPRNG.Collectors, 'getPrivateKeyCollector')
  53. .and.callThrough();
  54. cryptoPRNG.setDataForPrivateKeyEntropyCollector('', 10);
  55. cryptoPRNG.startEntropyCollection();
  56. cryptoPRNG.stopEntropyCollectionAndCreatePRNG();
  57. expect(cryptoPRNG.Collectors.getPrivateKeyCollector)
  58. .not.toHaveBeenCalled();
  59. });
  60. });
  61. it('add private key entropy collector', function() {
  62. cryptolib('cryptoprng', function() {
  63. spyOn(cryptoPRNG, '_noWindow').and.returnValue(false);
  64. spyOn(cryptoPRNG, '_getCrypto').and.returnValue(null);
  65. spyOn(cryptoPRNG.Collectors, 'getPrivateKeyCollector')
  66. .and.callThrough();
  67. cryptoPRNG.setDataForPrivateKeyEntropyCollector(privateKeyPem, 100);
  68. cryptoPRNG.startEntropyCollection();
  69. cryptoPRNG.stopEntropyCollectionAndCreatePRNG();
  70. expect(cryptoPRNG.Collectors.getPrivateKeyCollector).toHaveBeenCalled();
  71. });
  72. });
  73. it('add entropy from private key pem', function() {
  74. cryptolib('cryptoprng', function() {
  75. spyOn(cryptoPRNG, '_noWindow').and.returnValue(false);
  76. spyOn(cryptoPRNG, '_getCrypto').and.returnValue(null);
  77. spyOn(cryptoPRNG, '_collectEntropy').and.callThrough();
  78. cryptoPRNG.setDataForPrivateKeyEntropyCollector(privateKeyPem, 100);
  79. cryptoPRNG.startEntropyCollection();
  80. cryptoPRNG.stopEntropyCollectionAndCreatePRNG();
  81. var privateKey = forge.pki.privateKeyFromPem(privateKeyPem);
  82. var args = cryptoPRNG._collectEntropy.calls.argsFor(0);
  83. expect(args[0]).toEqual(privateKey.d);
  84. expect(args[1]).toEqual(100);
  85. });
  86. });
  87. it('throw exception when private key pem is not correct', function() {
  88. cryptolib('cryptoprng', function() {
  89. var privateKeyPemInvalid = ['Invalid Pem'].join('\n');
  90. spyOn(cryptoPRNG, '_noWindow').and.returnValue(false);
  91. spyOn(cryptoPRNG, '_getCrypto').and.returnValue(null);
  92. spyOn(cryptoPRNG, 'startEntropyCollection').and.callThrough();
  93. cryptoPRNG.setDataForPrivateKeyEntropyCollector(
  94. privateKeyPemInvalid, 100);
  95. expect(function() {
  96. cryptoPRNG.startEntropyCollection();
  97. }).toThrowError('Invalid PEM formatted message.');
  98. });
  99. });
  100. it('properly handle entropy collection when window is not defined',
  101. function() {
  102. cryptolib('cryptoprng', function() {
  103. spyOn(cryptoPRNG, '_noWindow').and.returnValue(true);
  104. spyOn(cryptoPRNG, '_addNonWindowEntropyCollectors')
  105. .and.callThrough();
  106. spyOn(cryptoPRNG, '_getCrypto').and.callThrough();
  107. cryptoPRNG.startEntropyCollection();
  108. cryptoPRNG.stopEntropyCollectionAndCreatePRNG();
  109. expect(cryptoPRNG._addNonWindowEntropyCollectors).toHaveBeenCalled();
  110. expect(cryptoPRNG._getCrypto).not.toHaveBeenCalled();
  111. });
  112. });
  113. describe('return percentage of entropy collected ..', function() {
  114. it('equal to 100 when max entropy number is reached', function() {
  115. cryptolib('cryptoprng', function() {
  116. cryptoPRNG._maxEntropyCounter = 300;
  117. cryptoPRNG._entropyCounter = cryptoPRNG._maxEntropyCounter;
  118. expect(cryptoPRNG.getEntropyCollectedAsPercentage()).toEqual(100);
  119. });
  120. });
  121. it('equal to 100 when entropy counter is bigger than max entropy number',
  122. function() {
  123. cryptolib('cryptoprng', function() {
  124. cryptoPRNG._entropyCounter = cryptoPRNG._maxEntropyCounter + 1;
  125. expect(cryptoPRNG.getEntropyCollectedAsPercentage()).toEqual(100);
  126. });
  127. });
  128. it('equal to 0 when entropy counter is set to 0', function() {
  129. cryptolib('cryptoprng', function() {
  130. cryptoPRNG._entropyCounter = 0;
  131. expect(cryptoPRNG.getEntropyCollectedAsPercentage()).toEqual(0);
  132. });
  133. });
  134. it('equal to 50 when entropy counter = max entropy / 2', function() {
  135. cryptolib('cryptoprng', function() {
  136. cryptoPRNG._maxEntropyCounter = 300;
  137. cryptoPRNG._entropyCounter = cryptoPRNG._maxEntropyCounter / 2;
  138. expect(cryptoPRNG.getEntropyCollectedAsPercentage()).toEqual(50);
  139. });
  140. });
  141. it('equal to 10 when entropy counter is 10% of maximum entropy',
  142. function() {
  143. cryptolib('cryptoprng', function() {
  144. cryptoPRNG._maxEntropyCounter = 300;
  145. cryptoPRNG._entropyCounter = cryptoPRNG._maxEntropyCounter / 10;
  146. expect(cryptoPRNG.getEntropyCollectedAsPercentage()).toEqual(10);
  147. });
  148. });
  149. });
  150. });
  151. });