otr.js 69 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640
  1. /*!
  2. otr.js v0.2.16 - 2015-12-03
  3. (c) 2015 - Arlo Breault <arlolra@gmail.com>
  4. Freely distributed under the MPL-2.0 license.
  5. This file is concatenated for the browser.
  6. Please see: https://github.com/arlolra/otr
  7. */
  8. ;(function (root, factory) {
  9. if (typeof define === 'function' && define.amd) {
  10. define([
  11. "bigint"
  12. , "crypto"
  13. , "eventemitter"
  14. ], function (BigInt, CryptoJS, EventEmitter) {
  15. var root = {
  16. BigInt: BigInt
  17. , CryptoJS: CryptoJS
  18. , EventEmitter: EventEmitter
  19. , OTR: {}
  20. , DSA: {}
  21. }
  22. return factory.call(root)
  23. })
  24. } else {
  25. root.OTR = {}
  26. root.DSA = {}
  27. factory.call(root)
  28. }
  29. }(this, function () {
  30. ;(function () {
  31. "use strict";
  32. var root = this
  33. var CONST = {
  34. // diffie-heilman
  35. N : 'FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D670C354E4ABC9804F1746C08CA237327FFFFFFFFFFFFFFFF'
  36. , G : '2'
  37. // otr message states
  38. , MSGSTATE_PLAINTEXT : 0
  39. , MSGSTATE_ENCRYPTED : 1
  40. , MSGSTATE_FINISHED : 2
  41. // otr auth states
  42. , AUTHSTATE_NONE : 0
  43. , AUTHSTATE_AWAITING_DHKEY : 1
  44. , AUTHSTATE_AWAITING_REVEALSIG : 2
  45. , AUTHSTATE_AWAITING_SIG : 3
  46. // whitespace tags
  47. , WHITESPACE_TAG : '\x20\x09\x20\x20\x09\x09\x09\x09\x20\x09\x20\x09\x20\x09\x20\x20'
  48. , WHITESPACE_TAG_V2 : '\x20\x20\x09\x09\x20\x20\x09\x20'
  49. , WHITESPACE_TAG_V3 : '\x20\x20\x09\x09\x20\x20\x09\x09'
  50. // otr tags
  51. , OTR_TAG : '?OTR'
  52. , OTR_VERSION_1 : '\x00\x01'
  53. , OTR_VERSION_2 : '\x00\x02'
  54. , OTR_VERSION_3 : '\x00\x03'
  55. // smp machine states
  56. , SMPSTATE_EXPECT0 : 0
  57. , SMPSTATE_EXPECT1 : 1
  58. , SMPSTATE_EXPECT2 : 2
  59. , SMPSTATE_EXPECT3 : 3
  60. , SMPSTATE_EXPECT4 : 4
  61. // unstandard status codes
  62. , STATUS_SEND_QUERY : 0
  63. , STATUS_AKE_INIT : 1
  64. , STATUS_AKE_SUCCESS : 2
  65. , STATUS_END_OTR : 3
  66. }
  67. if (typeof module !== 'undefined' && module.exports) {
  68. module.exports = CONST
  69. } else {
  70. root.OTR.CONST = CONST
  71. }
  72. }).call(this)
  73. ;(function () {
  74. "use strict";
  75. var root = this
  76. var HLP = {}, CryptoJS, BigInt
  77. if (typeof module !== 'undefined' && module.exports) {
  78. module.exports = HLP = {}
  79. CryptoJS = require('../vendor/crypto.js')
  80. BigInt = require('../vendor/bigint.js')
  81. } else {
  82. if (root.OTR) root.OTR.HLP = HLP
  83. if (root.DSA) root.DSA.HLP = HLP
  84. CryptoJS = root.CryptoJS
  85. BigInt = root.BigInt
  86. }
  87. // data types (byte lengths)
  88. var DTS = {
  89. BYTE : 1
  90. , SHORT : 2
  91. , INT : 4
  92. , CTR : 8
  93. , MAC : 20
  94. , SIG : 40
  95. }
  96. // otr message wrapper begin and end
  97. var WRAPPER_BEGIN = "?OTR"
  98. , WRAPPER_END = "."
  99. var TWO = BigInt.str2bigInt('2', 10)
  100. HLP.debug = function (msg) {
  101. // used as HLP.debug.call(ctx, msg)
  102. if ( this.debug &&
  103. typeof this.debug !== 'function' &&
  104. typeof console !== 'undefined'
  105. ) console.log(msg)
  106. }
  107. HLP.extend = function (child, parent) {
  108. for (var key in parent) {
  109. if (Object.hasOwnProperty.call(parent, key))
  110. child[key] = parent[key]
  111. }
  112. function Ctor() { this.constructor = child }
  113. Ctor.prototype = parent.prototype
  114. child.prototype = new Ctor()
  115. child.__super__ = parent.prototype
  116. }
  117. // assumes 32-bit
  118. function intCompare(x, y) {
  119. var z = ~(x ^ y)
  120. z &= z >> 16
  121. z &= z >> 8
  122. z &= z >> 4
  123. z &= z >> 2
  124. z &= z >> 1
  125. return z & 1
  126. }
  127. // constant-time string comparison
  128. HLP.compare = function (str1, str2) {
  129. if (str1.length !== str2.length)
  130. return false
  131. var i = 0, result = 0
  132. for (; i < str1.length; i++)
  133. result |= str1[i].charCodeAt(0) ^ str2[i].charCodeAt(0)
  134. return intCompare(result, 0)
  135. }
  136. HLP.randomExponent = function () {
  137. return BigInt.randBigInt(1536)
  138. }
  139. HLP.smpHash = function (version, fmpi, smpi) {
  140. var sha256 = CryptoJS.algo.SHA256.create()
  141. sha256.update(CryptoJS.enc.Latin1.parse(HLP.packBytes(version, DTS.BYTE)))
  142. sha256.update(CryptoJS.enc.Latin1.parse(HLP.packMPI(fmpi)))
  143. if (smpi) sha256.update(CryptoJS.enc.Latin1.parse(HLP.packMPI(smpi)))
  144. var hash = sha256.finalize()
  145. return HLP.bits2bigInt(hash.toString(CryptoJS.enc.Latin1))
  146. }
  147. HLP.makeMac = function (aesctr, m) {
  148. var pass = CryptoJS.enc.Latin1.parse(m)
  149. var mac = CryptoJS.HmacSHA256(CryptoJS.enc.Latin1.parse(aesctr), pass)
  150. return HLP.mask(mac.toString(CryptoJS.enc.Latin1), 0, 160)
  151. }
  152. HLP.make1Mac = function (aesctr, m) {
  153. var pass = CryptoJS.enc.Latin1.parse(m)
  154. var mac = CryptoJS.HmacSHA1(CryptoJS.enc.Latin1.parse(aesctr), pass)
  155. return mac.toString(CryptoJS.enc.Latin1)
  156. }
  157. HLP.encryptAes = function (msg, c, iv) {
  158. var opts = {
  159. mode: CryptoJS.mode.CTR
  160. , iv: CryptoJS.enc.Latin1.parse(iv)
  161. , padding: CryptoJS.pad.NoPadding
  162. }
  163. var aesctr = CryptoJS.AES.encrypt(
  164. msg
  165. , CryptoJS.enc.Latin1.parse(c)
  166. , opts
  167. )
  168. var aesctr_decoded = CryptoJS.enc.Base64.parse(aesctr.toString())
  169. return CryptoJS.enc.Latin1.stringify(aesctr_decoded)
  170. }
  171. HLP.decryptAes = function (msg, c, iv) {
  172. msg = CryptoJS.enc.Latin1.parse(msg)
  173. var opts = {
  174. mode: CryptoJS.mode.CTR
  175. , iv: CryptoJS.enc.Latin1.parse(iv)
  176. , padding: CryptoJS.pad.NoPadding
  177. }
  178. return CryptoJS.AES.decrypt(
  179. CryptoJS.enc.Base64.stringify(msg)
  180. , CryptoJS.enc.Latin1.parse(c)
  181. , opts
  182. )
  183. }
  184. HLP.multPowMod = function (a, b, c, d, e) {
  185. return BigInt.multMod(BigInt.powMod(a, b, e), BigInt.powMod(c, d, e), e)
  186. }
  187. HLP.ZKP = function (v, c, d, e) {
  188. return BigInt.equals(c, HLP.smpHash(v, d, e))
  189. }
  190. // greater than, or equal
  191. HLP.GTOE = function (a, b) {
  192. return (BigInt.equals(a, b) || BigInt.greater(a, b))
  193. }
  194. HLP.between = function (x, a, b) {
  195. return (BigInt.greater(x, a) && BigInt.greater(b, x))
  196. }
  197. HLP.checkGroup = function (g, N_MINUS_2) {
  198. return HLP.GTOE(g, TWO) && HLP.GTOE(N_MINUS_2, g)
  199. }
  200. HLP.h1 = function (b, secbytes) {
  201. var sha1 = CryptoJS.algo.SHA1.create()
  202. sha1.update(CryptoJS.enc.Latin1.parse(b))
  203. sha1.update(CryptoJS.enc.Latin1.parse(secbytes))
  204. return (sha1.finalize()).toString(CryptoJS.enc.Latin1)
  205. }
  206. HLP.h2 = function (b, secbytes) {
  207. var sha256 = CryptoJS.algo.SHA256.create()
  208. sha256.update(CryptoJS.enc.Latin1.parse(b))
  209. sha256.update(CryptoJS.enc.Latin1.parse(secbytes))
  210. return (sha256.finalize()).toString(CryptoJS.enc.Latin1)
  211. }
  212. HLP.mask = function (bytes, start, n) {
  213. return bytes.substr(start / 8, n / 8)
  214. }
  215. var _toString = String.fromCharCode;
  216. HLP.packBytes = function (val, bytes) {
  217. val = val.toString(16)
  218. var nex, res = '' // big-endian, unsigned long
  219. for (; bytes > 0; bytes--) {
  220. nex = val.length ? val.substr(-2, 2) : '0'
  221. val = val.substr(0, val.length - 2)
  222. res = _toString(parseInt(nex, 16)) + res
  223. }
  224. return res
  225. }
  226. HLP.packINT = function (d) {
  227. return HLP.packBytes(d, DTS.INT)
  228. }
  229. HLP.packCtr = function (d) {
  230. return HLP.padCtr(HLP.packBytes(d, DTS.CTR))
  231. }
  232. HLP.padCtr = function (ctr) {
  233. return ctr + '\x00\x00\x00\x00\x00\x00\x00\x00'
  234. }
  235. HLP.unpackCtr = function (d) {
  236. d = HLP.toByteArray(d.substring(0, 8))
  237. return HLP.unpack(d)
  238. }
  239. HLP.unpack = function (arr) {
  240. var val = 0, i = 0, len = arr.length
  241. for (; i < len; i++) {
  242. val = (val * 256) + arr[i]
  243. }
  244. return val
  245. }
  246. HLP.packData = function (d) {
  247. return HLP.packINT(d.length) + d
  248. }
  249. HLP.bits2bigInt = function (bits) {
  250. bits = HLP.toByteArray(bits)
  251. return BigInt.ba2bigInt(bits)
  252. }
  253. HLP.packMPI = function (mpi) {
  254. return HLP.packData(BigInt.bigInt2bits(BigInt.trim(mpi, 0)))
  255. }
  256. HLP.packSHORT = function (short) {
  257. return HLP.packBytes(short, DTS.SHORT)
  258. }
  259. HLP.unpackSHORT = function (short) {
  260. short = HLP.toByteArray(short)
  261. return HLP.unpack(short)
  262. }
  263. HLP.packTLV = function (type, value) {
  264. return HLP.packSHORT(type) + HLP.packSHORT(value.length) + value
  265. }
  266. HLP.readLen = function (msg) {
  267. msg = HLP.toByteArray(msg.substring(0, 4))
  268. return HLP.unpack(msg)
  269. }
  270. HLP.readData = function (data) {
  271. var n = HLP.unpack(data.splice(0, 4))
  272. return [n, data]
  273. }
  274. HLP.readMPI = function (data) {
  275. data = HLP.toByteArray(data)
  276. data = HLP.readData(data)
  277. return BigInt.ba2bigInt(data[1])
  278. }
  279. HLP.packMPIs = function (arr) {
  280. return arr.reduce(function (prv, cur) {
  281. return prv + HLP.packMPI(cur)
  282. }, '')
  283. }
  284. HLP.unpackMPIs = function (num, mpis) {
  285. var i = 0, arr = []
  286. for (; i < num; i++) arr.push('MPI')
  287. return (HLP.splitype(arr, mpis)).map(function (m) {
  288. return HLP.readMPI(m)
  289. })
  290. }
  291. HLP.wrapMsg = function (msg, fs, v3, our_it, their_it) {
  292. msg = CryptoJS.enc.Base64.stringify(CryptoJS.enc.Latin1.parse(msg))
  293. msg = WRAPPER_BEGIN + ":" + msg + WRAPPER_END
  294. var its
  295. if (v3) {
  296. its = '|'
  297. its += (HLP.readLen(our_it)).toString(16)
  298. its += '|'
  299. its += (HLP.readLen(their_it)).toString(16)
  300. }
  301. if (!fs) return [null, msg]
  302. var n = Math.ceil(msg.length / fs)
  303. if (n > 65535) return ['Too many fragments']
  304. if (n == 1) return [null, msg]
  305. var k, bi, ei, frag, mf, mfs = []
  306. for (k = 1; k <= n; k++) {
  307. bi = (k - 1) * fs
  308. ei = k * fs
  309. frag = msg.slice(bi, ei)
  310. mf = WRAPPER_BEGIN
  311. if (v3) mf += its
  312. mf += ',' + k + ','
  313. mf += n + ','
  314. mf += frag + ','
  315. mfs.push(mf)
  316. }
  317. return [null, mfs]
  318. }
  319. HLP.splitype = function splitype(arr, msg) {
  320. var data = []
  321. arr.forEach(function (a) {
  322. var str
  323. switch (a) {
  324. case 'PUBKEY':
  325. str = splitype(['SHORT', 'MPI', 'MPI', 'MPI', 'MPI'], msg).join('')
  326. break
  327. case 'DATA': // falls through
  328. case 'MPI':
  329. str = msg.substring(0, HLP.readLen(msg) + 4)
  330. break
  331. default:
  332. str = msg.substring(0, DTS[a])
  333. }
  334. data.push(str)
  335. msg = msg.substring(str.length)
  336. })
  337. return data
  338. }
  339. // https://github.com/msgpack/msgpack-javascript/blob/master/msgpack.js
  340. var _bin2num = (function () {
  341. var i = 0, _bin2num = {}
  342. for (; i < 0x100; ++i) {
  343. _bin2num[String.fromCharCode(i)] = i // "\00" -> 0x00
  344. }
  345. for (i = 0x80; i < 0x100; ++i) { // [Webkit][Gecko]
  346. _bin2num[String.fromCharCode(0xf700 + i)] = i // "\f780" -> 0x80
  347. }
  348. return _bin2num
  349. }())
  350. HLP.toByteArray = function (data) {
  351. var rv = []
  352. , ary = data.split("")
  353. , i = -1
  354. , iz = ary.length
  355. , remain = iz % 8
  356. while (remain--) {
  357. ++i
  358. rv[i] = _bin2num[ary[i]]
  359. }
  360. remain = iz >> 3
  361. while (remain--) {
  362. rv.push(_bin2num[ary[++i]], _bin2num[ary[++i]],
  363. _bin2num[ary[++i]], _bin2num[ary[++i]],
  364. _bin2num[ary[++i]], _bin2num[ary[++i]],
  365. _bin2num[ary[++i]], _bin2num[ary[++i]])
  366. }
  367. return rv
  368. }
  369. }).call(this)
  370. ;(function () {
  371. "use strict";
  372. var root = this
  373. var CryptoJS, BigInt, Worker, WWPath, HLP
  374. if (typeof module !== 'undefined' && module.exports) {
  375. module.exports = DSA
  376. CryptoJS = require('../vendor/crypto.js')
  377. BigInt = require('../vendor/bigint.js')
  378. WWPath = require('path').join(__dirname, '/dsa-webworker.js')
  379. HLP = require('./helpers.js')
  380. } else {
  381. // copy over and expose internals
  382. Object.keys(root.DSA).forEach(function (k) {
  383. DSA[k] = root.DSA[k]
  384. })
  385. root.DSA = DSA
  386. CryptoJS = root.CryptoJS
  387. BigInt = root.BigInt
  388. Worker = root.Worker
  389. WWPath = 'dsa-webworker.js'
  390. HLP = DSA.HLP
  391. }
  392. var ZERO = BigInt.str2bigInt('0', 10)
  393. , ONE = BigInt.str2bigInt('1', 10)
  394. , TWO = BigInt.str2bigInt('2', 10)
  395. , KEY_TYPE = '\x00\x00'
  396. var DEBUG = false
  397. function timer() {
  398. var start = (new Date()).getTime()
  399. return function (s) {
  400. if (!DEBUG || typeof console === 'undefined') return
  401. var t = (new Date()).getTime()
  402. console.log(s + ': ' + (t - start))
  403. start = t
  404. }
  405. }
  406. function makeRandom(min, max) {
  407. var c = BigInt.randBigInt(BigInt.bitSize(max))
  408. if (!HLP.between(c, min, max)) return makeRandom(min, max)
  409. return c
  410. }
  411. // altered BigInt.randProbPrime()
  412. // n rounds of Miller Rabin (after trial division with small primes)
  413. var rpprb = []
  414. function isProbPrime(k, n) {
  415. var i, B = 30000, l = BigInt.bitSize(k)
  416. var primes = BigInt.primes
  417. if (primes.length === 0)
  418. primes = BigInt.findPrimes(B)
  419. if (rpprb.length != k.length)
  420. rpprb = BigInt.dup(k)
  421. // check ans for divisibility by small primes up to B
  422. for (i = 0; (i < primes.length) && (primes[i] <= B); i++)
  423. if (BigInt.modInt(k, primes[i]) === 0 && !BigInt.equalsInt(k, primes[i]))
  424. return 0
  425. // do n rounds of Miller Rabin, with random bases less than k
  426. for (i = 0; i < n; i++) {
  427. BigInt.randBigInt_(rpprb, l, 0)
  428. while(!BigInt.greater(k, rpprb)) // pick a random rpprb that's < k
  429. BigInt.randBigInt_(rpprb, l, 0)
  430. if (!BigInt.millerRabin(k, rpprb))
  431. return 0
  432. }
  433. return 1
  434. }
  435. var bit_lengths = {
  436. '1024': { N: 160, repeat: 40 } // 40x should give 2^-80 confidence
  437. , '2048': { N: 224, repeat: 56 }
  438. }
  439. var primes = {}
  440. // follows go lang http://golang.org/src/pkg/crypto/dsa/dsa.go
  441. // fips version was removed in 0c99af0df3e7
  442. function generatePrimes(bit_length) {
  443. var t = timer() // for debugging
  444. // number of MR tests to perform
  445. var repeat = bit_lengths[bit_length].repeat
  446. var N = bit_lengths[bit_length].N
  447. var LM1 = BigInt.twoToThe(bit_length - 1)
  448. var bl4 = 4 * bit_length
  449. var brk = false
  450. var q, p, rem, counter
  451. for (;;) {
  452. q = BigInt.randBigInt(N, 1)
  453. q[0] |= 1
  454. if (!isProbPrime(q, repeat)) continue
  455. t('q')
  456. for (counter = 0; counter < bl4; counter++) {
  457. p = BigInt.randBigInt(bit_length, 1)
  458. p[0] |= 1
  459. rem = BigInt.mod(p, q)
  460. rem = BigInt.sub(rem, ONE)
  461. p = BigInt.sub(p, rem)
  462. if (BigInt.greater(LM1, p)) continue
  463. if (!isProbPrime(p, repeat)) continue
  464. t('p')
  465. primes[bit_length] = { p: p, q: q }
  466. brk = true
  467. break
  468. }
  469. if (brk) break
  470. }
  471. var h = BigInt.dup(TWO)
  472. var pm1 = BigInt.sub(p, ONE)
  473. var e = BigInt.multMod(pm1, BigInt.inverseMod(q, p), p)
  474. var g
  475. for (;;) {
  476. g = BigInt.powMod(h, e, p)
  477. if (BigInt.equals(g, ONE)) {
  478. h = BigInt.add(h, ONE)
  479. continue
  480. }
  481. primes[bit_length].g = g
  482. t('g')
  483. return
  484. }
  485. throw new Error('Unreachable!')
  486. }
  487. function DSA(obj, opts) {
  488. if (!(this instanceof DSA)) return new DSA(obj, opts)
  489. // options
  490. opts = opts || {}
  491. // inherit
  492. if (obj) {
  493. var self = this
  494. ;['p', 'q', 'g', 'y', 'x'].forEach(function (prop) {
  495. self[prop] = obj[prop]
  496. })
  497. this.type = obj.type || KEY_TYPE
  498. return
  499. }
  500. // default to 1024
  501. var bit_length = parseInt(opts.bit_length ? opts.bit_length : 1024, 10)
  502. if (!bit_lengths[bit_length])
  503. throw new Error('Unsupported bit length.')
  504. // set primes
  505. if (!primes[bit_length])
  506. generatePrimes(bit_length)
  507. this.p = primes[bit_length].p
  508. this.q = primes[bit_length].q
  509. this.g = primes[bit_length].g
  510. // key type
  511. this.type = KEY_TYPE
  512. // private key
  513. this.x = makeRandom(ZERO, this.q)
  514. // public keys (p, q, g, y)
  515. this.y = BigInt.powMod(this.g, this.x, this.p)
  516. // nocache?
  517. if (opts.nocache) primes[bit_length] = null
  518. }
  519. DSA.prototype = {
  520. constructor: DSA,
  521. packPublic: function () {
  522. var str = this.type
  523. str += HLP.packMPI(this.p)
  524. str += HLP.packMPI(this.q)
  525. str += HLP.packMPI(this.g)
  526. str += HLP.packMPI(this.y)
  527. return str
  528. },
  529. packPrivate: function () {
  530. var str = this.packPublic() + HLP.packMPI(this.x)
  531. str = CryptoJS.enc.Latin1.parse(str)
  532. return str.toString(CryptoJS.enc.Base64)
  533. },
  534. // http://www.imperialviolet.org/2013/06/15/suddendeathentropy.html
  535. generateNonce: function (m) {
  536. var priv = BigInt.bigInt2bits(BigInt.trim(this.x, 0))
  537. var rand = BigInt.bigInt2bits(BigInt.randBigInt(256))
  538. var sha256 = CryptoJS.algo.SHA256.create()
  539. sha256.update(CryptoJS.enc.Latin1.parse(priv))
  540. sha256.update(m)
  541. sha256.update(CryptoJS.enc.Latin1.parse(rand))
  542. var hash = sha256.finalize()
  543. hash = HLP.bits2bigInt(hash.toString(CryptoJS.enc.Latin1))
  544. BigInt.rightShift_(hash, 256 - BigInt.bitSize(this.q))
  545. return HLP.between(hash, ZERO, this.q) ? hash : this.generateNonce(m)
  546. },
  547. sign: function (m) {
  548. m = CryptoJS.enc.Latin1.parse(m)
  549. var b = BigInt.str2bigInt(m.toString(CryptoJS.enc.Hex), 16)
  550. var k, r = ZERO, s = ZERO
  551. while (BigInt.isZero(s) || BigInt.isZero(r)) {
  552. k = this.generateNonce(m)
  553. r = BigInt.mod(BigInt.powMod(this.g, k, this.p), this.q)
  554. if (BigInt.isZero(r)) continue
  555. s = BigInt.inverseMod(k, this.q)
  556. s = BigInt.mult(s, BigInt.add(b, BigInt.mult(this.x, r)))
  557. s = BigInt.mod(s, this.q)
  558. }
  559. return [r, s]
  560. },
  561. fingerprint: function () {
  562. var pk = this.packPublic()
  563. if (this.type === KEY_TYPE) pk = pk.substring(2)
  564. pk = CryptoJS.enc.Latin1.parse(pk)
  565. return CryptoJS.SHA1(pk).toString(CryptoJS.enc.Hex)
  566. }
  567. }
  568. DSA.parsePublic = function (str, priv) {
  569. var fields = ['SHORT', 'MPI', 'MPI', 'MPI', 'MPI']
  570. if (priv) fields.push('MPI')
  571. str = HLP.splitype(fields, str)
  572. var obj = {
  573. type: str[0]
  574. , p: HLP.readMPI(str[1])
  575. , q: HLP.readMPI(str[2])
  576. , g: HLP.readMPI(str[3])
  577. , y: HLP.readMPI(str[4])
  578. }
  579. if (priv) obj.x = HLP.readMPI(str[5])
  580. return new DSA(obj)
  581. }
  582. function tokenizeStr(str) {
  583. var start, end
  584. start = str.indexOf("(")
  585. end = str.lastIndexOf(")")
  586. if (start < 0 || end < 0)
  587. throw new Error("Malformed S-Expression")
  588. str = str.substring(start + 1, end)
  589. var splt = str.search(/\s/)
  590. var obj = {
  591. type: str.substring(0, splt)
  592. , val: []
  593. }
  594. str = str.substring(splt + 1, end)
  595. start = str.indexOf("(")
  596. if (start < 0) obj.val.push(str)
  597. else {
  598. var i, len, ss, es
  599. while (start > -1) {
  600. i = start + 1
  601. len = str.length
  602. for (ss = 1, es = 0; i < len && es < ss; i++) {
  603. if (str[i] === "(") ss++
  604. if (str[i] === ")") es++
  605. }
  606. obj.val.push(tokenizeStr(str.substring(start, ++i)))
  607. str = str.substring(++i)
  608. start = str.indexOf("(")
  609. }
  610. }
  611. return obj
  612. }
  613. function parseLibotr(obj) {
  614. if (!obj.type) throw new Error("Parse error.")
  615. var o, val
  616. if (obj.type === "privkeys") {
  617. o = []
  618. obj.val.forEach(function (i) {
  619. o.push(parseLibotr(i))
  620. })
  621. return o
  622. }
  623. o = {}
  624. obj.val.forEach(function (i) {
  625. val = i.val[0]
  626. if (typeof val === "string") {
  627. if (val.indexOf("#") === 0) {
  628. val = val.substring(1, val.lastIndexOf("#"))
  629. val = BigInt.str2bigInt(val, 16)
  630. }
  631. } else {
  632. val = parseLibotr(i)
  633. }
  634. o[i.type] = val
  635. })
  636. return o
  637. }
  638. DSA.parsePrivate = function (str, libotr) {
  639. if (!libotr) {
  640. str = CryptoJS.enc.Base64.parse(str)
  641. str = str.toString(CryptoJS.enc.Latin1)
  642. return DSA.parsePublic(str, true)
  643. }
  644. // only returning the first key found
  645. return parseLibotr(tokenizeStr(str))[0]["private-key"].dsa
  646. }
  647. DSA.verify = function (key, m, r, s) {
  648. if (!HLP.between(r, ZERO, key.q) || !HLP.between(s, ZERO, key.q))
  649. return false
  650. var hm = CryptoJS.enc.Latin1.parse(m) // CryptoJS.SHA1(m)
  651. hm = BigInt.str2bigInt(hm.toString(CryptoJS.enc.Hex), 16)
  652. var w = BigInt.inverseMod(s, key.q)
  653. var u1 = BigInt.multMod(hm, w, key.q)
  654. var u2 = BigInt.multMod(r, w, key.q)
  655. u1 = BigInt.powMod(key.g, u1, key.p)
  656. u2 = BigInt.powMod(key.y, u2, key.p)
  657. var v = BigInt.mod(BigInt.multMod(u1, u2, key.p), key.q)
  658. return BigInt.equals(v, r)
  659. }
  660. DSA.createInWebWorker = function (options, cb) {
  661. var opts = {
  662. path: WWPath
  663. , seed: BigInt.getSeed
  664. }
  665. if (options && typeof options === 'object')
  666. Object.keys(options).forEach(function (k) {
  667. opts[k] = options[k]
  668. })
  669. // load optional dep. in node
  670. if (typeof module !== 'undefined' && module.exports)
  671. Worker = require('webworker-threads').Worker
  672. var worker = new Worker(opts.path)
  673. worker.onmessage = function (e) {
  674. var data = e.data
  675. switch (data.type) {
  676. case "debug":
  677. if (!DEBUG || typeof console === 'undefined') return
  678. console.log(data.val)
  679. break;
  680. case "data":
  681. worker.terminate()
  682. cb(DSA.parsePrivate(data.val))
  683. break;
  684. default:
  685. throw new Error("Unrecognized type.")
  686. }
  687. }
  688. worker.postMessage({
  689. seed: opts.seed()
  690. , imports: opts.imports
  691. , debug: DEBUG
  692. })
  693. }
  694. }).call(this)
  695. ;(function () {
  696. "use strict";
  697. var root = this
  698. var Parse = {}, CryptoJS, CONST, HLP
  699. if (typeof module !== 'undefined' && module.exports) {
  700. module.exports = Parse
  701. CryptoJS = require('../vendor/crypto.js')
  702. CONST = require('./const.js')
  703. HLP = require('./helpers.js')
  704. } else {
  705. root.OTR.Parse = Parse
  706. CryptoJS = root.CryptoJS
  707. CONST = root.OTR.CONST
  708. HLP = root.OTR.HLP
  709. }
  710. // whitespace tags
  711. var tags = {}
  712. tags[CONST.WHITESPACE_TAG_V2] = CONST.OTR_VERSION_2
  713. tags[CONST.WHITESPACE_TAG_V3] = CONST.OTR_VERSION_3
  714. Parse.parseMsg = function (otr, msg) {
  715. var ver = []
  716. // is this otr?
  717. var start = msg.indexOf(CONST.OTR_TAG)
  718. if (!~start) {
  719. // restart fragments
  720. this.initFragment(otr)
  721. // whitespace tags
  722. ind = msg.indexOf(CONST.WHITESPACE_TAG)
  723. if (~ind) {
  724. msg = msg.split('')
  725. msg.splice(ind, 16)
  726. var tag, len = msg.length
  727. for (; ind < len;) {
  728. tag = msg.slice(ind, ind + 8).join('')
  729. if (Object.hasOwnProperty.call(tags, tag)) {
  730. msg.splice(ind, 8)
  731. ver.push(tags[tag])
  732. continue
  733. }
  734. ind += 8
  735. }
  736. msg = msg.join('')
  737. }
  738. return { msg: msg, ver: ver }
  739. }
  740. var ind = start + CONST.OTR_TAG.length
  741. var com = msg[ind]
  742. // message fragment
  743. if (com === ',' || com === '|') {
  744. return this.msgFragment(otr, msg.substring(ind + 1), (com === '|'))
  745. }
  746. this.initFragment(otr)
  747. // query message
  748. if (~['?', 'v'].indexOf(com)) {
  749. // version 1
  750. if (msg[ind] === '?') {
  751. ver.push(CONST.OTR_VERSION_1)
  752. ind += 1
  753. }
  754. // other versions
  755. var vers = {
  756. '2': CONST.OTR_VERSION_2
  757. , '3': CONST.OTR_VERSION_3
  758. }
  759. var qs = msg.substring(ind + 1)
  760. var qi = qs.indexOf('?')
  761. if (qi >= 1) {
  762. qs = qs.substring(0, qi).split('')
  763. if (msg[ind] === 'v') {
  764. qs.forEach(function (q) {
  765. if (Object.hasOwnProperty.call(vers, q)) ver.push(vers[q])
  766. })
  767. }
  768. }
  769. return { cls: 'query', ver: ver }
  770. }
  771. // otr message
  772. if (com === ':') {
  773. ind += 1
  774. var info = msg.substring(ind, ind + 4)
  775. if (info.length < 4) return { msg: msg }
  776. info = CryptoJS.enc.Base64.parse(info).toString(CryptoJS.enc.Latin1)
  777. var version = info.substring(0, 2)
  778. var type = info.substring(2)
  779. // supporting otr versions 2 and 3
  780. if (!otr['ALLOW_V' + HLP.unpackSHORT(version)]) return { msg: msg }
  781. ind += 4
  782. var end = msg.substring(ind).indexOf('.')
  783. if (!~end) return { msg: msg }
  784. msg = CryptoJS.enc.Base64.parse(msg.substring(ind, ind + end))
  785. msg = CryptoJS.enc.Latin1.stringify(msg)
  786. // instance tags
  787. var instance_tags
  788. if (version === CONST.OTR_VERSION_3) {
  789. instance_tags = msg.substring(0, 8)
  790. msg = msg.substring(8)
  791. }
  792. var cls
  793. if (~['\x02', '\x0a', '\x11', '\x12'].indexOf(type)) {
  794. cls = 'ake'
  795. } else if (type === '\x03') {
  796. cls = 'data'
  797. }
  798. return {
  799. version: version
  800. , type: type
  801. , msg: msg
  802. , cls: cls
  803. , instance_tags: instance_tags
  804. }
  805. }
  806. // error message
  807. if (msg.substring(ind, ind + 7) === ' Error:') {
  808. if (otr.ERROR_START_AKE) {
  809. otr.sendQueryMsg()
  810. }
  811. return { msg: msg.substring(ind + 7), cls: 'error' }
  812. }
  813. return { msg: msg }
  814. }
  815. Parse.initFragment = function (otr) {
  816. otr.fragment = { s: '', j: 0, k: 0 }
  817. }
  818. Parse.msgFragment = function (otr, msg, v3) {
  819. msg = msg.split(',')
  820. // instance tags
  821. if (v3) {
  822. var its = msg.shift().split('|')
  823. var their_it = HLP.packINT(parseInt(its[0], 16))
  824. var our_it = HLP.packINT(parseInt(its[1], 16))
  825. if (otr.checkInstanceTags(their_it + our_it)) return // ignore
  826. }
  827. if (msg.length < 4 ||
  828. isNaN(parseInt(msg[0], 10)) ||
  829. isNaN(parseInt(msg[1], 10))
  830. ) return
  831. var k = parseInt(msg[0], 10)
  832. var n = parseInt(msg[1], 10)
  833. msg = msg[2]
  834. if (n < k || n === 0 || k === 0) {
  835. this.initFragment(otr)
  836. return
  837. }
  838. if (k === 1) {
  839. this.initFragment(otr)
  840. otr.fragment = { k: 1, n: n, s: msg }
  841. } else if (n === otr.fragment.n && k === (otr.fragment.k + 1)) {
  842. otr.fragment.s += msg
  843. otr.fragment.k += 1
  844. } else {
  845. this.initFragment(otr)
  846. }
  847. if (n === k) {
  848. msg = otr.fragment.s
  849. this.initFragment(otr)
  850. return this.parseMsg(otr, msg)
  851. }
  852. return
  853. }
  854. }).call(this)
  855. ;(function () {
  856. "use strict";
  857. var root = this
  858. var CryptoJS, BigInt, CONST, HLP, DSA
  859. if (typeof module !== 'undefined' && module.exports) {
  860. module.exports = AKE
  861. CryptoJS = require('../vendor/crypto.js')
  862. BigInt = require('../vendor/bigint.js')
  863. CONST = require('./const.js')
  864. HLP = require('./helpers.js')
  865. DSA = require('./dsa.js')
  866. } else {
  867. root.OTR.AKE = AKE
  868. CryptoJS = root.CryptoJS
  869. BigInt = root.BigInt
  870. CONST = root.OTR.CONST
  871. HLP = root.OTR.HLP
  872. DSA = root.DSA
  873. }
  874. // diffie-hellman modulus
  875. // see group 5, RFC 3526
  876. var N = BigInt.str2bigInt(CONST.N, 16)
  877. var N_MINUS_2 = BigInt.sub(N, BigInt.str2bigInt('2', 10))
  878. function hMac(gx, gy, pk, kid, m) {
  879. var pass = CryptoJS.enc.Latin1.parse(m)
  880. var hmac = CryptoJS.algo.HMAC.create(CryptoJS.algo.SHA256, pass)
  881. hmac.update(CryptoJS.enc.Latin1.parse(HLP.packMPI(gx)))
  882. hmac.update(CryptoJS.enc.Latin1.parse(HLP.packMPI(gy)))
  883. hmac.update(CryptoJS.enc.Latin1.parse(pk))
  884. hmac.update(CryptoJS.enc.Latin1.parse(kid))
  885. return (hmac.finalize()).toString(CryptoJS.enc.Latin1)
  886. }
  887. // AKE constructor
  888. function AKE(otr) {
  889. if (!(this instanceof AKE)) return new AKE(otr)
  890. // otr instance
  891. this.otr = otr
  892. // our keys
  893. this.our_dh = otr.our_old_dh
  894. this.our_keyid = otr.our_keyid - 1
  895. // their keys
  896. this.their_y = null
  897. this.their_keyid = null
  898. this.their_priv_pk = null
  899. // state
  900. this.ssid = null
  901. this.transmittedRS = false
  902. this.r = null
  903. // bind methods
  904. var self = this
  905. ;['sendMsg'].forEach(function (meth) {
  906. self[meth] = self[meth].bind(self)
  907. })
  908. }
  909. AKE.prototype = {
  910. constructor: AKE,
  911. createKeys: function(g) {
  912. var s = BigInt.powMod(g, this.our_dh.privateKey, N)
  913. var secbytes = HLP.packMPI(s)
  914. this.ssid = HLP.mask(HLP.h2('\x00', secbytes), 0, 64) // first 64-bits
  915. var tmp = HLP.h2('\x01', secbytes)
  916. this.c = HLP.mask(tmp, 0, 128) // first 128-bits
  917. this.c_prime = HLP.mask(tmp, 128, 128) // second 128-bits
  918. this.m1 = HLP.h2('\x02', secbytes)
  919. this.m2 = HLP.h2('\x03', secbytes)
  920. this.m1_prime = HLP.h2('\x04', secbytes)
  921. this.m2_prime = HLP.h2('\x05', secbytes)
  922. },
  923. verifySignMac: function (mac, aesctr, m2, c, their_y, our_dh_pk, m1, ctr) {
  924. // verify mac
  925. var vmac = HLP.makeMac(aesctr, m2)
  926. if (!HLP.compare(mac, vmac))
  927. return ['MACs do not match.']
  928. // decrypt x
  929. var x = HLP.decryptAes(aesctr.substring(4), c, ctr)
  930. x = HLP.splitype(['PUBKEY', 'INT', 'SIG'], x.toString(CryptoJS.enc.Latin1))
  931. var m = hMac(their_y, our_dh_pk, x[0], x[1], m1)
  932. var pub = DSA.parsePublic(x[0])
  933. var r = HLP.bits2bigInt(x[2].substring(0, 20))
  934. var s = HLP.bits2bigInt(x[2].substring(20))
  935. // verify sign m
  936. if (!DSA.verify(pub, m, r, s)) return ['Cannot verify signature of m.']
  937. return [null, HLP.readLen(x[1]), pub]
  938. },
  939. makeM: function (their_y, m1, c, m2) {
  940. var pk = this.otr.priv.packPublic()
  941. var kid = HLP.packINT(this.our_keyid)
  942. var m = hMac(this.our_dh.publicKey, their_y, pk, kid, m1)
  943. m = this.otr.priv.sign(m)
  944. var msg = pk + kid
  945. msg += BigInt.bigInt2bits(m[0], 20) // pad to 20 bytes
  946. msg += BigInt.bigInt2bits(m[1], 20)
  947. msg = CryptoJS.enc.Latin1.parse(msg)
  948. var aesctr = HLP.packData(HLP.encryptAes(msg, c, HLP.packCtr(0)))
  949. var mac = HLP.makeMac(aesctr, m2)
  950. return aesctr + mac
  951. },
  952. akeSuccess: function (version) {
  953. HLP.debug.call(this.otr, 'success')
  954. if (BigInt.equals(this.their_y, this.our_dh.publicKey))
  955. return this.otr.error('equal keys - we have a problem.')
  956. this.otr.our_old_dh = this.our_dh
  957. this.otr.their_priv_pk = this.their_priv_pk
  958. if (!(
  959. (this.their_keyid === this.otr.their_keyid &&
  960. BigInt.equals(this.their_y, this.otr.their_y)) ||
  961. (this.their_keyid === (this.otr.their_keyid - 1) &&
  962. BigInt.equals(this.their_y, this.otr.their_old_y))
  963. )) {
  964. this.otr.their_y = this.their_y
  965. this.otr.their_old_y = null
  966. this.otr.their_keyid = this.their_keyid
  967. // rotate keys
  968. this.otr.sessKeys[0] = [ new this.otr.DHSession(
  969. this.otr.our_dh
  970. , this.otr.their_y
  971. ), null ]
  972. this.otr.sessKeys[1] = [ new this.otr.DHSession(
  973. this.otr.our_old_dh
  974. , this.otr.their_y
  975. ), null ]
  976. }
  977. // ake info
  978. this.otr.ssid = this.ssid
  979. this.otr.transmittedRS = this.transmittedRS
  980. this.otr_version = version
  981. // go encrypted
  982. this.otr.authstate = CONST.AUTHSTATE_NONE
  983. this.otr.msgstate = CONST.MSGSTATE_ENCRYPTED
  984. // null out values
  985. this.r = null
  986. this.myhashed = null
  987. this.dhcommit = null
  988. this.encrypted = null
  989. this.hashed = null
  990. this.otr.trigger('status', [CONST.STATUS_AKE_SUCCESS])
  991. // send stored msgs
  992. this.otr.sendStored()
  993. },
  994. handleAKE: function (msg) {
  995. var send, vsm, type
  996. var version = msg.version
  997. switch (msg.type) {
  998. case '\x02':
  999. HLP.debug.call(this.otr, 'd-h key message')
  1000. msg = HLP.splitype(['DATA', 'DATA'], msg.msg)
  1001. if (this.otr.authstate === CONST.AUTHSTATE_AWAITING_DHKEY) {
  1002. var ourHash = HLP.readMPI(this.myhashed)
  1003. var theirHash = HLP.readMPI(msg[1])
  1004. if (BigInt.greater(ourHash, theirHash)) {
  1005. type = '\x02'
  1006. send = this.dhcommit
  1007. break // ignore
  1008. } else {
  1009. // forget
  1010. this.our_dh = this.otr.dh()
  1011. this.otr.authstate = CONST.AUTHSTATE_NONE
  1012. this.r = null
  1013. this.myhashed = null
  1014. }
  1015. } else if (
  1016. this.otr.authstate === CONST.AUTHSTATE_AWAITING_SIG
  1017. ) this.our_dh = this.otr.dh()
  1018. this.otr.authstate = CONST.AUTHSTATE_AWAITING_REVEALSIG
  1019. this.encrypted = msg[0].substring(4)
  1020. this.hashed = msg[1].substring(4)
  1021. type = '\x0a'
  1022. send = HLP.packMPI(this.our_dh.publicKey)
  1023. break
  1024. case '\x0a':
  1025. HLP.debug.call(this.otr, 'reveal signature message')
  1026. msg = HLP.splitype(['MPI'], msg.msg)
  1027. if (this.otr.authstate !== CONST.AUTHSTATE_AWAITING_DHKEY) {
  1028. if (this.otr.authstate === CONST.AUTHSTATE_AWAITING_SIG) {
  1029. if (!BigInt.equals(this.their_y, HLP.readMPI(msg[0]))) return
  1030. } else {
  1031. return // ignore
  1032. }
  1033. }
  1034. this.otr.authstate = CONST.AUTHSTATE_AWAITING_SIG
  1035. this.their_y = HLP.readMPI(msg[0])
  1036. // verify gy is legal 2 <= gy <= N-2
  1037. if (!HLP.checkGroup(this.their_y, N_MINUS_2))
  1038. return this.otr.error('Illegal g^y.')
  1039. this.createKeys(this.their_y)
  1040. type = '\x11'
  1041. send = HLP.packMPI(this.r)
  1042. send += this.makeM(this.their_y, this.m1, this.c, this.m2)
  1043. this.m1 = null
  1044. this.m2 = null
  1045. this.c = null
  1046. break
  1047. case '\x11':
  1048. HLP.debug.call(this.otr, 'signature message')
  1049. if (this.otr.authstate !== CONST.AUTHSTATE_AWAITING_REVEALSIG)
  1050. return // ignore
  1051. msg = HLP.splitype(['DATA', 'DATA', 'MAC'], msg.msg)
  1052. this.r = HLP.readMPI(msg[0])
  1053. // decrypt their_y
  1054. var key = CryptoJS.enc.Hex.parse(BigInt.bigInt2str(this.r, 16))
  1055. key = CryptoJS.enc.Latin1.stringify(key)
  1056. var gxmpi = HLP.decryptAes(this.encrypted, key, HLP.packCtr(0))
  1057. gxmpi = gxmpi.toString(CryptoJS.enc.Latin1)
  1058. this.their_y = HLP.readMPI(gxmpi)
  1059. // verify hash
  1060. var hash = CryptoJS.SHA256(CryptoJS.enc.Latin1.parse(gxmpi))
  1061. if (!HLP.compare(this.hashed, hash.toString(CryptoJS.enc.Latin1)))
  1062. return this.otr.error('Hashed g^x does not match.')
  1063. // verify gx is legal 2 <= g^x <= N-2
  1064. if (!HLP.checkGroup(this.their_y, N_MINUS_2))
  1065. return this.otr.error('Illegal g^x.')
  1066. this.createKeys(this.their_y)
  1067. vsm = this.verifySignMac(
  1068. msg[2]
  1069. , msg[1]
  1070. , this.m2
  1071. , this.c
  1072. , this.their_y
  1073. , this.our_dh.publicKey
  1074. , this.m1
  1075. , HLP.packCtr(0)
  1076. )
  1077. if (vsm[0]) return this.otr.error(vsm[0])
  1078. // store their key
  1079. this.their_keyid = vsm[1]
  1080. this.their_priv_pk = vsm[2]
  1081. send = this.makeM(
  1082. this.their_y
  1083. , this.m1_prime
  1084. , this.c_prime
  1085. , this.m2_prime
  1086. )
  1087. this.m1 = null
  1088. this.m2 = null
  1089. this.m1_prime = null
  1090. this.m2_prime = null
  1091. this.c = null
  1092. this.c_prime = null
  1093. this.sendMsg(version, '\x12', send)
  1094. this.akeSuccess(version)
  1095. return
  1096. case '\x12':
  1097. HLP.debug.call(this.otr, 'data message')
  1098. if (this.otr.authstate !== CONST.AUTHSTATE_AWAITING_SIG)
  1099. return // ignore
  1100. msg = HLP.splitype(['DATA', 'MAC'], msg.msg)
  1101. vsm = this.verifySignMac(
  1102. msg[1]
  1103. , msg[0]
  1104. , this.m2_prime
  1105. , this.c_prime
  1106. , this.their_y
  1107. , this.our_dh.publicKey
  1108. , this.m1_prime
  1109. , HLP.packCtr(0)
  1110. )
  1111. if (vsm[0]) return this.otr.error(vsm[0])
  1112. // store their key
  1113. this.their_keyid = vsm[1]
  1114. this.their_priv_pk = vsm[2]
  1115. this.m1_prime = null
  1116. this.m2_prime = null
  1117. this.c_prime = null
  1118. this.transmittedRS = true
  1119. this.akeSuccess(version)
  1120. return
  1121. default:
  1122. return // ignore
  1123. }
  1124. this.sendMsg(version, type, send)
  1125. },
  1126. sendMsg: function (version, type, msg) {
  1127. var send = version + type
  1128. var v3 = (version === CONST.OTR_VERSION_3)
  1129. // instance tags for v3
  1130. if (v3) {
  1131. HLP.debug.call(this.otr, 'instance tags')
  1132. send += this.otr.our_instance_tag
  1133. send += this.otr.their_instance_tag
  1134. }
  1135. send += msg
  1136. // fragment message if necessary
  1137. send = HLP.wrapMsg(
  1138. send
  1139. , this.otr.fragment_size
  1140. , v3
  1141. , this.otr.our_instance_tag
  1142. , this.otr.their_instance_tag
  1143. )
  1144. if (send[0]) return this.otr.error(send[0])
  1145. this.otr.io(send[1])
  1146. },
  1147. initiateAKE: function (version) {
  1148. HLP.debug.call(this.otr, 'd-h commit message')
  1149. this.otr.trigger('status', [CONST.STATUS_AKE_INIT])
  1150. this.otr.authstate = CONST.AUTHSTATE_AWAITING_DHKEY
  1151. var gxmpi = HLP.packMPI(this.our_dh.publicKey)
  1152. gxmpi = CryptoJS.enc.Latin1.parse(gxmpi)
  1153. this.r = BigInt.randBigInt(128)
  1154. var key = CryptoJS.enc.Hex.parse(BigInt.bigInt2str(this.r, 16))
  1155. key = CryptoJS.enc.Latin1.stringify(key)
  1156. this.myhashed = CryptoJS.SHA256(gxmpi)
  1157. this.myhashed = HLP.packData(this.myhashed.toString(CryptoJS.enc.Latin1))
  1158. this.dhcommit = HLP.packData(HLP.encryptAes(gxmpi, key, HLP.packCtr(0)))
  1159. this.dhcommit += this.myhashed
  1160. this.sendMsg(version, '\x02', this.dhcommit)
  1161. }
  1162. }
  1163. }).call(this)
  1164. ;(function () {
  1165. "use strict";
  1166. var root = this
  1167. var CryptoJS, BigInt, EventEmitter, CONST, HLP
  1168. if (typeof module !== 'undefined' && module.exports) {
  1169. module.exports = SM
  1170. CryptoJS = require('../vendor/crypto.js')
  1171. BigInt = require('../vendor/bigint.js')
  1172. EventEmitter = require('../vendor/eventemitter.js')
  1173. CONST = require('./const.js')
  1174. HLP = require('./helpers.js')
  1175. } else {
  1176. root.OTR.SM = SM
  1177. CryptoJS = root.CryptoJS
  1178. BigInt = root.BigInt
  1179. EventEmitter = root.EventEmitter
  1180. CONST = root.OTR.CONST
  1181. HLP = root.OTR.HLP
  1182. }
  1183. // diffie-hellman modulus and generator
  1184. // see group 5, RFC 3526
  1185. var G = BigInt.str2bigInt(CONST.G, 10)
  1186. var N = BigInt.str2bigInt(CONST.N, 16)
  1187. var N_MINUS_2 = BigInt.sub(N, BigInt.str2bigInt('2', 10))
  1188. // to calculate D's for zero-knowledge proofs
  1189. var Q = BigInt.sub(N, BigInt.str2bigInt('1', 10))
  1190. BigInt.divInt_(Q, 2) // meh
  1191. function SM(reqs) {
  1192. if (!(this instanceof SM)) return new SM(reqs)
  1193. this.version = 1
  1194. this.our_fp = reqs.our_fp
  1195. this.their_fp = reqs.their_fp
  1196. this.ssid = reqs.ssid
  1197. this.debug = !!reqs.debug
  1198. // initial state
  1199. this.init()
  1200. }
  1201. // inherit from EE
  1202. HLP.extend(SM, EventEmitter)
  1203. // set the initial values
  1204. // also used when aborting
  1205. SM.prototype.init = function () {
  1206. this.smpstate = CONST.SMPSTATE_EXPECT1
  1207. this.secret = null
  1208. }
  1209. SM.prototype.makeSecret = function (our, secret) {
  1210. var sha256 = CryptoJS.algo.SHA256.create()
  1211. sha256.update(CryptoJS.enc.Latin1.parse(HLP.packBytes(this.version, 1)))
  1212. sha256.update(CryptoJS.enc.Hex.parse(our ? this.our_fp : this.their_fp))
  1213. sha256.update(CryptoJS.enc.Hex.parse(our ? this.their_fp : this.our_fp))
  1214. sha256.update(CryptoJS.enc.Latin1.parse(this.ssid))
  1215. sha256.update(CryptoJS.enc.Latin1.parse(secret))
  1216. var hash = sha256.finalize()
  1217. this.secret = HLP.bits2bigInt(hash.toString(CryptoJS.enc.Latin1))
  1218. }
  1219. SM.prototype.makeG2s = function () {
  1220. this.a2 = HLP.randomExponent()
  1221. this.a3 = HLP.randomExponent()
  1222. this.g2a = BigInt.powMod(G, this.a2, N)
  1223. this.g3a = BigInt.powMod(G, this.a3, N)
  1224. if ( !HLP.checkGroup(this.g2a, N_MINUS_2) ||
  1225. !HLP.checkGroup(this.g3a, N_MINUS_2)
  1226. ) this.makeG2s()
  1227. }
  1228. SM.prototype.computeGs = function (g2a, g3a) {
  1229. this.g2 = BigInt.powMod(g2a, this.a2, N)
  1230. this.g3 = BigInt.powMod(g3a, this.a3, N)
  1231. }
  1232. SM.prototype.computePQ = function (r) {
  1233. this.p = BigInt.powMod(this.g3, r, N)
  1234. this.q = HLP.multPowMod(G, r, this.g2, this.secret, N)
  1235. }
  1236. SM.prototype.computeR = function () {
  1237. this.r = BigInt.powMod(this.QoQ, this.a3, N)
  1238. }
  1239. SM.prototype.computeRab = function (r) {
  1240. return BigInt.powMod(r, this.a3, N)
  1241. }
  1242. SM.prototype.computeC = function (v, r) {
  1243. return HLP.smpHash(v, BigInt.powMod(G, r, N))
  1244. }
  1245. SM.prototype.computeD = function (r, a, c) {
  1246. return BigInt.subMod(r, BigInt.multMod(a, c, Q), Q)
  1247. }
  1248. // the bulk of the work
  1249. SM.prototype.handleSM = function (msg) {
  1250. var send, r2, r3, r7, t1, t2, t3, t4, rab, tmp2, cR, d7, ms, trust
  1251. var expectStates = {
  1252. 2: CONST.SMPSTATE_EXPECT1
  1253. , 3: CONST.SMPSTATE_EXPECT2
  1254. , 4: CONST.SMPSTATE_EXPECT3
  1255. , 5: CONST.SMPSTATE_EXPECT4
  1256. , 7: CONST.SMPSTATE_EXPECT1
  1257. }
  1258. if (msg.type === 6) {
  1259. this.init()
  1260. this.trigger('abort')
  1261. return
  1262. }
  1263. // abort! there was an error
  1264. if (this.smpstate !== expectStates[msg.type])
  1265. return this.abort()
  1266. switch (this.smpstate) {
  1267. case CONST.SMPSTATE_EXPECT1:
  1268. HLP.debug.call(this, 'smp tlv 2')
  1269. // user specified question
  1270. var ind, question
  1271. if (msg.type === 7) {
  1272. ind = msg.msg.indexOf('\x00')
  1273. question = msg.msg.substring(0, ind)
  1274. msg.msg = msg.msg.substring(ind + 1)
  1275. }
  1276. // 0:g2a, 1:c2, 2:d2, 3:g3a, 4:c3, 5:d3
  1277. ms = HLP.readLen(msg.msg.substr(0, 4))
  1278. if (ms !== 6) return this.abort()
  1279. msg = HLP.unpackMPIs(6, msg.msg.substring(4))
  1280. if ( !HLP.checkGroup(msg[0], N_MINUS_2) ||
  1281. !HLP.checkGroup(msg[3], N_MINUS_2)
  1282. ) return this.abort()
  1283. // verify znp's
  1284. if (!HLP.ZKP(1, msg[1], HLP.multPowMod(G, msg[2], msg[0], msg[1], N)))
  1285. return this.abort()
  1286. if (!HLP.ZKP(2, msg[4], HLP.multPowMod(G, msg[5], msg[3], msg[4], N)))
  1287. return this.abort()
  1288. this.g3ao = msg[3] // save for later
  1289. this.makeG2s()
  1290. // zero-knowledge proof that the exponents
  1291. // associated with g2a & g3a are known
  1292. r2 = HLP.randomExponent()
  1293. r3 = HLP.randomExponent()
  1294. this.c2 = this.computeC(3, r2)
  1295. this.c3 = this.computeC(4, r3)
  1296. this.d2 = this.computeD(r2, this.a2, this.c2)
  1297. this.d3 = this.computeD(r3, this.a3, this.c3)
  1298. this.computeGs(msg[0], msg[3])
  1299. this.smpstate = CONST.SMPSTATE_EXPECT0
  1300. if (question) {
  1301. // assume utf8 question
  1302. question = CryptoJS.enc.Latin1
  1303. .parse(question)
  1304. .toString(CryptoJS.enc.Utf8)
  1305. }
  1306. // invoke question
  1307. this.trigger('question', [question])
  1308. return
  1309. case CONST.SMPSTATE_EXPECT2:
  1310. HLP.debug.call(this, 'smp tlv 3')
  1311. // 0:g2a, 1:c2, 2:d2, 3:g3a, 4:c3, 5:d3, 6:p, 7:q, 8:cP, 9:d5, 10:d6
  1312. ms = HLP.readLen(msg.msg.substr(0, 4))
  1313. if (ms !== 11) return this.abort()
  1314. msg = HLP.unpackMPIs(11, msg.msg.substring(4))
  1315. if ( !HLP.checkGroup(msg[0], N_MINUS_2) ||
  1316. !HLP.checkGroup(msg[3], N_MINUS_2) ||
  1317. !HLP.checkGroup(msg[6], N_MINUS_2) ||
  1318. !HLP.checkGroup(msg[7], N_MINUS_2)
  1319. ) return this.abort()
  1320. // verify znp of c3 / c3
  1321. if (!HLP.ZKP(3, msg[1], HLP.multPowMod(G, msg[2], msg[0], msg[1], N)))
  1322. return this.abort()
  1323. if (!HLP.ZKP(4, msg[4], HLP.multPowMod(G, msg[5], msg[3], msg[4], N)))
  1324. return this.abort()
  1325. this.g3ao = msg[3] // save for later
  1326. this.computeGs(msg[0], msg[3])
  1327. // verify znp of cP
  1328. t1 = HLP.multPowMod(this.g3, msg[9], msg[6], msg[8], N)
  1329. t2 = HLP.multPowMod(G, msg[9], this.g2, msg[10], N)
  1330. t2 = BigInt.multMod(t2, BigInt.powMod(msg[7], msg[8], N), N)
  1331. if (!HLP.ZKP(5, msg[8], t1, t2))
  1332. return this.abort()
  1333. var r4 = HLP.randomExponent()
  1334. this.computePQ(r4)
  1335. // zero-knowledge proof that P & Q
  1336. // were generated according to the protocol
  1337. var r5 = HLP.randomExponent()
  1338. var r6 = HLP.randomExponent()
  1339. var tmp = HLP.multPowMod(G, r5, this.g2, r6, N)
  1340. var cP = HLP.smpHash(6, BigInt.powMod(this.g3, r5, N), tmp)
  1341. var d5 = this.computeD(r5, r4, cP)
  1342. var d6 = this.computeD(r6, this.secret, cP)
  1343. // store these
  1344. this.QoQ = BigInt.divMod(this.q, msg[7], N)
  1345. this.PoP = BigInt.divMod(this.p, msg[6], N)
  1346. this.computeR()
  1347. // zero-knowledge proof that R
  1348. // was generated according to the protocol
  1349. r7 = HLP.randomExponent()
  1350. tmp2 = BigInt.powMod(this.QoQ, r7, N)
  1351. cR = HLP.smpHash(7, BigInt.powMod(G, r7, N), tmp2)
  1352. d7 = this.computeD(r7, this.a3, cR)
  1353. this.smpstate = CONST.SMPSTATE_EXPECT4
  1354. send = HLP.packINT(8) + HLP.packMPIs([
  1355. this.p
  1356. , this.q
  1357. , cP
  1358. , d5
  1359. , d6
  1360. , this.r
  1361. , cR
  1362. , d7
  1363. ])
  1364. // TLV
  1365. send = HLP.packTLV(4, send)
  1366. break
  1367. case CONST.SMPSTATE_EXPECT3:
  1368. HLP.debug.call(this, 'smp tlv 4')
  1369. // 0:p, 1:q, 2:cP, 3:d5, 4:d6, 5:r, 6:cR, 7:d7
  1370. ms = HLP.readLen(msg.msg.substr(0, 4))
  1371. if (ms !== 8) return this.abort()
  1372. msg = HLP.unpackMPIs(8, msg.msg.substring(4))
  1373. if ( !HLP.checkGroup(msg[0], N_MINUS_2) ||
  1374. !HLP.checkGroup(msg[1], N_MINUS_2) ||
  1375. !HLP.checkGroup(msg[5], N_MINUS_2)
  1376. ) return this.abort()
  1377. // verify znp of cP
  1378. t1 = HLP.multPowMod(this.g3, msg[3], msg[0], msg[2], N)
  1379. t2 = HLP.multPowMod(G, msg[3], this.g2, msg[4], N)
  1380. t2 = BigInt.multMod(t2, BigInt.powMod(msg[1], msg[2], N), N)
  1381. if (!HLP.ZKP(6, msg[2], t1, t2))
  1382. return this.abort()
  1383. // verify znp of cR
  1384. t3 = HLP.multPowMod(G, msg[7], this.g3ao, msg[6], N)
  1385. this.QoQ = BigInt.divMod(msg[1], this.q, N) // save Q over Q
  1386. t4 = HLP.multPowMod(this.QoQ, msg[7], msg[5], msg[6], N)
  1387. if (!HLP.ZKP(7, msg[6], t3, t4))
  1388. return this.abort()
  1389. this.computeR()
  1390. // zero-knowledge proof that R
  1391. // was generated according to the protocol
  1392. r7 = HLP.randomExponent()
  1393. tmp2 = BigInt.powMod(this.QoQ, r7, N)
  1394. cR = HLP.smpHash(8, BigInt.powMod(G, r7, N), tmp2)
  1395. d7 = this.computeD(r7, this.a3, cR)
  1396. send = HLP.packINT(3) + HLP.packMPIs([ this.r, cR, d7 ])
  1397. send = HLP.packTLV(5, send)
  1398. rab = this.computeRab(msg[5])
  1399. trust = !!BigInt.equals(rab, BigInt.divMod(msg[0], this.p, N))
  1400. this.trigger('trust', [trust, 'answered'])
  1401. this.init()
  1402. break
  1403. case CONST.SMPSTATE_EXPECT4:
  1404. HLP.debug.call(this, 'smp tlv 5')
  1405. // 0:r, 1:cR, 2:d7
  1406. ms = HLP.readLen(msg.msg.substr(0, 4))
  1407. if (ms !== 3) return this.abort()
  1408. msg = HLP.unpackMPIs(3, msg.msg.substring(4))
  1409. if (!HLP.checkGroup(msg[0], N_MINUS_2)) return this.abort()
  1410. // verify znp of cR
  1411. t3 = HLP.multPowMod(G, msg[2], this.g3ao, msg[1], N)
  1412. t4 = HLP.multPowMod(this.QoQ, msg[2], msg[0], msg[1], N)
  1413. if (!HLP.ZKP(8, msg[1], t3, t4))
  1414. return this.abort()
  1415. rab = this.computeRab(msg[0])
  1416. trust = !!BigInt.equals(rab, this.PoP)
  1417. this.trigger('trust', [trust, 'asked'])
  1418. this.init()
  1419. return
  1420. }
  1421. this.sendMsg(send)
  1422. }
  1423. // send a message
  1424. SM.prototype.sendMsg = function (send) {
  1425. this.trigger('send', [this.ssid, '\x00' + send])
  1426. }
  1427. SM.prototype.rcvSecret = function (secret, question) {
  1428. HLP.debug.call(this, 'receive secret')
  1429. var fn, our = false
  1430. if (this.smpstate === CONST.SMPSTATE_EXPECT0) {
  1431. fn = this.answer
  1432. } else {
  1433. fn = this.initiate
  1434. our = true
  1435. }
  1436. this.makeSecret(our, secret)
  1437. fn.call(this, question)
  1438. }
  1439. SM.prototype.answer = function () {
  1440. HLP.debug.call(this, 'smp answer')
  1441. var r4 = HLP.randomExponent()
  1442. this.computePQ(r4)
  1443. // zero-knowledge proof that P & Q
  1444. // were generated according to the protocol
  1445. var r5 = HLP.randomExponent()
  1446. var r6 = HLP.randomExponent()
  1447. var tmp = HLP.multPowMod(G, r5, this.g2, r6, N)
  1448. var cP = HLP.smpHash(5, BigInt.powMod(this.g3, r5, N), tmp)
  1449. var d5 = this.computeD(r5, r4, cP)
  1450. var d6 = this.computeD(r6, this.secret, cP)
  1451. this.smpstate = CONST.SMPSTATE_EXPECT3
  1452. var send = HLP.packINT(11) + HLP.packMPIs([
  1453. this.g2a
  1454. , this.c2
  1455. , this.d2
  1456. , this.g3a
  1457. , this.c3
  1458. , this.d3
  1459. , this.p
  1460. , this.q
  1461. , cP
  1462. , d5
  1463. , d6
  1464. ])
  1465. this.sendMsg(HLP.packTLV(3, send))
  1466. }
  1467. SM.prototype.initiate = function (question) {
  1468. HLP.debug.call(this, 'smp initiate')
  1469. if (this.smpstate !== CONST.SMPSTATE_EXPECT1)
  1470. this.abort() // abort + restart
  1471. this.makeG2s()
  1472. // zero-knowledge proof that the exponents
  1473. // associated with g2a & g3a are known
  1474. var r2 = HLP.randomExponent()
  1475. var r3 = HLP.randomExponent()
  1476. this.c2 = this.computeC(1, r2)
  1477. this.c3 = this.computeC(2, r3)
  1478. this.d2 = this.computeD(r2, this.a2, this.c2)
  1479. this.d3 = this.computeD(r3, this.a3, this.c3)
  1480. // set the next expected state
  1481. this.smpstate = CONST.SMPSTATE_EXPECT2
  1482. var send = ''
  1483. var type = 2
  1484. if (question) {
  1485. send += question
  1486. send += '\x00'
  1487. type = 7
  1488. }
  1489. send += HLP.packINT(6) + HLP.packMPIs([
  1490. this.g2a
  1491. , this.c2
  1492. , this.d2
  1493. , this.g3a
  1494. , this.c3
  1495. , this.d3
  1496. ])
  1497. this.sendMsg(HLP.packTLV(type, send))
  1498. }
  1499. SM.prototype.abort = function () {
  1500. this.init()
  1501. this.sendMsg(HLP.packTLV(6, ''))
  1502. this.trigger('abort')
  1503. }
  1504. }).call(this)
  1505. ;(function () {
  1506. "use strict";
  1507. var root = this
  1508. var CryptoJS, BigInt, EventEmitter, Worker, SMWPath
  1509. , CONST, HLP, Parse, AKE, SM, DSA
  1510. if (typeof module !== 'undefined' && module.exports) {
  1511. module.exports = OTR
  1512. CryptoJS = require('../vendor/crypto.js')
  1513. BigInt = require('../vendor/bigint.js')
  1514. EventEmitter = require('../vendor/eventemitter.js')
  1515. SMWPath = require('path').join(__dirname, '/sm-webworker.js')
  1516. CONST = require('./const.js')
  1517. HLP = require('./helpers.js')
  1518. Parse = require('./parse.js')
  1519. AKE = require('./ake.js')
  1520. SM = require('./sm.js')
  1521. DSA = require('./dsa.js')
  1522. // expose CONST for consistency with docs
  1523. OTR.CONST = CONST
  1524. } else {
  1525. // copy over and expose internals
  1526. Object.keys(root.OTR).forEach(function (k) {
  1527. OTR[k] = root.OTR[k]
  1528. })
  1529. root.OTR = OTR
  1530. CryptoJS = root.CryptoJS
  1531. BigInt = root.BigInt
  1532. EventEmitter = root.EventEmitter
  1533. Worker = root.Worker
  1534. SMWPath = 'sm-webworker.js'
  1535. CONST = OTR.CONST
  1536. HLP = OTR.HLP
  1537. Parse = OTR.Parse
  1538. AKE = OTR.AKE
  1539. SM = OTR.SM
  1540. DSA = root.DSA
  1541. }
  1542. // diffie-hellman modulus and generator
  1543. // see group 5, RFC 3526
  1544. var G = BigInt.str2bigInt(CONST.G, 10)
  1545. var N = BigInt.str2bigInt(CONST.N, 16)
  1546. // JavaScript integers
  1547. var MAX_INT = Math.pow(2, 53) - 1 // doubles
  1548. var MAX_UINT = Math.pow(2, 31) - 1 // bitwise operators
  1549. // an internal callback
  1550. function OTRCB(cb) {
  1551. this.cb = cb
  1552. }
  1553. // OTR contructor
  1554. function OTR(options) {
  1555. if (!(this instanceof OTR)) return new OTR(options)
  1556. // options
  1557. options = options || {}
  1558. // private keys
  1559. if (options.priv && !(options.priv instanceof DSA))
  1560. throw new Error('Requires long-lived DSA key.')
  1561. this.priv = options.priv ? options.priv : new DSA()
  1562. this.fragment_size = options.fragment_size || 0
  1563. if (this.fragment_size < 0)
  1564. throw new Error('Fragment size must be a positive integer.')
  1565. this.send_interval = options.send_interval || 0
  1566. if (this.send_interval < 0)
  1567. throw new Error('Send interval must be a positive integer.')
  1568. this.outgoing = []
  1569. // instance tag
  1570. this.our_instance_tag = options.instance_tag || OTR.makeInstanceTag()
  1571. // debug
  1572. this.debug = !!options.debug
  1573. // smp in webworker options
  1574. // this is still experimental and undocumented
  1575. this.smw = options.smw
  1576. // init vals
  1577. this.init()
  1578. // bind methods
  1579. var self = this
  1580. ;['sendMsg', 'receiveMsg'].forEach(function (meth) {
  1581. self[meth] = self[meth].bind(self)
  1582. })
  1583. EventEmitter.call(this)
  1584. }
  1585. // inherit from EE
  1586. HLP.extend(OTR, EventEmitter)
  1587. // add to prototype
  1588. OTR.prototype.init = function () {
  1589. this.msgstate = CONST.MSGSTATE_PLAINTEXT
  1590. this.authstate = CONST.AUTHSTATE_NONE
  1591. this.ALLOW_V2 = true
  1592. this.ALLOW_V3 = true
  1593. this.REQUIRE_ENCRYPTION = false
  1594. this.SEND_WHITESPACE_TAG = false
  1595. this.WHITESPACE_START_AKE = false
  1596. this.ERROR_START_AKE = false
  1597. Parse.initFragment(this)
  1598. // their keys
  1599. this.their_y = null
  1600. this.their_old_y = null
  1601. this.their_keyid = 0
  1602. this.their_priv_pk = null
  1603. this.their_instance_tag = '\x00\x00\x00\x00'
  1604. // our keys
  1605. this.our_dh = this.dh()
  1606. this.our_old_dh = this.dh()
  1607. this.our_keyid = 2
  1608. // session keys
  1609. this.sessKeys = [ new Array(2), new Array(2) ]
  1610. // saved
  1611. this.storedMgs = []
  1612. this.oldMacKeys = []
  1613. // smp
  1614. this.sm = null // initialized after AKE
  1615. // when ake is complete
  1616. // save their keys and the session
  1617. this._akeInit()
  1618. // receive plaintext message since switching to plaintext
  1619. // used to decide when to stop sending pt tags when SEND_WHITESPACE_TAG
  1620. this.receivedPlaintext = false
  1621. }
  1622. OTR.prototype._akeInit = function () {
  1623. this.ake = new AKE(this)
  1624. this.transmittedRS = false
  1625. this.ssid = null
  1626. }
  1627. // smp over webworker
  1628. OTR.prototype._SMW = function (otr, reqs) {
  1629. this.otr = otr
  1630. var opts = {
  1631. path: SMWPath
  1632. , seed: BigInt.getSeed
  1633. }
  1634. if (typeof otr.smw === 'object')
  1635. Object.keys(otr.smw).forEach(function (k) {
  1636. opts[k] = otr.smw[k]
  1637. })
  1638. // load optional dep. in node
  1639. if (typeof module !== 'undefined' && module.exports)
  1640. Worker = require('webworker-threads').Worker
  1641. this.worker = new Worker(opts.path)
  1642. var self = this
  1643. this.worker.onmessage = function (e) {
  1644. var d = e.data
  1645. if (!d) return
  1646. self.trigger(d.method, d.args)
  1647. }
  1648. this.worker.postMessage({
  1649. type: 'seed'
  1650. , seed: opts.seed()
  1651. , imports: opts.imports
  1652. })
  1653. this.worker.postMessage({
  1654. type: 'init'
  1655. , reqs: reqs
  1656. })
  1657. }
  1658. // inherit from EE
  1659. HLP.extend(OTR.prototype._SMW, EventEmitter)
  1660. // shim sm methods
  1661. ;['handleSM', 'rcvSecret', 'abort'].forEach(function (m) {
  1662. OTR.prototype._SMW.prototype[m] = function () {
  1663. this.worker.postMessage({
  1664. type: 'method'
  1665. , method: m
  1666. , args: Array.prototype.slice.call(arguments, 0)
  1667. })
  1668. }
  1669. })
  1670. OTR.prototype._smInit = function () {
  1671. var reqs = {
  1672. ssid: this.ssid
  1673. , our_fp: this.priv.fingerprint()
  1674. , their_fp: this.their_priv_pk.fingerprint()
  1675. , debug: this.debug
  1676. }
  1677. if (this.smw) {
  1678. if (this.sm) this.sm.worker.terminate() // destroy prev webworker
  1679. this.sm = new this._SMW(this, reqs)
  1680. } else {
  1681. this.sm = new SM(reqs)
  1682. }
  1683. var self = this
  1684. ;['trust', 'abort', 'question'].forEach(function (e) {
  1685. self.sm.on(e, function () {
  1686. self.trigger('smp', [e].concat(Array.prototype.slice.call(arguments)))
  1687. })
  1688. })
  1689. this.sm.on('send', function (ssid, send) {
  1690. if (self.ssid === ssid) {
  1691. send = self.prepareMsg(send)
  1692. self.io(send)
  1693. }
  1694. })
  1695. }
  1696. OTR.prototype.io = function (msg, meta) {
  1697. // buffer
  1698. msg = ([].concat(msg)).map(function(m, i, arr) {
  1699. var obj = { msg: m }
  1700. if (!(meta instanceof OTRCB) ||
  1701. i === (arr.length - 1) // only cb after last fragment is sent
  1702. ) obj.meta = meta
  1703. return obj
  1704. })
  1705. this.outgoing = this.outgoing.concat(msg)
  1706. var self = this
  1707. ;(function send(first) {
  1708. if (!first) {
  1709. if (!self.outgoing.length) return
  1710. var elem = self.outgoing.shift(), cb = null
  1711. if (elem.meta instanceof OTRCB) {
  1712. cb = elem.meta.cb
  1713. elem.meta = null
  1714. }
  1715. self.trigger('io', [elem.msg, elem.meta])
  1716. if (cb) cb()
  1717. }
  1718. setTimeout(send, first ? 0 : self.send_interval)
  1719. }(true))
  1720. }
  1721. OTR.prototype.dh = function dh() {
  1722. var keys = { privateKey: BigInt.randBigInt(320) }
  1723. keys.publicKey = BigInt.powMod(G, keys.privateKey, N)
  1724. return keys
  1725. }
  1726. // session constructor
  1727. OTR.prototype.DHSession = function DHSession(our_dh, their_y) {
  1728. if (!(this instanceof DHSession)) return new DHSession(our_dh, their_y)
  1729. // shared secret
  1730. var s = BigInt.powMod(their_y, our_dh.privateKey, N)
  1731. var secbytes = HLP.packMPI(s)
  1732. // session id
  1733. this.id = HLP.mask(HLP.h2('\x00', secbytes), 0, 64) // first 64-bits
  1734. // are we the high or low end of the connection?
  1735. var sq = BigInt.greater(our_dh.publicKey, their_y)
  1736. var sendbyte = sq ? '\x01' : '\x02'
  1737. var rcvbyte = sq ? '\x02' : '\x01'
  1738. // sending and receiving keys
  1739. this.sendenc = HLP.mask(HLP.h1(sendbyte, secbytes), 0, 128) // f16 bytes
  1740. this.sendmac = CryptoJS.SHA1(CryptoJS.enc.Latin1.parse(this.sendenc))
  1741. this.sendmac = this.sendmac.toString(CryptoJS.enc.Latin1)
  1742. this.rcvenc = HLP.mask(HLP.h1(rcvbyte, secbytes), 0, 128)
  1743. this.rcvmac = CryptoJS.SHA1(CryptoJS.enc.Latin1.parse(this.rcvenc))
  1744. this.rcvmac = this.rcvmac.toString(CryptoJS.enc.Latin1)
  1745. this.rcvmacused = false
  1746. // extra symmetric key
  1747. this.extra_symkey = HLP.h2('\xff', secbytes)
  1748. // counters
  1749. this.send_counter = 0
  1750. this.rcv_counter = 0
  1751. }
  1752. OTR.prototype.rotateOurKeys = function () {
  1753. // reveal old mac keys
  1754. var self = this
  1755. this.sessKeys[1].forEach(function (sk) {
  1756. if (sk && sk.rcvmacused) self.oldMacKeys.push(sk.rcvmac)
  1757. })
  1758. // rotate our keys
  1759. this.our_old_dh = this.our_dh
  1760. this.our_dh = this.dh()
  1761. this.our_keyid += 1
  1762. this.sessKeys[1][0] = this.sessKeys[0][0]
  1763. this.sessKeys[1][1] = this.sessKeys[0][1]
  1764. this.sessKeys[0] = [
  1765. this.their_y ?
  1766. new this.DHSession(this.our_dh, this.their_y) : null
  1767. , this.their_old_y ?
  1768. new this.DHSession(this.our_dh, this.their_old_y) : null
  1769. ]
  1770. }
  1771. OTR.prototype.rotateTheirKeys = function (their_y) {
  1772. // increment their keyid
  1773. this.their_keyid += 1
  1774. // reveal old mac keys
  1775. var self = this
  1776. this.sessKeys.forEach(function (sk) {
  1777. if (sk[1] && sk[1].rcvmacused) self.oldMacKeys.push(sk[1].rcvmac)
  1778. })
  1779. // rotate their keys / session
  1780. this.their_old_y = this.their_y
  1781. this.sessKeys[0][1] = this.sessKeys[0][0]
  1782. this.sessKeys[1][1] = this.sessKeys[1][0]
  1783. // new keys / sessions
  1784. this.their_y = their_y
  1785. this.sessKeys[0][0] = new this.DHSession(this.our_dh, this.their_y)
  1786. this.sessKeys[1][0] = new this.DHSession(this.our_old_dh, this.their_y)
  1787. }
  1788. OTR.prototype.prepareMsg = function (msg, esk) {
  1789. if (this.msgstate !== CONST.MSGSTATE_ENCRYPTED || this.their_keyid === 0)
  1790. return this.notify('Not ready to encrypt.')
  1791. var sessKeys = this.sessKeys[1][0]
  1792. if (sessKeys.send_counter >= MAX_INT)
  1793. return this.notify('Should have rekeyed by now.')
  1794. sessKeys.send_counter += 1
  1795. var ctr = HLP.packCtr(sessKeys.send_counter)
  1796. var send = this.ake.otr_version + '\x03' // version and type
  1797. var v3 = (this.ake.otr_version === CONST.OTR_VERSION_3)
  1798. if (v3) {
  1799. send += this.our_instance_tag
  1800. send += this.their_instance_tag
  1801. }
  1802. send += '\x00' // flag
  1803. send += HLP.packINT(this.our_keyid - 1)
  1804. send += HLP.packINT(this.their_keyid)
  1805. send += HLP.packMPI(this.our_dh.publicKey)
  1806. send += ctr.substring(0, 8)
  1807. if (Math.ceil(msg.length / 8) >= MAX_UINT) // * 16 / 128
  1808. return this.notify('Message is too long.')
  1809. var aes = HLP.encryptAes(
  1810. CryptoJS.enc.Latin1.parse(msg)
  1811. , sessKeys.sendenc
  1812. , ctr
  1813. )
  1814. send += HLP.packData(aes)
  1815. send += HLP.make1Mac(send, sessKeys.sendmac)
  1816. send += HLP.packData(this.oldMacKeys.splice(0).join(''))
  1817. send = HLP.wrapMsg(
  1818. send
  1819. , this.fragment_size
  1820. , v3
  1821. , this.our_instance_tag
  1822. , this.their_instance_tag
  1823. )
  1824. if (send[0]) return this.notify(send[0])
  1825. // emit extra symmetric key
  1826. if (esk) this.trigger('file', ['send', sessKeys.extra_symkey, esk])
  1827. return send[1]
  1828. }
  1829. OTR.prototype.handleDataMsg = function (msg) {
  1830. var vt = msg.version + msg.type
  1831. if (this.ake.otr_version === CONST.OTR_VERSION_3)
  1832. vt += msg.instance_tags
  1833. var types = ['BYTE', 'INT', 'INT', 'MPI', 'CTR', 'DATA', 'MAC', 'DATA']
  1834. msg = HLP.splitype(types, msg.msg)
  1835. // ignore flag
  1836. var ign = (msg[0] === '\x01')
  1837. if (this.msgstate !== CONST.MSGSTATE_ENCRYPTED || msg.length !== 8) {
  1838. if (!ign) this.error('Received an unreadable encrypted message.')
  1839. return
  1840. }
  1841. var our_keyid = this.our_keyid - HLP.readLen(msg[2])
  1842. var their_keyid = this.their_keyid - HLP.readLen(msg[1])
  1843. if (our_keyid < 0 || our_keyid > 1) {
  1844. if (!ign) this.error('Not of our latest keys.')
  1845. return
  1846. }
  1847. if (their_keyid < 0 || their_keyid > 1) {
  1848. if (!ign) this.error('Not of your latest keys.')
  1849. return
  1850. }
  1851. var their_y = their_keyid ? this.their_old_y : this.their_y
  1852. if (their_keyid === 1 && !their_y) {
  1853. if (!ign) this.error('Do not have that key.')
  1854. return
  1855. }
  1856. var sessKeys = this.sessKeys[our_keyid][their_keyid]
  1857. var ctr = HLP.unpackCtr(msg[4])
  1858. if (ctr <= sessKeys.rcv_counter) {
  1859. if (!ign) this.error('Counter in message is not larger.')
  1860. return
  1861. }
  1862. sessKeys.rcv_counter = ctr
  1863. // verify mac
  1864. vt += msg.slice(0, 6).join('')
  1865. var vmac = HLP.make1Mac(vt, sessKeys.rcvmac)
  1866. if (!HLP.compare(msg[6], vmac)) {
  1867. if (!ign) this.error('MACs do not match.')
  1868. return
  1869. }
  1870. sessKeys.rcvmacused = true
  1871. var out = HLP.decryptAes(
  1872. msg[5].substring(4)
  1873. , sessKeys.rcvenc
  1874. , HLP.padCtr(msg[4])
  1875. )
  1876. out = out.toString(CryptoJS.enc.Latin1)
  1877. if (!our_keyid) this.rotateOurKeys()
  1878. if (!their_keyid) this.rotateTheirKeys(HLP.readMPI(msg[3]))
  1879. // parse TLVs
  1880. var ind = out.indexOf('\x00')
  1881. if (~ind) {
  1882. this.handleTLVs(out.substring(ind + 1), sessKeys)
  1883. out = out.substring(0, ind)
  1884. }
  1885. out = CryptoJS.enc.Latin1.parse(out)
  1886. return out.toString(CryptoJS.enc.Utf8)
  1887. }
  1888. OTR.prototype.handleTLVs = function (tlvs, sessKeys) {
  1889. var type, len, msg
  1890. for (; tlvs.length; ) {
  1891. type = HLP.unpackSHORT(tlvs.substr(0, 2))
  1892. len = HLP.unpackSHORT(tlvs.substr(2, 2))
  1893. msg = tlvs.substr(4, len)
  1894. // TODO: handle pathological cases better
  1895. if (msg.length < len) break
  1896. switch (type) {
  1897. case 1:
  1898. // Disconnected
  1899. this.msgstate = CONST.MSGSTATE_FINISHED
  1900. this.trigger('status', [CONST.STATUS_END_OTR])
  1901. break
  1902. case 2: case 3: case 4:
  1903. case 5: case 6: case 7:
  1904. // SMP
  1905. if (this.msgstate !== CONST.MSGSTATE_ENCRYPTED) {
  1906. if (this.sm) this.sm.abort()
  1907. return
  1908. }
  1909. if (!this.sm) this._smInit()
  1910. this.sm.handleSM({ msg: msg, type: type })
  1911. break
  1912. case 8:
  1913. // utf8 filenames
  1914. msg = msg.substring(4) // remove 4-byte indication
  1915. msg = CryptoJS.enc.Latin1.parse(msg)
  1916. msg = msg.toString(CryptoJS.enc.Utf8)
  1917. // Extra Symkey
  1918. this.trigger('file', ['receive', sessKeys.extra_symkey, msg])
  1919. break
  1920. }
  1921. tlvs = tlvs.substring(4 + len)
  1922. }
  1923. }
  1924. OTR.prototype.smpSecret = function (secret, question) {
  1925. if (this.msgstate !== CONST.MSGSTATE_ENCRYPTED)
  1926. return this.notify('Must be encrypted for SMP.')
  1927. if (typeof secret !== 'string' || secret.length < 1)
  1928. return this.notify('Secret is required.')
  1929. if (!this.sm) this._smInit()
  1930. // utf8 inputs
  1931. secret = CryptoJS.enc.Utf8.parse(secret).toString(CryptoJS.enc.Latin1)
  1932. if (question)
  1933. question = CryptoJS.enc.Utf8.parse(question).toString(CryptoJS.enc.Latin1)
  1934. this.sm.rcvSecret(secret, question)
  1935. }
  1936. OTR.prototype.sendQueryMsg = function () {
  1937. var versions = {}
  1938. , msg = CONST.OTR_TAG
  1939. if (this.ALLOW_V2) versions['2'] = true
  1940. if (this.ALLOW_V3) versions['3'] = true
  1941. // but we don't allow v1
  1942. // if (versions['1']) msg += '?'
  1943. var vs = Object.keys(versions)
  1944. if (vs.length) {
  1945. msg += 'v'
  1946. vs.forEach(function (v) {
  1947. if (v !== '1') msg += v
  1948. })
  1949. msg += '?'
  1950. }
  1951. this.io(msg)
  1952. this.trigger('status', [CONST.STATUS_SEND_QUERY])
  1953. }
  1954. OTR.prototype.sendMsg = function (msg, meta) {
  1955. if ( this.REQUIRE_ENCRYPTION ||
  1956. this.msgstate !== CONST.MSGSTATE_PLAINTEXT
  1957. ) {
  1958. msg = CryptoJS.enc.Utf8.parse(msg)
  1959. msg = msg.toString(CryptoJS.enc.Latin1)
  1960. }
  1961. switch (this.msgstate) {
  1962. case CONST.MSGSTATE_PLAINTEXT:
  1963. if (this.REQUIRE_ENCRYPTION) {
  1964. this.storedMgs.push({msg: msg, meta: meta})
  1965. this.sendQueryMsg()
  1966. return
  1967. }
  1968. if (this.SEND_WHITESPACE_TAG && !this.receivedPlaintext) {
  1969. msg += CONST.WHITESPACE_TAG // 16 byte tag
  1970. if (this.ALLOW_V3) msg += CONST.WHITESPACE_TAG_V3
  1971. if (this.ALLOW_V2) msg += CONST.WHITESPACE_TAG_V2
  1972. }
  1973. break
  1974. case CONST.MSGSTATE_FINISHED:
  1975. this.storedMgs.push({msg: msg, meta: meta})
  1976. this.notify('Message cannot be sent at this time.', 'warn')
  1977. return
  1978. case CONST.MSGSTATE_ENCRYPTED:
  1979. msg = this.prepareMsg(msg)
  1980. break
  1981. default:
  1982. throw new Error('Unknown message state.')
  1983. }
  1984. if (msg) this.io(msg, meta)
  1985. }
  1986. OTR.prototype.receiveMsg = function (msg, meta) {
  1987. // parse type
  1988. msg = Parse.parseMsg(this, msg)
  1989. if (!msg) return
  1990. switch (msg.cls) {
  1991. case 'error':
  1992. this.notify(msg.msg)
  1993. return
  1994. case 'ake':
  1995. if ( msg.version === CONST.OTR_VERSION_3 &&
  1996. this.checkInstanceTags(msg.instance_tags)
  1997. ) {
  1998. this.notify(
  1999. 'Received a message intended for a different session.', 'warn')
  2000. return // ignore
  2001. }
  2002. this.ake.handleAKE(msg)
  2003. return
  2004. case 'data':
  2005. if ( msg.version === CONST.OTR_VERSION_3 &&
  2006. this.checkInstanceTags(msg.instance_tags)
  2007. ) {
  2008. this.notify(
  2009. 'Received a message intended for a different session.', 'warn')
  2010. return // ignore
  2011. }
  2012. msg.msg = this.handleDataMsg(msg)
  2013. msg.encrypted = true
  2014. break
  2015. case 'query':
  2016. if (this.msgstate === CONST.MSGSTATE_ENCRYPTED) this._akeInit()
  2017. this.doAKE(msg)
  2018. break
  2019. default:
  2020. // check for encrypted
  2021. if ( this.REQUIRE_ENCRYPTION ||
  2022. this.msgstate !== CONST.MSGSTATE_PLAINTEXT
  2023. ) this.notify('Received an unencrypted message.', 'warn')
  2024. // received a plaintext message
  2025. // stop sending the whitespace tag
  2026. this.receivedPlaintext = true
  2027. // received a whitespace tag
  2028. if (this.WHITESPACE_START_AKE && msg.ver.length > 0)
  2029. this.doAKE(msg)
  2030. }
  2031. if (msg.msg) this.trigger('ui', [msg.msg, !!msg.encrypted, meta])
  2032. }
  2033. OTR.prototype.checkInstanceTags = function (it) {
  2034. var their_it = HLP.readLen(it.substr(0, 4))
  2035. var our_it = HLP.readLen(it.substr(4, 4))
  2036. if (our_it && our_it !== HLP.readLen(this.our_instance_tag))
  2037. return true
  2038. if (HLP.readLen(this.their_instance_tag)) {
  2039. if (HLP.readLen(this.their_instance_tag) !== their_it) return true
  2040. } else {
  2041. if (their_it < 100) return true
  2042. this.their_instance_tag = HLP.packINT(their_it)
  2043. }
  2044. }
  2045. OTR.prototype.doAKE = function (msg) {
  2046. if (this.ALLOW_V3 && ~msg.ver.indexOf(CONST.OTR_VERSION_3)) {
  2047. this.ake.initiateAKE(CONST.OTR_VERSION_3)
  2048. } else if (this.ALLOW_V2 && ~msg.ver.indexOf(CONST.OTR_VERSION_2)) {
  2049. this.ake.initiateAKE(CONST.OTR_VERSION_2)
  2050. } else {
  2051. this.notify('OTR conversation requested, ' +
  2052. 'but no compatible protocol version found.', 'warn')
  2053. }
  2054. }
  2055. OTR.prototype.error = function (err) {
  2056. if (!this.debug) err = 'An OTR error has occurred.'
  2057. this.io('?OTR Error:' + err)
  2058. this.notify(err)
  2059. }
  2060. OTR.prototype.notify = function (err, severity) {
  2061. this.trigger('error', [err, severity || 'error'])
  2062. }
  2063. OTR.prototype.sendStored = function () {
  2064. var self = this
  2065. ;(this.storedMgs.splice(0)).forEach(function (elem) {
  2066. var msg = self.prepareMsg(elem.msg)
  2067. self.io(msg, elem.meta)
  2068. })
  2069. }
  2070. OTR.prototype.sendFile = function (filename) {
  2071. if (this.msgstate !== CONST.MSGSTATE_ENCRYPTED)
  2072. return this.notify('Not ready to encrypt.')
  2073. if (this.ake.otr_version !== CONST.OTR_VERSION_3)
  2074. return this.notify('Protocol v3 required.')
  2075. if (!filename) return this.notify('Please specify a filename.')
  2076. // utf8 filenames
  2077. var l1name = CryptoJS.enc.Utf8.parse(filename)
  2078. l1name = l1name.toString(CryptoJS.enc.Latin1)
  2079. if (l1name.length >= 65532) return this.notify('Filename is too long.')
  2080. var msg = '\x00' // null byte
  2081. msg += '\x00\x08' // type 8 tlv
  2082. msg += HLP.packSHORT(4 + l1name.length) // length of value
  2083. msg += '\x00\x00\x00\x01' // four bytes indicating file
  2084. msg += l1name
  2085. msg = this.prepareMsg(msg, filename)
  2086. this.io(msg)
  2087. }
  2088. OTR.prototype.endOtr = function (cb) {
  2089. if (this.msgstate === CONST.MSGSTATE_ENCRYPTED) {
  2090. if (typeof cb === 'function')
  2091. cb = new OTRCB(cb)
  2092. this.sendMsg('\x00\x00\x01\x00\x00', cb)
  2093. if (this.sm) {
  2094. if (this.smw) this.sm.worker.terminate() // destroy webworker
  2095. this.sm = null
  2096. }
  2097. } else if (typeof cb === 'function')
  2098. setTimeout(cb, 0)
  2099. this.msgstate = CONST.MSGSTATE_PLAINTEXT
  2100. this.receivedPlaintext = false
  2101. this.trigger('status', [CONST.STATUS_END_OTR])
  2102. }
  2103. // attach methods
  2104. OTR.makeInstanceTag = function () {
  2105. var num = BigInt.randBigInt(32)
  2106. if (BigInt.greater(BigInt.str2bigInt('100', 16), num))
  2107. return OTR.makeInstanceTag()
  2108. return HLP.packINT(parseInt(BigInt.bigInt2str(num, 10), 10))
  2109. }
  2110. }).call(this)
  2111. return {
  2112. OTR: this.OTR
  2113. , DSA: this.DSA
  2114. }
  2115. }))