Browse Source
Rewrote comments in the example configuration. Moved all global test code into a plugin (plugin-test-authorize.js).pull/28/head
10 changed files with 386 additions and 108 deletions
@ -0,0 +1,109 @@ |
|||||||
|
/* |
||||||
|
* Spreed Speak Freely. |
||||||
|
* Copyright (C) 2013-2014 struktur AG |
||||||
|
* |
||||||
|
* This file is part of Spreed Speak Freely. |
||||||
|
* |
||||||
|
* This program is free software: you can redistribute it and/or modify |
||||||
|
* it under the terms of the GNU Affero General Public License as published by |
||||||
|
* the Free Software Foundation, either version 3 of the License, or |
||||||
|
* (at your option) any later version. |
||||||
|
* |
||||||
|
* This program is distributed in the hope that it will be useful, |
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||||
|
* GNU Affero General Public License for more details. |
||||||
|
* |
||||||
|
* You should have received a copy of the GNU Affero General Public License |
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
* |
||||||
|
*/ |
||||||
|
define(['angular', 'sjcl'], function(angular, sjcl) { |
||||||
|
|
||||||
|
return { |
||||||
|
|
||||||
|
initialize: function(app) { |
||||||
|
|
||||||
|
var lastNonce = null; |
||||||
|
var lastUserid = null; |
||||||
|
var disconnectTimeout = null; |
||||||
|
|
||||||
|
app.run(["$window", "mediaStream", function($window, mediaStream) { |
||||||
|
|
||||||
|
console.log("Injecting test plugin functions to window ..."); |
||||||
|
|
||||||
|
$window.testDisconnect = function() { |
||||||
|
if (disconnectTimeout) { |
||||||
|
$window.clearInterval(disconnectTimeout); |
||||||
|
disconnectTimeout = null; |
||||||
|
console.info("Stopped disconnector."); |
||||||
|
return; |
||||||
|
} |
||||||
|
disconnectTimeout = $window.setInterval(function() { |
||||||
|
console.info("Test disconnect!"); |
||||||
|
mediaStream.connector.conn.close(); |
||||||
|
}, 10000); |
||||||
|
console.info("Started disconnector."); |
||||||
|
}; |
||||||
|
|
||||||
|
$window.testCreateSuserid = function(key, userid) { |
||||||
|
|
||||||
|
var k = sjcl.codec.utf8String.toBits(key); |
||||||
|
var foo = new sjcl.misc.hmac(k, sjcl.hash.sha256) |
||||||
|
var expiration = parseInt(((new Date).getTime()/1000)+3600, 10); |
||||||
|
var useridCombo = ""+expiration+":"+userid; |
||||||
|
var secret = foo.mac(useridCombo); |
||||||
|
return [useridCombo, sjcl.codec.base64.fromBits(secret)] |
||||||
|
|
||||||
|
}; |
||||||
|
|
||||||
|
$window.testAuthorize = function(useridCombo, secret) { |
||||||
|
|
||||||
|
console.log("Testing authorize with userid", useridCombo, secret); |
||||||
|
var url = mediaStream.url.api("sessions") + "/" + mediaStream.api.id + "/"; |
||||||
|
console.log("URL", url); |
||||||
|
var data = { |
||||||
|
id: mediaStream.api.id, |
||||||
|
sid: mediaStream.api.sid, |
||||||
|
useridcombo: useridCombo, |
||||||
|
secret: secret |
||||||
|
} |
||||||
|
console.log("Data", data); |
||||||
|
$.ajax({ |
||||||
|
type: "PATCH", |
||||||
|
url: url, |
||||||
|
contentType: "application/json", |
||||||
|
dataType: "json", |
||||||
|
data: JSON.stringify(data), |
||||||
|
success: function(data) { |
||||||
|
if (data.success) { |
||||||
|
lastNonce = data.nonce; |
||||||
|
lastUserid = data.userid; |
||||||
|
console.log("Retrieved nonce", lastNonce, lastUserid); |
||||||
|
} |
||||||
|
}, |
||||||
|
error: function() { |
||||||
|
console.log("error", arguments) |
||||||
|
} |
||||||
|
}); |
||||||
|
|
||||||
|
}; |
||||||
|
|
||||||
|
$window.testAuthenticate = function() { |
||||||
|
|
||||||
|
if (!lastNonce || !lastUserid) { |
||||||
|
console.log("Run testAuthorize first."); |
||||||
|
return |
||||||
|
} |
||||||
|
|
||||||
|
mediaStream.api.requestAuthentication(lastUserid, lastNonce); |
||||||
|
|
||||||
|
}; |
||||||
|
|
||||||
|
}]); |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
}); |
@ -1,35 +1,99 @@ |
|||||||
# Spreed Speak Freely server example configuration |
; Spreed Speak Freely server example configuration |
||||||
|
|
||||||
[http] |
[http] |
||||||
|
; HTTP listener in format ip:port. |
||||||
listen = 127.0.0.1:8080 |
listen = 127.0.0.1:8080 |
||||||
#root = /usr/share/spreed-speakfreely-server/www |
; Full path to directory where to find the server web assets. |
||||||
#readtimeout = 10 |
;root = /usr/share/spreed-speakfreely-server/www |
||||||
#writetimeout = 10 |
; HTTP socket read timeout in seconds. |
||||||
#basePath = /some/sub/path/ # Set this when running behind a web server under a sub path. |
;readtimeout = 10 |
||||||
#maxfd = 32768 # Try to set max open files limit on start (works only when run as root). |
; HTTP socket write timeout in seconds. |
||||||
#stats = true # Provide stats API at /api/v1/stats (do not enable this in production or unprotected!). |
;writetimeout = 10 |
||||||
#pprofListen = 127.0.0.1:6060 # See http://golang.org/pkg/net/http/pprof/ for details |
; Use basePath if the server does not run on the root path (/) of your server. |
||||||
|
;basePath = /some/sub/path/ |
||||||
|
; Set maximum number of open files (only works when run as root). |
||||||
|
;maxfd = 32768 |
||||||
|
; Enable stats API /api/v1/stats for debugging (not for production use!). |
||||||
|
;stats = false |
||||||
|
; Enable HTTP listener for golang pprof module. See |
||||||
|
; http://golang.org/pkg/net/http/pprof/ for details. |
||||||
|
;pprofListen = 127.0.0.1:6060 |
||||||
|
|
||||||
[https] |
[https] |
||||||
#listen = 127.0.0.1:8443 |
; Native HTTPS listener in format ip:port. |
||||||
#certificate = server.crt # Full path to certificate. |
;listen = 127.0.0.1:8443 |
||||||
#key = server.key # Full path to key. |
; Full path to PEM encoded certificate chain. |
||||||
#minVersion = SSLv3 # Minimal supported encryption (SSLv3, TLSv1, TLSv1.1, TLSv1.2). |
;certificate = server.crt |
||||||
#readtimeout = 10 |
; Full path to PEM encoded private key. |
||||||
#writetimeout = 10 |
;key = server.key |
||||||
|
; Mimimal supported encryption standard (SSLv3, TLSv1, TLSv1.1 or TLSv1.2). |
||||||
|
;minVersion = SSLv3 |
||||||
|
; HTTPS socket read timeout in seconds. |
||||||
|
;readtimeout = 10 |
||||||
|
; HTTPS socket write timeout in seconds. |
||||||
|
;writetimeout = 10 |
||||||
|
|
||||||
[app] |
[app] |
||||||
#title = Spreed Speak Freely |
; HTML page title |
||||||
#ver = 1234 # version string to use for static resource |
;title = Spreed Speak Freely |
||||||
#stunURIs = stun.l.google.com:19302 |
; Version string to use for static resources. This defaults to the server |
||||||
#turnURIs = turn:turnserver:port?transport=udp turn:anotherturnserver:port?transport=tcp turns:turnserver:443?transport=tcp |
; version and should only be changed when you use your own way to invalidate |
||||||
#turnSecret = the-default-turn-shared-secret-do-not-keep |
; long cached static resources. |
||||||
sessionSecret = the-default-secret-do-not-keep-me # Use 32 or 64 bytes random data |
;ver = 1234 |
||||||
#tokenFile = tokens.txt # If set, everyone needs to give one of the tokens to launch the web client. One token per line in the file. |
; STUN server URIs in format host:port. You can provide multiple seperated by |
||||||
#globalRoom = global # Enables a global room. Users in that room are in all rooms. |
; space. If you do not have one use a public one like stun.l.google.com:19302. |
||||||
#defaultRoomEnabled = true # Set to false to disable default room. |
; If you have a TURN server you do not need to set an STUN server as the TURN |
||||||
#extra = /usr/share/spreed-speakfreely-server/extra # Extra templates directory. Add .html files to define extra-* template slots here. |
; server will normally do STUN too. |
||||||
#plugin = plugins/example1 # Plugin support. |
;stunURIs = stun.l.google.com:19302 |
||||||
|
; TURN server URIs in format host:port?transport=udp|tcp. You can provide |
||||||
|
; multiple seperated by space. If you do not have at least one TURN server then |
||||||
|
; some users will not be able to use the server as the peer to peer connection |
||||||
|
; cannot be established without a TURN server due to firewall reasons. An open |
||||||
|
; source TURN server which is fully supported can be found at |
||||||
|
; https://code.google.com/p/rfc5766-turn-server/. |
||||||
|
;turnURIs = turn:turnserver:port?transport=udp turns:turnserver:443?transport=tcp |
||||||
|
; Shared secret authentication for TURN user generation if the TURN server is |
||||||
|
; protected (which it should be). |
||||||
|
; See http://tools.ietf.org/html/draft-uberti-behave-turn-rest-00 for details. |
||||||
|
; A supported TURN server is https://code.google.com/p/rfc5766-turn-server/. |
||||||
|
;turnSecret = the-default-turn-shared-secret-do-not-keep |
||||||
|
; Session secret to use for session id generator. 32 or 64 bytes of random data |
||||||
|
; are recommented. |
||||||
|
sessionSecret = the-default-secret-do-not-keep-me |
||||||
|
; Full path to a text file containig client tokens which a user needs to enter |
||||||
|
; when accessing the web client. Each line in this file represents a valid token. |
||||||
|
;tokenFile = tokens.txt |
||||||
|
; The name of a global room. If enabled it should be kept secret. Users in that |
||||||
|
; room are visible in all other rooms. |
||||||
|
;globalRoom = global |
||||||
|
; The default room is the room at the root URL of the servers base address and |
||||||
|
; all users will join this room if enabled. If it is disabled then a room join |
||||||
|
; form will be shown instead. |
||||||
|
;defaultRoomEnabled = true |
||||||
|
; Full path to an extra templates directory. Templates in this directory ending |
||||||
|
; with .html will be parsed on startup and can be used to fill the supported |
||||||
|
; extra-* template slots. If the extra folder has a sub folder "static", the |
||||||
|
; resources in this static folder will be available as /extra/static/filename |
||||||
|
; relative to your servers base URL. |
||||||
|
;extra = /usr/share/spreed-speakfreely-server/extra |
||||||
|
; URL relative to the servers base path for a plugin javascript file which is |
||||||
|
; automatically loaded on web client start for all users. You can put your |
||||||
|
; plugin in the extra/static folder (see above) or provide another folder using |
||||||
|
; a front end webserver. Check the doc folder for more info about plugins and |
||||||
|
; examples. |
||||||
|
;plugin = extra/static/myplugin.js |
||||||
|
|
||||||
[log] |
[log] |
||||||
#logfile = /var/log/spreed-speakfreely-server.log |
;logfile = /var/log/spreed-speakfreely-server.log |
||||||
|
|
||||||
|
[users] |
||||||
|
; Set to true to enable user functionality. |
||||||
|
;enabled = false |
||||||
|
; Set authorization mode for users. Currently implemented is the "sharedsecret" |
||||||
|
; mode which does validate the userid with a HMAC authentication secret. |
||||||
|
; The format goes like this: |
||||||
|
; BASE64(HMAC-SHA-256(secret, expirationTimestampInSeconds:userid)) |
||||||
|
;mode = sharedsecret |
||||||
|
; The shared secred for HMAC validation in "sharedsecret" mode. Best use 32 or |
||||||
|
; 64 bytes of random data. |
||||||
|
;sharedsecret_secret = some-secret-do-not-keep |
||||||
|
@ -0,0 +1,112 @@ |
|||||||
|
/* |
||||||
|
* Spreed Speak Freely. |
||||||
|
* Copyright (C) 2013-2014 struktur AG |
||||||
|
* |
||||||
|
* This file is part of Spreed Speak Freely. |
||||||
|
* |
||||||
|
* This program is free software: you can redistribute it and/or modify |
||||||
|
* it under the terms of the GNU Affero General Public License as published by |
||||||
|
* the Free Software Foundation, either version 3 of the License, or |
||||||
|
* (at your option) any later version. |
||||||
|
* |
||||||
|
* This program is distributed in the hope that it will be useful, |
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||||
|
* GNU Affero General Public License for more details. |
||||||
|
* |
||||||
|
* You should have received a copy of the GNU Affero General Public License |
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
* |
||||||
|
*/ |
||||||
|
|
||||||
|
package main |
||||||
|
|
||||||
|
import ( |
||||||
|
"crypto/hmac" |
||||||
|
"crypto/sha256" |
||||||
|
"encoding/base64" |
||||||
|
"errors" |
||||||
|
"github.com/strukturag/phoenix" |
||||||
|
"log" |
||||||
|
"strconv" |
||||||
|
"strings" |
||||||
|
"time" |
||||||
|
) |
||||||
|
|
||||||
|
type UsersHandler interface { |
||||||
|
Validate(snr *SessionNonceRequest) (string, error) |
||||||
|
} |
||||||
|
|
||||||
|
type UsersSharedsecretHandler struct { |
||||||
|
secret []byte |
||||||
|
} |
||||||
|
|
||||||
|
func (uh *UsersSharedsecretHandler) Validate(snr *SessionNonceRequest) (string, error) { |
||||||
|
|
||||||
|
// Parse UseridCombo.
|
||||||
|
useridCombo := strings.SplitN(snr.UseridCombo, ":", 2) |
||||||
|
expirationString, userid := useridCombo[0], useridCombo[1] |
||||||
|
|
||||||
|
expiration, err := strconv.ParseInt(expirationString, 10, 64) |
||||||
|
if err != nil { |
||||||
|
return "", err |
||||||
|
} |
||||||
|
|
||||||
|
// Check expiration.
|
||||||
|
if time.Unix(expiration, 0).Before(time.Now()) { |
||||||
|
return "", errors.New("expired secret") |
||||||
|
} |
||||||
|
|
||||||
|
// Check HMAC.
|
||||||
|
foo := hmac.New(sha256.New, uh.secret) |
||||||
|
foo.Write([]byte(snr.UseridCombo)) |
||||||
|
fooSecret := base64.StdEncoding.EncodeToString(foo.Sum(nil)) |
||||||
|
if snr.Secret != fooSecret { |
||||||
|
return "", errors.New("invalid secret") |
||||||
|
} |
||||||
|
|
||||||
|
return userid, nil |
||||||
|
} |
||||||
|
|
||||||
|
type Users struct { |
||||||
|
Enabled bool |
||||||
|
Handler UsersHandler |
||||||
|
} |
||||||
|
|
||||||
|
func NewUsers(runtime phoenix.Runtime) *Users { |
||||||
|
|
||||||
|
enabled := false |
||||||
|
enabledString, err := runtime.GetString("users", "enabled") |
||||||
|
if err == nil { |
||||||
|
enabled = enabledString == "true" |
||||||
|
} |
||||||
|
|
||||||
|
var handler UsersHandler |
||||||
|
|
||||||
|
if enabled { |
||||||
|
|
||||||
|
mode, _ := runtime.GetString("users", "mode") |
||||||
|
switch mode { |
||||||
|
case "sharedsecret": |
||||||
|
secret, _ := runtime.GetString("users", "sharedsecret_secret") |
||||||
|
if secret != "" { |
||||||
|
handler = &UsersSharedsecretHandler{secret: []byte(secret)} |
||||||
|
} |
||||||
|
default: |
||||||
|
mode = "" |
||||||
|
} |
||||||
|
|
||||||
|
if handler == nil { |
||||||
|
enabled = false |
||||||
|
} else { |
||||||
|
log.Printf("Enabled users handler '%s'.\n", mode) |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
return &Users{ |
||||||
|
Enabled: enabled, |
||||||
|
Handler: handler, |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,26 @@ |
|||||||
|
// http://bitwiseshiftleft.github.io/sjcl/
|
||||||
|
// ./configure --without-all --with-sha256 --with-sha512 --with-sha1 --with-hmac --with-codecBase64 --with-codecString
|
||||||
|
// Copyright 2009-2010 Emily Stark, Mike Hamburg, Dan Boneh, Stanford University.
|
||||||
|
// SJCL is dual-licensed under the GNU GPL version 2.0 or higher, and a 2-clause BSD license.
|
||||||
|
"use strict";var sjcl={cipher:{},hash:{},keyexchange:{},mode:{},misc:{},codec:{},exception:{corrupt:function(a){this.toString=function(){return"CORRUPT: "+this.message};this.message=a},invalid:function(a){this.toString=function(){return"INVALID: "+this.message};this.message=a},bug:function(a){this.toString=function(){return"BUG: "+this.message};this.message=a},notReady:function(a){this.toString=function(){return"NOT READY: "+this.message};this.message=a}}}; |
||||||
|
"undefined"!==typeof module&&module.exports&&(module.exports=sjcl); |
||||||
|
sjcl.bitArray={bitSlice:function(a,b,c){a=sjcl.bitArray.l(a.slice(b/32),32-(b&31)).slice(1);return void 0===c?a:sjcl.bitArray.clamp(a,c-b)},extract:function(a,b,c){var e=Math.floor(-b-c&31);return((b+c-1^b)&-32?a[b/32|0]<<32-e^a[b/32+1|0]>>>e:a[b/32|0]>>>e)&(1<<c)-1},concat:function(a,b){if(0===a.length||0===b.length)return a.concat(b);var c=a[a.length-1],e=sjcl.bitArray.getPartial(c);return 32===e?a.concat(b):sjcl.bitArray.l(b,e,c|0,a.slice(0,a.length-1))},bitLength:function(a){var b=a.length;return 0=== |
||||||
|
b?0:32*(b-1)+sjcl.bitArray.getPartial(a[b-1])},clamp:function(a,b){if(32*a.length<b)return a;a=a.slice(0,Math.ceil(b/32));var c=a.length;b&=31;0<c&&b&&(a[c-1]=sjcl.bitArray.partial(b,a[c-1]&2147483648>>b-1,1));return a},partial:function(a,b,c){return 32===a?b:(c?b|0:b<<32-a)+0x10000000000*a},getPartial:function(a){return Math.round(a/0x10000000000)||32},equal:function(a,b){if(sjcl.bitArray.bitLength(a)!==sjcl.bitArray.bitLength(b))return!1;var c=0,e;for(e=0;e<a.length;e++)c|=a[e]^b[e];return 0=== |
||||||
|
c},l:function(a,b,c,e){var d;d=0;for(void 0===e&&(e=[]);32<=b;b-=32)e.push(c),c=0;if(0===b)return e.concat(a);for(d=0;d<a.length;d++)e.push(c|a[d]>>>b),c=a[d]<<32-b;d=a.length?a[a.length-1]:0;a=sjcl.bitArray.getPartial(d);e.push(sjcl.bitArray.partial(b+a&31,32<b+a?c:e.pop(),1));return e},p:function(a,b){return[a[0]^b[0],a[1]^b[1],a[2]^b[2],a[3]^b[3]]}}; |
||||||
|
sjcl.codec.utf8String={fromBits:function(a){var b="",c=sjcl.bitArray.bitLength(a),e,d;for(e=0;e<c/8;e++)0===(e&3)&&(d=a[e/4]),b+=String.fromCharCode(d>>>24),d<<=8;return decodeURIComponent(escape(b))},toBits:function(a){a=unescape(encodeURIComponent(a));var b=[],c,e=0;for(c=0;c<a.length;c++)e=e<<8|a.charCodeAt(c),3===(c&3)&&(b.push(e),e=0);c&3&&b.push(sjcl.bitArray.partial(8*(c&3),e));return b}}; |
||||||
|
sjcl.codec.base64={j:"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",fromBits:function(a,b,c){var e="",d=0,h=sjcl.codec.base64.j,k=0,f=sjcl.bitArray.bitLength(a);c&&(h=h.substr(0,62)+"-_");for(c=0;6*e.length<f;)e+=h.charAt((k^a[c]>>>d)>>>26),6>d?(k=a[c]<<6-d,d+=26,c++):(k<<=6,d-=6);for(;e.length&3&&!b;)e+="=";return e},toBits:function(a,b){a=a.replace(/\s|=/g,"");var c=[],e,d=0,h=sjcl.codec.base64.j,k=0,f;b&&(h=h.substr(0,62)+"-_");for(e=0;e<a.length;e++){f=h.indexOf(a.charAt(e)); |
||||||
|
if(0>f)throw new sjcl.exception.invalid("this isn't base64!");26<d?(d-=26,c.push(k^f>>>d),k=f<<32-d):(d+=6,k^=f<<32-d)}d&56&&c.push(sjcl.bitArray.partial(d&56,k,1));return c}};sjcl.codec.base64url={fromBits:function(a){return sjcl.codec.base64.fromBits(a,1,1)},toBits:function(a){return sjcl.codec.base64.toBits(a,1)}};sjcl.hash.sha256=function(a){this.d[0]||this.h();a?(this.c=a.c.slice(0),this.b=a.b.slice(0),this.a=a.a):this.reset()};sjcl.hash.sha256.hash=function(a){return(new sjcl.hash.sha256).update(a).finalize()}; |
||||||
|
sjcl.hash.sha256.prototype={blockSize:512,reset:function(){this.c=this.f.slice(0);this.b=[];this.a=0;return this},update:function(a){"string"===typeof a&&(a=sjcl.codec.utf8String.toBits(a));var b,c=this.b=sjcl.bitArray.concat(this.b,a);b=this.a;a=this.a=b+sjcl.bitArray.bitLength(a);for(b=512+b&-512;b<=a;b+=512)this.e(c.splice(0,16));return this},finalize:function(){var a,b=this.b,c=this.c,b=sjcl.bitArray.concat(b,[sjcl.bitArray.partial(1,1)]);for(a=b.length+2;a&15;a++)b.push(0);b.push(Math.floor(this.a/ |
||||||
|
4294967296));for(b.push(this.a|0);b.length;)this.e(b.splice(0,16));this.reset();return c},f:[],d:[],h:function(){function a(a){return 0x100000000*(a-Math.floor(a))|0}var b=0,c=2,e;a:for(;64>b;c++){for(e=2;e*e<=c;e++)if(0===c%e)continue a;8>b&&(this.f[b]=a(Math.pow(c,0.5)));this.d[b]=a(Math.pow(c,1/3));b++}},e:function(a){var b,c,e=a.slice(0),d=this.c,h=this.d,k=d[0],f=d[1],g=d[2],u=d[3],m=d[4],v=d[5],w=d[6],x=d[7];for(a=0;64>a;a++)16>a?b=e[a]:(b=e[a+1&15],c=e[a+14&15],b=e[a&15]=(b>>>7^b>>>18^b>>>3^ |
||||||
|
b<<25^b<<14)+(c>>>17^c>>>19^c>>>10^c<<15^c<<13)+e[a&15]+e[a+9&15]|0),b=b+x+(m>>>6^m>>>11^m>>>25^m<<26^m<<21^m<<7)+(w^m&(v^w))+h[a],x=w,w=v,v=m,m=u+b|0,u=g,g=f,f=k,k=b+(f&g^u&(f^g))+(f>>>2^f>>>13^f>>>22^f<<30^f<<19^f<<10)|0;d[0]=d[0]+k|0;d[1]=d[1]+f|0;d[2]=d[2]+g|0;d[3]=d[3]+u|0;d[4]=d[4]+m|0;d[5]=d[5]+v|0;d[6]=d[6]+w|0;d[7]=d[7]+x|0}};sjcl.hash.sha512=function(a){this.d[0]||this.h();a?(this.c=a.c.slice(0),this.b=a.b.slice(0),this.a=a.a):this.reset()};sjcl.hash.sha512.hash=function(a){return(new sjcl.hash.sha512).update(a).finalize()}; |
||||||
|
sjcl.hash.sha512.prototype={blockSize:1024,reset:function(){this.c=this.f.slice(0);this.b=[];this.a=0;return this},update:function(a){"string"===typeof a&&(a=sjcl.codec.utf8String.toBits(a));var b,c=this.b=sjcl.bitArray.concat(this.b,a);b=this.a;a=this.a=b+sjcl.bitArray.bitLength(a);for(b=1024+b&-1024;b<=a;b+=1024)this.e(c.splice(0,32));return this},finalize:function(){var a,b=this.b,c=this.c,b=sjcl.bitArray.concat(b,[sjcl.bitArray.partial(1,1)]);for(a=b.length+4;a&31;a++)b.push(0);b.push(0);b.push(0); |
||||||
|
b.push(Math.floor(this.a/0x100000000));for(b.push(this.a|0);b.length;)this.e(b.splice(0,32));this.reset();return c},f:[],n:[12372232,13281083,9762859,1914609,15106769,4090911,4308331,8266105],d:[],o:[2666018,15689165,5061423,9034684,4764984,380953,1658779,7176472,197186,7368638,14987916,16757986,8096111,1480369,13046325,6891156,15813330,5187043,9229749,11312229,2818677,10937475,4324308,1135541,6741931,11809296,16458047,15666916,11046850,698149,229999,945776,13774844,2541862,12856045,9810911,11494366, |
||||||
|
7844520,15576806,8533307,15795044,4337665,16291729,5553712,15684120,6662416,7413802,12308920,13816008,4303699,9366425,10176680,13195875,4295371,6546291,11712675,15708924,1519456,15772530,6568428,6495784,8568297,13007125,7492395,2515356,12632583,14740254,7262584,1535930,13146278,16321966,1853211,294276,13051027,13221564,1051980,4080310,6651434,14088940,4675607],h:function(){function a(a){return 0x100000000*(a-Math.floor(a))|0}function b(a){return 0x10000000000*(a-Math.floor(a))&255}var c=0,e=2,d;a:for(;80> |
||||||
|
c;e++){for(d=2;d*d<=e;d++)if(0===e%d)continue a;8>c&&(this.f[2*c]=a(Math.pow(e,0.5)),this.f[2*c+1]=b(Math.pow(e,0.5))<<24|this.n[c]);this.d[2*c]=a(Math.pow(e,1/3));this.d[2*c+1]=b(Math.pow(e,1/3))<<24|this.o[c];c++}},e:function(a){var b,c,e=a.slice(0),d=this.c,h=this.d,k=d[0],f=d[1],g=d[2],u=d[3],m=d[4],v=d[5],w=d[6],x=d[7],R=d[8],H=d[9],S=d[10],I=d[11],T=d[12],J=d[13],U=d[14],K=d[15],q=k,n=f,A=g,y=u,B=m,z=v,N=w,C=x,r=R,p=H,L=S,D=I,M=T,E=J,O=U,F=K;for(a=0;80>a;a++){if(16>a)b=e[2*a],c=e[2*a+1];else{c= |
||||||
|
e[2*(a-15)];var l=e[2*(a-15)+1];b=(l<<31|c>>>1)^(l<<24|c>>>8)^c>>>7;var s=(c<<31|l>>>1)^(c<<24|l>>>8)^(c<<25|l>>>7);c=e[2*(a-2)];var t=e[2*(a-2)+1],l=(t<<13|c>>>19)^(c<<3|t>>>29)^c>>>6,t=(c<<13|t>>>19)^(t<<3|c>>>29)^(c<<26|t>>>6),P=e[2*(a-7)],Q=e[2*(a-16)],G=e[2*(a-16)+1];c=s+e[2*(a-7)+1];b=b+P+(c>>>0<s>>>0?1:0);c+=t;b+=l+(c>>>0<t>>>0?1:0);c+=G;b+=Q+(c>>>0<G>>>0?1:0)}e[2*a]=b|=0;e[2*a+1]=c|=0;var P=r&L^~r&M,V=p&D^~p&E,t=q&A^q&B^A&B,X=n&y^n&z^y&z,Q=(n<<4|q>>>28)^(q<<30|n>>>2)^(q<<25|n>>>7),G=(q<<4| |
||||||
|
n>>>28)^(n<<30|q>>>2)^(n<<25|q>>>7),Y=h[2*a],W=h[2*a+1],l=F+((r<<18|p>>>14)^(r<<14|p>>>18)^(p<<23|r>>>9)),s=O+((p<<18|r>>>14)^(p<<14|r>>>18)^(r<<23|p>>>9))+(l>>>0<F>>>0?1:0),l=l+V,s=s+(P+(l>>>0<V>>>0?1:0)),l=l+W,s=s+(Y+(l>>>0<W>>>0?1:0)),l=l+c,s=s+(b+(l>>>0<c>>>0?1:0));c=G+X;b=Q+t+(c>>>0<G>>>0?1:0);O=M;F=E;M=L;E=D;L=r;D=p;p=C+l|0;r=N+s+(p>>>0<C>>>0?1:0)|0;N=B;C=z;B=A;z=y;A=q;y=n;n=l+c|0;q=s+b+(n>>>0<l>>>0?1:0)|0}f=d[1]=f+n|0;d[0]=k+q+(f>>>0<n>>>0?1:0)|0;u=d[3]=u+y|0;d[2]=g+A+(u>>>0<y>>>0?1:0)|0;v= |
||||||
|
d[5]=v+z|0;d[4]=m+B+(v>>>0<z>>>0?1:0)|0;x=d[7]=x+C|0;d[6]=w+N+(x>>>0<C>>>0?1:0)|0;H=d[9]=H+p|0;d[8]=R+r+(H>>>0<p>>>0?1:0)|0;I=d[11]=I+D|0;d[10]=S+L+(I>>>0<D>>>0?1:0)|0;J=d[13]=J+E|0;d[12]=T+M+(J>>>0<E>>>0?1:0)|0;K=d[15]=K+F|0;d[14]=U+O+(K>>>0<F>>>0?1:0)|0}};sjcl.hash.sha1=function(a){a?(this.c=a.c.slice(0),this.b=a.b.slice(0),this.a=a.a):this.reset()};sjcl.hash.sha1.hash=function(a){return(new sjcl.hash.sha1).update(a).finalize()}; |
||||||
|
sjcl.hash.sha1.prototype={blockSize:512,reset:function(){this.c=this.f.slice(0);this.b=[];this.a=0;return this},update:function(a){"string"===typeof a&&(a=sjcl.codec.utf8String.toBits(a));var b,c=this.b=sjcl.bitArray.concat(this.b,a);b=this.a;a=this.a=b+sjcl.bitArray.bitLength(a);for(b=this.blockSize+b&-this.blockSize;b<=a;b+=this.blockSize)this.e(c.splice(0,16));return this},finalize:function(){var a,b=this.b,c=this.c,b=sjcl.bitArray.concat(b,[sjcl.bitArray.partial(1,1)]);for(a=b.length+2;a&15;a++)b.push(0); |
||||||
|
b.push(Math.floor(this.a/0x100000000));for(b.push(this.a|0);b.length;)this.e(b.splice(0,16));this.reset();return c},f:[1732584193,4023233417,2562383102,271733878,3285377520],d:[1518500249,1859775393,2400959708,3395469782],e:function(a){var b,c,e,d,h,k,f=a.slice(0),g=this.c;c=g[0];e=g[1];d=g[2];h=g[3];k=g[4];for(a=0;79>=a;a++)16<=a&&(f[a]=(f[a-3]^f[a-8]^f[a-14]^f[a-16])<<1|(f[a-3]^f[a-8]^f[a-14]^f[a-16])>>>31),b=19>=a?e&d|~e&h:39>=a?e^d^h:59>=a?e&d|e&h|d&h:79>=a?e^d^h:void 0,b=(c<<5|c>>>27)+b+k+f[a]+ |
||||||
|
this.d[Math.floor(a/20)]|0,k=h,h=d,d=e<<30|e>>>2,e=c,c=b;g[0]=g[0]+c|0;g[1]=g[1]+e|0;g[2]=g[2]+d|0;g[3]=g[3]+h|0;g[4]=g[4]+k|0}};sjcl.misc.hmac=function(a,b){this.k=b=b||sjcl.hash.sha256;var c=[[],[]],e,d=b.prototype.blockSize/32;this.g=[new b,new b];a.length>d&&(a=b.hash(a));for(e=0;e<d;e++)c[0][e]=a[e]^909522486,c[1][e]=a[e]^1549556828;this.g[0].update(c[0]);this.g[1].update(c[1]);this.i=new b(this.g[0])}; |
||||||
|
sjcl.misc.hmac.prototype.encrypt=sjcl.misc.hmac.prototype.mac=function(a){if(this.m)throw new sjcl.exception.invalid("encrypt on already updated hmac called!");this.update(a);return this.digest(a)};sjcl.misc.hmac.prototype.reset=function(){this.i=new this.k(this.g[0]);this.m=!1};sjcl.misc.hmac.prototype.update=function(a){this.m=!0;this.i.update(a)};sjcl.misc.hmac.prototype.digest=function(){var a=this.i.finalize(),a=(new this.k(this.g[1])).update(a).finalize();this.reset();return a}; |
Loading…
Reference in new issue