-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
a332823
commit 8b5c121
Showing
3 changed files
with
367 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,134 @@ | ||
// Copyright (c) 2012 Jake Willoughby | ||
// | ||
// This file is part of DOH. | ||
// | ||
// DOH is free software: you can redistribute it and/or modify | ||
// it under the terms of the GNU General Public License as published by | ||
// the Free Software Foundation, either version 3 of the License, or | ||
// any later version. | ||
// | ||
// DOH 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 General Public License for more details. | ||
// | ||
// You should have received a copy of the GNU General Public License | ||
// along with DOH. See gpl3.txt. If not, see <http://www.gnu.org/licenses/>. | ||
|
||
// Requires 2.5.3-crypto-sha1-hmac-pbkdf2.js to be included first. | ||
// Requires js-yaml-0.3.7.min.js to be included first. | ||
|
||
var DOH = new function() { | ||
var lower = "abcdefghijklmnopqrstuvwxyz"; | ||
var upper = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; | ||
var num = "0123456789"; | ||
var special = " !\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~"; | ||
|
||
var char_set = function(use,exclude) { | ||
var use_vals = use.split(',').sort(); | ||
var even_split = Math.floor(64/use_vals.length); | ||
var left = 64; | ||
var pos = 0; | ||
var final_set = ""; | ||
var size = 0; | ||
|
||
for (var i=0; i<use_vals.length; i++) { | ||
switch (use_vals[i]) { | ||
case "c": | ||
size = even_split; | ||
if (size > upper.length) { | ||
size = upper.length; | ||
} | ||
final_set += upper.substring(0,size); | ||
left -= size; | ||
break; | ||
case "l": | ||
size = even_split; | ||
if (size > lower.length) { | ||
size = lower.length; | ||
} | ||
final_set += lower.substring(0,size); | ||
left -= size; | ||
break; | ||
case "n": | ||
size = even_split; | ||
if (size > num.length) { | ||
size = num.length; | ||
} | ||
final_set += num.substring(0,size); | ||
left -= size; | ||
break; | ||
case "x": | ||
size = left; | ||
if (size > special.length) { | ||
size = special.length; | ||
} | ||
final_set += special.substring(0,size); | ||
left -= size; | ||
break; | ||
default: | ||
alert("Bad use string " + use); | ||
} | ||
} | ||
|
||
var exclude_re = new RegExp ("[" + RegExp.escape(exclude) + "]", 'g'); | ||
final_set = final_set.replace(exclude_re,''); | ||
while (final_set.length < 64) { | ||
final_set += final_set; | ||
} | ||
return final_set; | ||
} | ||
|
||
this.trans_chars = function(str,from,to) { | ||
var translate_re = new RegExp ("[" + from + "]", 'g'); | ||
return (str.replace(translate_re, function(match) { | ||
return to.substr(from.indexOf(match),1); }) | ||
); | ||
} | ||
|
||
// Thanks to: http://simonwillison.net/2006/jan/20/escape/ | ||
RegExp.escape = function(text) { | ||
return text.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&"); | ||
} | ||
|
||
var get_domain_reqs = function(domain) { | ||
var rsp = {}; | ||
var ds = DOH_UI.domainSpecs; | ||
if (!(domain in ds)) { | ||
domain = "defaults"; | ||
} | ||
var d = ds[domain]; | ||
rsp.use = d.use; | ||
rsp.exclude = d.exclude; | ||
rsp.length = d.max_length; | ||
return rsp; | ||
} | ||
|
||
this.gen_password = function(opts) { //hashedMaster,salt,seq,domain) { | ||
var hashedMaster = opts['hashedMaster']; | ||
var salt = opts['salt']; | ||
var seq = opts['seq']; | ||
var domain = opts['domain']; | ||
var hashFunction = opts['hashFunction']; | ||
if (hashFunction == "sha1") { | ||
hashFunction = Crypto.SHA1; | ||
} | ||
else if (hashFunction == "sha256") { | ||
hashFunction = Crypto.SHA256; | ||
} | ||
else { | ||
hashFunction = Crypto.SHA256; | ||
} | ||
var reqs = get_domain_reqs(domain); | ||
|
||
// Convert character length into byte lengths | ||
var len = Math.ceil(reqs.length*6/8); | ||
var foo = Crypto.PBKDF2(hashedMaster,seq + domain + salt,len, {iterations: 2000, | ||
asBytes: true, | ||
hasher: hashFunction}); | ||
foo = Crypto.util.bytesToBase64(foo); | ||
var set = char_set(reqs.use, reqs.exclude); | ||
var result = DOH.trans_chars(foo,upper+lower+num+"+/", set); | ||
return result; | ||
} | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,131 @@ | ||
// Copyright (c) 2012 Jake Willoughby | ||
// | ||
// This file is part of DOH. | ||
// | ||
// DOH is free software: you can redistribute it and/or modify | ||
// it under the terms of the GNU General Public License as published by | ||
// the Free Software Foundation, either version 3 of the License, or | ||
// any later version. | ||
// | ||
// DOH 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 General Public License for more details. | ||
// | ||
// You should have received a copy of the GNU General Public License | ||
// along with DOH. See gpl3.txt. If not, see <http://www.gnu.org/licenses/>. | ||
|
||
|
||
// Requires jquery. | ||
|
||
var DOH_UI = new function() { | ||
var master = ""; | ||
var masterHash = ""; | ||
var salt = ""; | ||
var host = ""; | ||
var seq = ""; | ||
this.domainSpecs = ""; | ||
var dohHashFunction = "sha256"; | ||
var selectedHasher = DOH.gen_password; | ||
var selectedHasherString = "DOHsha256"; | ||
var selectedHasherIsSecure = true; | ||
|
||
this.init = function(domain_info) { | ||
if (domain_info) { | ||
this.domainSpecs = domain_info; | ||
} | ||
else { | ||
$.getJSON('domain_specs.json', function (data) { | ||
DOH_UI.domainSpecs = data; | ||
}); | ||
} | ||
}; | ||
|
||
var hostSource = function() { | ||
}; | ||
|
||
var getHost = function() { | ||
return host; | ||
}; | ||
|
||
this.getSalt = function() { | ||
return salt; | ||
}; | ||
|
||
this.isSetMaster = function() { | ||
if (masterHash != "") { | ||
return true; | ||
} | ||
return false; | ||
}; | ||
|
||
this.getPassword = function() { | ||
var host = getHost(); | ||
var opts = {'domain': host, | ||
'salt': DOH_UI.getSalt(), | ||
'hashedMaster': masterHash, | ||
'seq': DOH_UI.getSequence(), | ||
'hashFunction': dohHashFunction}; | ||
if (!selectedHasherIsSecure) { | ||
opts['password'] = master; | ||
} | ||
if (host) { | ||
return selectedHasher(opts); | ||
} | ||
return "Invalid domain string."; | ||
}; | ||
this.setMaster = function(password) { | ||
if (password == "") { | ||
return; | ||
} | ||
if (!selectedHasherIsSecure) { | ||
master = password; | ||
} | ||
masterHash = Crypto.util.bytesToBase64(Crypto.SHA256(DOH_UI.getSalt() + password, {asBytes: true})); | ||
}; | ||
|
||
this.setSequence = function(sequenceString) { | ||
seq = sequenceString; | ||
} | ||
this.getSequence = function() { | ||
return seq; | ||
} | ||
|
||
this.setHasher = function(hasherString) { | ||
var h = hasherString; | ||
selectedHasherString = h; | ||
selectedHasherIsSecure = true; | ||
if (h == "DOHsha1") { | ||
selectedHasher = DOH.gen_password; | ||
dohHashFunction = "sha1"; | ||
} | ||
else if (h == "DOHsha256") { | ||
selectedHasher = DOH.gen_password; | ||
dohHashFunction = "sha256"; | ||
} | ||
else if (h == "INSECUREmd5hash") { | ||
selectedHasher = INSECURE.md5hash; | ||
selectedHasherIsSecure = false; | ||
} | ||
else if (h == "INSECUREangel") { | ||
selectedHasher = INSECURE.angel; | ||
selectedHasherIsSecure = false; | ||
} | ||
}; | ||
this.getHasher = function() { | ||
return selectedHasherString; | ||
}; | ||
|
||
this.setSalt = function(s) { | ||
salt = s; | ||
}; | ||
this.setHost = function(h) { | ||
var match = h.match(/([-A-Za-z0-9]+\.)*([-A-Za-z0-9]*\.[-A-Za-z0-9]+)/); | ||
if (match && 2 in match) { | ||
host = match[2]; | ||
} | ||
else { | ||
host = null; | ||
} | ||
}; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
// Copyright (c) 2012 Jake Willoughby | ||
// | ||
// This file is part of DOH. | ||
// | ||
// DOH is free software: you can redistribute it and/or modify | ||
// it under the terms of the GNU General Public License as published by | ||
// the Free Software Foundation, either version 3 of the License, or | ||
// any later version. | ||
// | ||
// DOH 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 General Public License for more details. | ||
// | ||
// You should have received a copy of the GNU General Public License | ||
// along with DOH. See gpl3.txt. If not, see <http://www.gnu.org/licenses/>. | ||
|
||
var INSECURE = new function() { | ||
this.angel = function(opts) { | ||
//Algorithm used at http://angel.net/~nic/passwd.current.html | ||
return Crypto.util.bytesToBase64(Crypto.SHA1(opts['password'] + ":" + opts['domain'], {asBytes: true})).substring(0,8) + "1a"; | ||
}; | ||
|
||
|
||
|
||
|
||
this.md5hash = function(opts) { | ||
//Original algorithm: (domain used as salt) | ||
//#!/bin/bash | ||
//salt=`echo -n $1 | base64 | md5sum | cut -c 1-8` | ||
//salthash=`openssl passwd -1 -salt $salt` | ||
//echo ${salthash:12} | ||
// Openssl implementation from: | ||
//http://www.freebsd.org/cgi/cvsweb.cgi/~checkout~/src/lib/libcrypt/crypt.c?rev=1.2 | ||
var salt = Crypto.MD5(btoa(opts['domain'] + opts['seq']) + '\n').substring(0,8); | ||
var tmp = Crypto.MD5(opts['password'] + salt + opts['password'], {asBytes:true}); | ||
var str = opts['password'] + "$1$" + salt; | ||
str = Crypto.charenc.Binary.stringToBytes(str); | ||
|
||
var cnt; | ||
for (cnt = opts['password'].length;cnt > 16; cnt = cnt - 16) { | ||
str = str.concat(tmp); | ||
} | ||
str = str.concat(tmp.slice(0,cnt)); | ||
|
||
|
||
for(cnt = opts['password'].length;cnt > 0; cnt = cnt >> 1) { | ||
if ((cnt & 1) != 0) { | ||
str = str.concat([0]); | ||
} | ||
else { | ||
str = str.concat(Crypto.charenc.Binary.stringToBytes(opts['password'].substring(0,1))); | ||
} | ||
} | ||
var foo = Crypto.charenc.Binary.bytesToString(str); | ||
var last = Crypto.MD5(str, {asBytes:true}); | ||
|
||
for (cnt=0;cnt<1000;cnt++) { | ||
var next = []; | ||
if ((cnt&1) != 0) { | ||
next = next.concat(Crypto.charenc.Binary.stringToBytes(opts['password'])); | ||
} | ||
else { | ||
next = next.concat(last); | ||
} | ||
if (cnt % 3 != 0) { | ||
next = next.concat(Crypto.charenc.Binary.stringToBytes(salt)); | ||
} | ||
if (cnt % 7 != 0) { | ||
next = next.concat(Crypto.charenc.Binary.stringToBytes(opts['password'])); | ||
} | ||
if ((cnt&1) != 0) { | ||
next = next.concat(last); | ||
} | ||
else { | ||
next = next.concat(Crypto.charenc.Binary.stringToBytes(opts['password'])); | ||
} | ||
last = Crypto.MD5(next, {asBytes:true}); | ||
} | ||
// For some reason they reorder the bytes when converting to base64 | ||
var reorder = [ | ||
last[0], last[6], last[12], | ||
last[1], last[7], last[13], | ||
last[2], last[8], last[14], | ||
last[3], last[9], last[15], | ||
last[4], last[10], last[5], | ||
0,0,last[11] ]; | ||
|
||
// They use a different base64 | ||
var tmp2 = Crypto.util.bytesToBase64(reorder); | ||
var tmp3 = DOH.trans_chars(Crypto.util.bytesToBase64(reorder),"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/","./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"); | ||
var tmp4 = ""; | ||
for (cnt=0;cnt<tmp3.length;cnt = cnt + 4) { | ||
tmp4 += tmp3.substring(cnt+3,cnt+4); | ||
tmp4 += tmp3.substring(cnt+2,cnt+3); | ||
tmp4 += tmp3.substring(cnt+1,cnt+2); | ||
tmp4 += tmp3.substring(cnt,cnt+1); | ||
} | ||
return tmp4.substring(0,tmp4.length-2); | ||
// return salt; | ||
}; | ||
}; |