You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@shindig.apache.org by jo...@apache.org on 2010/06/30 00:04:49 UTC
svn commit: r959124 - in /shindig/trunk/features: ./
src/main/javascript/features/ src/main/javascript/features/shindig.random/
Author: johnh
Date: Tue Jun 29 22:04:49 2010
New Revision: 959124
URL: http://svn.apache.org/viewvc?rev=959124&view=rev
Log:
shindig.random implementation, v1. A more-secure Math.random() in pure JS.
Added:
shindig/trunk/features/src/main/javascript/features/shindig.random/feature.xml
shindig/trunk/features/src/main/javascript/features/shindig.random/random.js
Modified:
shindig/trunk/features/NOTICE
shindig/trunk/features/src/main/javascript/features/features.txt
shindig/trunk/features/src/main/javascript/features/shindig.random/sha1.js
Modified: shindig/trunk/features/NOTICE
URL: http://svn.apache.org/viewvc/shindig/trunk/features/NOTICE?rev=959124&r1=959123&r2=959124&view=diff
==============================================================================
--- shindig/trunk/features/NOTICE (original)
+++ shindig/trunk/features/NOTICE Tue Jun 29 22:04:49 2010
@@ -22,3 +22,4 @@ Geoff Stearns, Michael Williams, and Bob
This product includes software (opensocial-resources) developed by
The OpenSocial Foundation (http://opensocial-resources.googlecode.com/svn/spec/0.8/)
+This product contains software (sha1 JS impl) developed by Google Inc.
Modified: shindig/trunk/features/src/main/javascript/features/features.txt
URL: http://svn.apache.org/viewvc/shindig/trunk/features/src/main/javascript/features/features.txt?rev=959124&r1=959123&r2=959124&view=diff
==============================================================================
--- shindig/trunk/features/src/main/javascript/features/features.txt (original)
+++ shindig/trunk/features/src/main/javascript/features/features.txt Tue Jun 29 22:04:49 2010
@@ -62,6 +62,7 @@ features/settitle/feature.xml
features/shindig.auth/feature.xml
features/shindig.container/feature.xml
features/shindig.container-1.0/feature.xml
+features/shindig.random/feature.xml
features/shindig.xhrwrapper/feature.xml
features/skins/feature.xml
features/swfobject/feature.xml
Added: shindig/trunk/features/src/main/javascript/features/shindig.random/feature.xml
URL: http://svn.apache.org/viewvc/shindig/trunk/features/src/main/javascript/features/shindig.random/feature.xml?rev=959124&view=auto
==============================================================================
--- shindig/trunk/features/src/main/javascript/features/shindig.random/feature.xml (added)
+++ shindig/trunk/features/src/main/javascript/features/shindig.random/feature.xml Tue Jun 29 22:04:49 2010
@@ -0,0 +1,29 @@
+<?xml version="1.0"?>
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations under the License.
+-->
+<feature>
+<!--
+A JavaScript "more-secure-random" implementation.
+-->
+ <name>shindig.random</name>
+ <dependency>globals</dependency>
+ <container>
+ <script src="sha1.js"/>
+ <script src="saferrandom.js"/>
+ </container>
+</feature>
Added: shindig/trunk/features/src/main/javascript/features/shindig.random/random.js
URL: http://svn.apache.org/viewvc/shindig/trunk/features/src/main/javascript/features/shindig.random/random.js?rev=959124&view=auto
==============================================================================
--- shindig/trunk/features/src/main/javascript/features/shindig.random/random.js (added)
+++ shindig/trunk/features/src/main/javascript/features/shindig.random/random.js Tue Jun 29 22:04:49 2010
@@ -0,0 +1,72 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ */
+
+/*
+ * @fileoverview
+ * This code implements a safer random() method that is seeded from
+ * screen width/height and (presumably random/unguessable) mouse
+ * movement, in an effort to create a better seed for random().
+ *
+ * Its aim is to solve the problem of gadgets that are relying on
+ * secret RPC tokens to validate identity.
+ *
+ * Another possible solution is to use XHR to get a real random number
+ * from the server, though this is not feasible or may be too slow in
+ * some circumstances.
+ */
+shindig.random = (function() {
+ var oth = Math.random();
+ var hex = '0123456789ABCDEF';
+ var start = 1;
+ var m = ((screen.width * screen.width) + screen.height) * 1e6;
+
+ function sha1(str) {
+ var s = shindig.sha1();
+ s.update(str);
+ var arr = s.digest();
+ var hash = '';
+ for (var i = 0; i < arr.length; i++) {
+ hash += hex.charAt(Math.floor(arr[i] / 16)) + hex.charAt(arr[i] % 16);
+ }
+ return hash;
+ }
+
+ var orig_onmousemove = window.onmousemove || function() { return false };
+
+ window.onmousemove = function(e) {
+ if (window.event) {
+ e = event;
+ }
+
+ var ac = (e.screenX ^ e.clientX) << 16;
+ ac += (e.screenY ^ e.clientY);
+ ac *= new Date().getTime() % 1e6;
+ start = (start * ac) % m;
+ return orig_onmousemove.call(window, Array.prototype.slice.call(arguments));
+ };
+
+ var seed = sha1(
+ document.cookie + '|' + document.location + '|' + (new Date()).getTime() + '|' + oth);
+
+ return function() {
+ var rnd = start;
+ rnd += parseInt(seed.substr(0, 20), 16);
+ seed = sha1(seed);
+ return rnd / (m + Math.pow(16, 20));
+ }
+})();
Modified: shindig/trunk/features/src/main/javascript/features/shindig.random/sha1.js
URL: http://svn.apache.org/viewvc/shindig/trunk/features/src/main/javascript/features/shindig.random/sha1.js?rev=959124&r1=959123&r2=959124&view=diff
==============================================================================
--- shindig/trunk/features/src/main/javascript/features/shindig.random/sha1.js (original)
+++ shindig/trunk/features/src/main/javascript/features/shindig.random/sha1.js Tue Jun 29 22:04:49 2010
@@ -1,28 +1,24 @@
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// Copyright 2005 Google Inc. All Rights Reserved
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS-IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ */
+
+// File copied directly from Closure Library (http://code.google.com/p/closure-library)
+// Imported into Shindig w/ slight namespacing modifications and change from
+// prototype-style to closure (ironically) style JS objects.
/**
* @fileoverview SHA-1 cryptographic hash.
@@ -30,35 +26,32 @@
* http://csrc.nist.gov/publications/fips/fips180-3/fips180-3_final.pdf.
*
* Usage:
- * var sha1 = new goog.crypt.sha1();
+ * var sha1 = shindig.sha1();
* sha1.update(bytes);
* var hash = sha1.digest();
- *
*/
-goog.provide('goog.crypt.Sha1');
-
/**
* SHA-1 cryptographic hash constructor.
*
* The properties declared here are discussed in the above algorithm document.
* @constructor
*/
-goog.crypt.Sha1 = function() {
+shindig.sha1 = (function() {
/**
* Holds the previous values of accumulated variables a-e in the compress_
* function.
* @type {Array.<number>}
* @private
*/
- this.chain_ = [];
+ var chain_ = [];
/**
* A buffer holding the partially computed hash result.
* @type {Array.<number>}
* @private
*/
- this.buf_ = [];
+ var buf_ = [];
/**
* An array of 80 bytes, each a part of the message to be hashed. Referred to
@@ -66,183 +59,184 @@ goog.crypt.Sha1 = function() {
* @type {Array.<number>}
* @private
*/
- this.W_ = [];
+ var W_ = [];
/**
* Contains data needed to pad messages less than 64 bytes.
* @type {Array.<number>}
* @private
*/
- this.pad_ = [];
+ var pad_ = [];
- this.pad_[0] = 128;
+ pad_[0] = 128;
for (var i = 1; i < 64; ++i) {
- this.pad_[i] = 0;
+ pad_[i] = 0;
}
- this.reset();
-};
-
+ /**
+ * Resets the internal accumulator.
+ */
+ function reset() {
+ chain_[0] = 0x67452301;
+ chain_[1] = 0xefcdab89;
+ chain_[2] = 0x98badcfe;
+ chain_[3] = 0x10325476;
+ chain_[4] = 0xc3d2e1f0;
-/**
- * Resets the internal accumulator.
- */
-goog.crypt.Sha1.prototype.reset = function() {
- this.chain_[0] = 0x67452301;
- this.chain_[1] = 0xefcdab89;
- this.chain_[2] = 0x98badcfe;
- this.chain_[3] = 0x10325476;
- this.chain_[4] = 0xc3d2e1f0;
-
- this.inbuf_ = 0;
- this.total_ = 0;
-};
+ inbuf_ = 0;
+ total_ = 0;
+ }
+ /**
+ * Internal helper performing 32 bit left rotate.
+ * @param {number} w 32-bit integer to rotate.
+ * @param {number} r Bits to rotate left by.
+ * @return {number} w rotated left by r bits.
+ * @private
+ */
+ function rotl_(w, r) {
+ return ((w << r) | (w >>> (32 - r))) & 0xffffffff;
+ }
-/**
- * Internal helper performing 32 bit left rotate.
- * @param {number} w 32-bit integer to rotate.
- * @param {number} r Bits to rotate left by.
- * @return {number} w rotated left by r bits.
- * @private
- */
-goog.crypt.Sha1.prototype.rotl_ = function(w, r) {
- return ((w << r) | (w >>> (32 - r))) & 0xffffffff;
-};
+ /**
+ * Internal compress helper function.
+ * @param {Array} buf containing block to compress.
+ * @private
+ */
+ function compress_(buf) {
+ var W = W_;
+ // get 16 big endian words
+ for (var i = 0; i < 64; i += 4) {
+ var w = (buf[i] << 24) |
+ (buf[i + 1] << 16) |
+ (buf[i + 2] << 8) |
+ (buf[i + 3]);
+ W[i / 4] = w;
+ }
-/**
- * Internal compress helper function.
- * @param {Array} buf containing block to compress.
- * @private
- */
-goog.crypt.Sha1.prototype.compress_ = function(buf) {
- var W = this.W_;
+ // expand to 80 words
+ for (var i = 16; i < 80; i++) {
+ W[i] = rotl_(W[i - 3] ^ W[i - 8] ^ W[i - 14] ^ W[i - 16], 1);
+ }
- // get 16 big endian words
- for (var i = 0; i < 64; i += 4) {
- var w = (buf[i] << 24) |
- (buf[i + 1] << 16) |
- (buf[i + 2] << 8) |
- (buf[i + 3]);
- W[i / 4] = w;
- }
-
- // expand to 80 words
- for (var i = 16; i < 80; i++) {
- W[i] = this.rotl_(W[i - 3] ^ W[i - 8] ^ W[i - 14] ^ W[i - 16], 1);
- }
-
- var a = this.chain_[0];
- var b = this.chain_[1];
- var c = this.chain_[2];
- var d = this.chain_[3];
- var e = this.chain_[4];
- var f, k;
-
- for (var i = 0; i < 80; i++) {
- if (i < 40) {
- if (i < 20) {
- f = d ^ (b & (c ^ d));
- k = 0x5a827999;
- } else {
- f = b ^ c ^ d;
- k = 0x6ed9eba1;
- }
- } else {
- if (i < 60) {
- f = (b & c) | (d & (b | c));
- k = 0x8f1bbcdc;
+ var a = chain_[0];
+ var b = chain_[1];
+ var c = chain_[2];
+ var d = chain_[3];
+ var e = chain_[4];
+ var f, k;
+
+ for (var i = 0; i < 80; i++) {
+ if (i < 40) {
+ if (i < 20) {
+ f = d ^ (b & (c ^ d));
+ k = 0x5a827999;
+ } else {
+ f = b ^ c ^ d;
+ k = 0x6ed9eba1;
+ }
} else {
- f = b ^ c ^ d;
- k = 0xca62c1d6;
+ if (i < 60) {
+ f = (b & c) | (d & (b | c));
+ k = 0x8f1bbcdc;
+ } else {
+ f = b ^ c ^ d;
+ k = 0xca62c1d6;
+ }
}
- }
-
- var t = (this.rotl_(a, 5) + f + e + k + W[i]) & 0xffffffff;
- e = d;
- d = c;
- c = this.rotl_(b, 30);
- b = a;
- a = t;
- }
-
- this.chain_[0] = (this.chain_[0] + a) & 0xffffffff;
- this.chain_[1] = (this.chain_[1] + b) & 0xffffffff;
- this.chain_[2] = (this.chain_[2] + c) & 0xffffffff;
- this.chain_[3] = (this.chain_[3] + d) & 0xffffffff;
- this.chain_[4] = (this.chain_[4] + e) & 0xffffffff;
-};
+ var t = (rotl_(a, 5) + f + e + k + W[i]) & 0xffffffff;
+ e = d;
+ d = c;
+ c = rotl_(b, 30);
+ b = a;
+ a = t;
+ }
-/**
- * Adds a byte array to internal accumulator.
- * @param {Array.<number>} bytes to add to digest.
- * @param {number=} opt_length is # of bytes to compress.
- */
-goog.crypt.Sha1.prototype.update = function(bytes, opt_length) {
- if (!opt_length) {
- opt_length = bytes.length;
+ chain_[0] = (chain_[0] + a) & 0xffffffff;
+ chain_[1] = (chain_[1] + b) & 0xffffffff;
+ chain_[2] = (chain_[2] + c) & 0xffffffff;
+ chain_[3] = (chain_[3] + d) & 0xffffffff;
+ chain_[4] = (chain_[4] + e) & 0xffffffff;
}
- var n = 0;
-
- // Optimize for 64 byte chunks at 64 byte boundaries.
- if (this.inbuf_ == 0) {
- while (n + 64 < opt_length) {
- this.compress_(bytes.slice(n, n + 64));
- n += 64;
- this.total_ += 64;
+ /**
+ * Adds a byte array to internal accumulator.
+ * @param {Array.<number>} bytes to add to digest.
+ * @param {number=} opt_length is # of bytes to compress.
+ */
+ function update(bytes, opt_length) {
+ if (!opt_length) {
+ opt_length = bytes.length;
}
- }
-
- while (n < opt_length) {
- this.buf_[this.inbuf_++] = bytes[n++];
- this.total_++;
- if (this.inbuf_ == 64) {
- this.inbuf_ = 0;
- this.compress_(this.buf_);
+ var n = 0;
- // Pick up 64 byte chunks.
+ // Optimize for 64 byte chunks at 64 byte boundaries.
+ if (inbuf_ == 0) {
while (n + 64 < opt_length) {
- this.compress_(bytes.slice(n, n + 64));
+ compress_(bytes.slice(n, n + 64));
n += 64;
- this.total_ += 64;
+ total_ += 64;
}
}
- }
-};
-
-/**
- * @return {Array} byte[20] containing finalized hash.
- */
-goog.crypt.Sha1.prototype.digest = function() {
- var digest = [];
- var totalBits = this.total_ * 8;
-
- // Add pad 0x80 0x00*.
- if (this.inbuf_ < 56) {
- this.update(this.pad_, 56 - this.inbuf_);
- } else {
- this.update(this.pad_, 64 - (this.inbuf_ - 56));
+ while (n < opt_length) {
+ buf_[inbuf_++] = bytes[n++];
+ total_++;
+
+ if (inbuf_ == 64) {
+ inbuf_ = 0;
+ compress_(buf_);
+
+ // Pick up 64 byte chunks.
+ while (n + 64 < opt_length) {
+ compress_(bytes.slice(n, n + 64));
+ n += 64;
+ total_ += 64;
+ }
+ }
+ }
}
- // Add # bits.
- for (var i = 63; i >= 56; i--) {
- this.buf_[i] = totalBits & 255;
- totalBits >>>= 8;
- }
+ /**
+ * @return {Array} byte[20] containing finalized hash.
+ */
+ function digest() {
+ var digest = [];
+ var totalBits = total_ * 8;
+
+ // Add pad 0x80 0x00*.
+ if (inbuf_ < 56) {
+ update(pad_, 56 - inbuf_);
+ } else {
+ update(pad_, 64 - (inbuf_ - 56));
+ }
+
+ // Add # bits.
+ for (var i = 63; i >= 56; i--) {
+ buf_[i] = totalBits & 255;
+ totalBits >>>= 8;
+ }
- this.compress_(this.buf_);
+ compress_(buf_);
- var n = 0;
- for (var i = 0; i < 5; i++) {
- for (var j = 24; j >= 0; j -= 8) {
- digest[n++] = (this.chain_[i] >> j) & 255;
+ var n = 0;
+ for (var i = 0; i < 5; i++) {
+ for (var j = 24; j >= 0; j -= 8) {
+ digest[n++] = (chain_[i] >> j) & 255;
+ }
}
+
+ return digest;
}
- return digest;
-};
+ reset();
+
+ return {
+ reset: reset,
+ update: update,
+ digest: digest
+ };
+});