source: trip-planner-front/node_modules/node-forge/lib/random.js@ 76712b2

Last change on this file since 76712b2 was 6a3a178, checked in by Ema <ema_spirova@…>, 3 years ago

initial commit

  • Property mode set to 100644
File size: 5.3 KB
RevLine 
[6a3a178]1/**
2 * An API for getting cryptographically-secure random bytes. The bytes are
3 * generated using the Fortuna algorithm devised by Bruce Schneier and
4 * Niels Ferguson.
5 *
6 * Getting strong random bytes is not yet easy to do in javascript. The only
7 * truish random entropy that can be collected is from the mouse, keyboard, or
8 * from timing with respect to page loads, etc. This generator makes a poor
9 * attempt at providing random bytes when those sources haven't yet provided
10 * enough entropy to initially seed or to reseed the PRNG.
11 *
12 * @author Dave Longley
13 *
14 * Copyright (c) 2009-2014 Digital Bazaar, Inc.
15 */
16var forge = require('./forge');
17require('./aes');
18require('./sha256');
19require('./prng');
20require('./util');
21
22(function() {
23
24// forge.random already defined
25if(forge.random && forge.random.getBytes) {
26 module.exports = forge.random;
27 return;
28}
29
30(function(jQuery) {
31
32// the default prng plugin, uses AES-128
33var prng_aes = {};
34var _prng_aes_output = new Array(4);
35var _prng_aes_buffer = forge.util.createBuffer();
36prng_aes.formatKey = function(key) {
37 // convert the key into 32-bit integers
38 var tmp = forge.util.createBuffer(key);
39 key = new Array(4);
40 key[0] = tmp.getInt32();
41 key[1] = tmp.getInt32();
42 key[2] = tmp.getInt32();
43 key[3] = tmp.getInt32();
44
45 // return the expanded key
46 return forge.aes._expandKey(key, false);
47};
48prng_aes.formatSeed = function(seed) {
49 // convert seed into 32-bit integers
50 var tmp = forge.util.createBuffer(seed);
51 seed = new Array(4);
52 seed[0] = tmp.getInt32();
53 seed[1] = tmp.getInt32();
54 seed[2] = tmp.getInt32();
55 seed[3] = tmp.getInt32();
56 return seed;
57};
58prng_aes.cipher = function(key, seed) {
59 forge.aes._updateBlock(key, seed, _prng_aes_output, false);
60 _prng_aes_buffer.putInt32(_prng_aes_output[0]);
61 _prng_aes_buffer.putInt32(_prng_aes_output[1]);
62 _prng_aes_buffer.putInt32(_prng_aes_output[2]);
63 _prng_aes_buffer.putInt32(_prng_aes_output[3]);
64 return _prng_aes_buffer.getBytes();
65};
66prng_aes.increment = function(seed) {
67 // FIXME: do we care about carry or signed issues?
68 ++seed[3];
69 return seed;
70};
71prng_aes.md = forge.md.sha256;
72
73/**
74 * Creates a new PRNG.
75 */
76function spawnPrng() {
77 var ctx = forge.prng.create(prng_aes);
78
79 /**
80 * Gets random bytes. If a native secure crypto API is unavailable, this
81 * method tries to make the bytes more unpredictable by drawing from data that
82 * can be collected from the user of the browser, eg: mouse movement.
83 *
84 * If a callback is given, this method will be called asynchronously.
85 *
86 * @param count the number of random bytes to get.
87 * @param [callback(err, bytes)] called once the operation completes.
88 *
89 * @return the random bytes in a string.
90 */
91 ctx.getBytes = function(count, callback) {
92 return ctx.generate(count, callback);
93 };
94
95 /**
96 * Gets random bytes asynchronously. If a native secure crypto API is
97 * unavailable, this method tries to make the bytes more unpredictable by
98 * drawing from data that can be collected from the user of the browser,
99 * eg: mouse movement.
100 *
101 * @param count the number of random bytes to get.
102 *
103 * @return the random bytes in a string.
104 */
105 ctx.getBytesSync = function(count) {
106 return ctx.generate(count);
107 };
108
109 return ctx;
110}
111
112// create default prng context
113var _ctx = spawnPrng();
114
115// add other sources of entropy only if window.crypto.getRandomValues is not
116// available -- otherwise this source will be automatically used by the prng
117var getRandomValues = null;
118var globalScope = forge.util.globalScope;
119var _crypto = globalScope.crypto || globalScope.msCrypto;
120if(_crypto && _crypto.getRandomValues) {
121 getRandomValues = function(arr) {
122 return _crypto.getRandomValues(arr);
123 };
124}
125
126if(forge.options.usePureJavaScript ||
127 (!forge.util.isNodejs && !getRandomValues)) {
128 // if this is a web worker, do not use weak entropy, instead register to
129 // receive strong entropy asynchronously from the main thread
130 if(typeof window === 'undefined' || window.document === undefined) {
131 // FIXME:
132 }
133
134 // get load time entropy
135 _ctx.collectInt(+new Date(), 32);
136
137 // add some entropy from navigator object
138 if(typeof(navigator) !== 'undefined') {
139 var _navBytes = '';
140 for(var key in navigator) {
141 try {
142 if(typeof(navigator[key]) == 'string') {
143 _navBytes += navigator[key];
144 }
145 } catch(e) {
146 /* Some navigator keys might not be accessible, e.g. the geolocation
147 attribute throws an exception if touched in Mozilla chrome://
148 context.
149
150 Silently ignore this and just don't use this as a source of
151 entropy. */
152 }
153 }
154 _ctx.collect(_navBytes);
155 _navBytes = null;
156 }
157
158 // add mouse and keyboard collectors if jquery is available
159 if(jQuery) {
160 // set up mouse entropy capture
161 jQuery().mousemove(function(e) {
162 // add mouse coords
163 _ctx.collectInt(e.clientX, 16);
164 _ctx.collectInt(e.clientY, 16);
165 });
166
167 // set up keyboard entropy capture
168 jQuery().keypress(function(e) {
169 _ctx.collectInt(e.charCode, 8);
170 });
171 }
172}
173
174/* Random API */
175if(!forge.random) {
176 forge.random = _ctx;
177} else {
178 // extend forge.random with _ctx
179 for(var key in _ctx) {
180 forge.random[key] = _ctx[key];
181 }
182}
183
184// expose spawn PRNG
185forge.random.createInstance = spawnPrng;
186
187module.exports = forge.random;
188
189})(typeof(jQuery) !== 'undefined' ? jQuery : null);
190
191})();
Note: See TracBrowser for help on using the repository browser.