Compare commits
422 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| cd4bc7590e | |||
| d626fed76a | |||
| 739af6ecb4 | |||
| 56b740ef5c | |||
| 18e70c52e1 | |||
| cc3ccf0ddd | |||
| 38db12c2b0 | |||
| a749611370 | |||
| b662d185ca | |||
| 6de6933819 | |||
| f46db48399 | |||
| 8049ddfe26 | |||
| f64e3dea51 | |||
| 17455afe4d | |||
| 047ce47742 | |||
| 558402848e | |||
| db93395061 | |||
| e246e98b20 | |||
| 7ecfa4f384 | |||
| bc216fb7d1 | |||
| b92528aeba | |||
| 81e2a53692 | |||
| 602248425a | |||
| 3b802c08b7 | |||
| 972b30ddc2 | |||
| f58b49fa08 | |||
| 131f9ea645 | |||
| cbf05f84fe | |||
| 611da86353 | |||
| fb4ac5ae51 | |||
| 063c7de783 | |||
| 08d37e0deb | |||
| ff30e5461f | |||
| 4071291fa9 | |||
| 611effd83b | |||
| b63d197292 | |||
| cf901ddac5 | |||
| 122985bd67 | |||
| 19c8482236 | |||
| 33a1bd2337 | |||
| 5f8cb96bab | |||
| 6ddfaa86ae | |||
| 4dc7c0da7a | |||
| 34a1b68d79 | |||
| a04edfe80f | |||
| 32c1abd5d9 | |||
| a47be21f9f | |||
| 5e0ff7d855 | |||
| c3acdc2e38 | |||
| 13c99bcf05 | |||
| b4e0b534d5 | |||
| be4119f84f | |||
| 32b0567343 | |||
| 82fe329129 | |||
| 0e5c3ecfda | |||
| 53f1f1989e | |||
| 081046b6cd | |||
| a61ae52610 | |||
| 477dce6cf8 | |||
| 8a0a47223d | |||
| 1f798214de | |||
| 4459824cc8 | |||
| c2a40d6900 | |||
| a7fa97f0e1 | |||
| 1190fe1204 | |||
| 7026e26d68 | |||
| 37e40a78f2 | |||
| edde5cd0ff | |||
| bff3c373b3 | |||
| f30ad05c70 | |||
| 354dd6b0a2 | |||
| e06de83295 | |||
| ab389d4e71 | |||
| eee946d2cf | |||
| 73af324a3a | |||
| 832118e61a | |||
| 264f8fdd7f | |||
| 36cb8f4676 | |||
| 36fcd5784f | |||
| 46450577c2 | |||
| d3ba23fa64 | |||
| 6d27b5d321 | |||
| 888e75a8fb | |||
| b7f255ce0b | |||
| 477947ba96 | |||
| 33e9a21ce4 | |||
| 2d078e8cd8 | |||
| d6d960dbe5 | |||
| ed109d7ec8 | |||
| bc917863e0 | |||
| e964c1edff | |||
| f5e42ff6f4 | |||
| f594d70daf | |||
| d0608a63b6 | |||
| 09f3ec7125 | |||
| 95593ac4bf | |||
| 1eecc7b17a | |||
| b05b773bd7 | |||
| debc926612 | |||
| 70eb75a3e6 | |||
| 903198a724 | |||
| 7b3dd8a6f5 | |||
| 208f83b9a2 | |||
| 4e3388964a | |||
| b9e1295f7a | |||
| d3865688c8 | |||
| 5a726c2e4d | |||
| db6a7e3e28 | |||
| d9aedfe7d3 | |||
| b2fe57c950 | |||
| 805026360e | |||
| 3d37d21b5f | |||
| c33f0b52e7 | |||
| 1d795c0643 | |||
| c00c0eed1a | |||
| 47fb367486 | |||
| 5e16b38524 | |||
| c728f43c63 | |||
| d1458d0063 | |||
| 66d772a6bc | |||
| a670af376e | |||
| 16691395e0 | |||
| 3018cf8c1a | |||
| 6a126405bd | |||
| ee2f269c06 | |||
| 780cb8a9e6 | |||
| 388d9573fd | |||
| 578dba1987 | |||
| 124c9a7d88 | |||
| e53fa10397 | |||
| 1295668abb | |||
| 880257a431 | |||
| 8b3125bcf3 | |||
| 471b504799 | |||
| b713acbeff | |||
| ff736e9ad3 | |||
| 384c2772fb | |||
| e6d8d8f242 | |||
| ca8efbf657 | |||
| eb6d4e183b | |||
| 6d9deda9c5 | |||
| 96890fab97 | |||
| c0d23e27e4 | |||
| 2d2798954e | |||
| 44e5fa0b82 | |||
| 82cb31f3b6 | |||
| 9348dd5208 | |||
| 17175afd73 | |||
| 53b074e8e7 | |||
| 068065e465 | |||
| 376872d993 | |||
| f55362ff07 | |||
| 36bdb09630 | |||
| d575e571fd | |||
| 00e9d3bf29 | |||
| 26e8095244 | |||
| e4b9d510f1 | |||
| 65e96176cb | |||
| 52beba8695 | |||
| e17e1158d8 | |||
| 2a8df6327e | |||
| 67d4c17516 | |||
| 1f5b492e10 | |||
| cb925eb486 | |||
| e295098330 | |||
| cddc1613ff | |||
| 233b622e47 | |||
| c7ba8c7826 | |||
| 89d2c92474 | |||
| d24f474362 | |||
| f3054df53a | |||
| c8018f29c9 | |||
| 763d2d7c1c | |||
| e1c206b315 | |||
| 63600bf422 | |||
| 19a9730744 | |||
| 7a4dbad3e8 | |||
| 9a88f1800c | |||
| 37c0c80a93 | |||
| aef7ab3a57 | |||
| 27c3da1908 | |||
| 9fcd92c39a | |||
| 7ea468b5d7 | |||
| 9decfe1c95 | |||
| cb839e85c4 | |||
| 31716a7265 | |||
| 301f3ae580 | |||
| db17151941 | |||
| 7d44853da7 | |||
| b405cdae7b | |||
| e02b698015 | |||
| bea32aebed | |||
| bc1ea59867 | |||
| b76c357f3f | |||
| 8e95f18f99 | |||
| 27ec5cff89 | |||
| e2497313f5 | |||
| 04b3b2057c | |||
| b2940c035f | |||
| 9ed4a17d70 | |||
| 6549c04fae | |||
| 2c053f349c | |||
| f2f838f7e2 | |||
| 3278905ead | |||
| a5d4fe1d18 | |||
| 297a818066 | |||
| 9aa2844856 | |||
| 0664584843 | |||
| 3aedd64765 | |||
| 7e6550806f | |||
| e02c62932b | |||
| d5c94db054 | |||
| 008a5118e7 | |||
| 7e2784bfcc | |||
| 669f77edb0 | |||
| e80327ac2f | |||
| a487e2afa7 | |||
| e69a8d89c2 | |||
| 545b6c80de | |||
| 40868636da | |||
| f69ac8e0a0 | |||
| eac2c9fadd | |||
| 1658649d0c | |||
| 74fd12a7ae | |||
| acacb4527d | |||
| 6b9d6c39be | |||
| 55e57c2048 | |||
| 6748098152 | |||
| 724aa3aca0 | |||
| 0f8b7580c6 | |||
| 636aba62ed | |||
| 1c39c7f1f0 | |||
| 6e263063c2 | |||
| ada02f2c03 | |||
| 0da91c7fdb | |||
| 86af0b614d | |||
| 2e00f96431 | |||
| 4a84ab3777 | |||
| 1f7a87ecee | |||
| 7b496ce5bc | |||
| 475cfae4e5 | |||
| f1c8223a51 | |||
| 80e1c38dd5 | |||
| 6d5a137970 | |||
| 6a7b56d56f | |||
| 108b617eef | |||
| 9c2a41fe0e | |||
| 46e2fbee5f | |||
| 7ae8711dc6 | |||
| 247b74950d | |||
| e11012437a | |||
| d0e1fe6a3c | |||
| 367ebb5597 | |||
| 8039dddced | |||
| 78697b9663 | |||
| b590289de5 | |||
| 9a2b50d80b | |||
| 306eab28da | |||
| 7057e31fa0 | |||
| 631c5990f7 | |||
| d97d1b72d7 | |||
| c42612643a | |||
| 52b07abe21 | |||
| 2aa2376e3a | |||
| 30681a7018 | |||
| 077279fe0f | |||
| eb62b2af6e | |||
| a09d18b234 | |||
| 8d71c243b1 | |||
| 7f487fdbd5 | |||
| d91d89167f | |||
| 8ae73adbb7 | |||
| d473f4b6d1 | |||
| c659bcb79e | |||
| c8587115bc | |||
| 85f84ef280 | |||
| 284ef3cc1a | |||
| 8c3fc55124 | |||
| a339a4856a | |||
| c4b6e77127 | |||
| d82aeac93a | |||
| 88b71ce171 | |||
| ff470ad704 | |||
| 65c1d8073c | |||
| 2bb1252666 | |||
| 7307be683f | |||
| 7858c194ca | |||
| 76e25898bb | |||
| 82d35c619c | |||
| 8765971e06 | |||
| 7534574a2f | |||
| fe6b1f9e7f | |||
| 6954e4641d | |||
| 0a2f850267 | |||
| 58995c6f10 | |||
| 49b47baf13 | |||
| cbc01b3f16 | |||
| 3d91fd3492 | |||
| 307dda1ad0 | |||
| d8c90aea88 | |||
| 70cef27dbe | |||
| 4a09e6655e | |||
| 3fa7b532b8 | |||
| 6ff5dfa02d | |||
| 9c4cf4ada2 | |||
| 046e22ea00 | |||
| 77e12cd586 | |||
| bc96026fbf | |||
| 124f28c63a | |||
| 6d1e216115 | |||
| 932e7318b9 | |||
| f2538f337d | |||
| 86725f9b4c | |||
| 6a88340929 | |||
| 6ace64d3ae | |||
| 90966d6251 | |||
| 9aaf26e878 | |||
| 02a7dd2c29 | |||
| 96bc3d3088 | |||
| 58dc1947de | |||
| 58da507bb8 | |||
| 9b940131d3 | |||
| e3716842ef | |||
| bf5ee68828 | |||
| 2574936f60 | |||
| 71ba9a7a54 | |||
| 56d9aa816b | |||
| 64dbc6bb63 | |||
| 6b900d25d0 | |||
| fce6ac5cb4 | |||
| 318d473438 | |||
| 0f7f146f20 | |||
| b992f7c7dd | |||
| a22a3cc0ea | |||
| 40a653f555 | |||
| b144a0933d | |||
| c99124b527 | |||
| 70c585968b | |||
| e46719100c | |||
| 5b0bbd5c12 | |||
| 79f0a095b6 | |||
| f7ec5b2cb6 | |||
| e66f3f89f2 | |||
| 1ee2d93e94 | |||
| fd758dd335 | |||
| 58b4c9408f | |||
| c1d008f1ee | |||
| cdb55d26e5 | |||
| 455e4657f6 | |||
| 3205a3dee8 | |||
| e70f1d947e | |||
| f61274c827 | |||
| 1f758e87d3 | |||
| 3dc3135b21 | |||
| 6502293f21 | |||
| e5d60a8ba2 | |||
| f1a9971c82 | |||
| 65bca0c904 | |||
| 028b26f14b | |||
| ce2b6909cd | |||
| 8b17ac27f0 | |||
| c084c396ba | |||
| 60440cee15 | |||
| a99959719d | |||
| a59f1cd269 | |||
| 5a00c9d18a | |||
| 8d5d2c8230 | |||
| 12d2e7c192 | |||
| a679a97d1b | |||
| 3b20e7a90f | |||
| 562beccf18 | |||
| d4139a9b06 | |||
| 6de07adb71 | |||
| f01e917ecc | |||
| ff36b1270b | |||
| aa78706983 | |||
| 005d9ee999 | |||
| 8787e49b92 | |||
| c1eba48f79 | |||
| 57c7903f60 | |||
| 31a837d55e | |||
| 02889945cb | |||
| 0a1184bde8 | |||
| 7e63919e6d | |||
| e3efeb32a7 | |||
| cc374cd61a | |||
| ac7bdbc22f | |||
| 071f2818a8 | |||
| edc4725260 | |||
| a0315ab1dc | |||
| 465faf19db | |||
| 5f409eeeeb | |||
| 2a6018df9f | |||
| b5087acc24 | |||
| c0f3c66489 | |||
| d595e65685 | |||
| 2f6a1c2bda | |||
| 673118fb21 | |||
| b8bd88d085 | |||
| 975aa8c01c | |||
| 3afc7a2b89 | |||
| 3cc74720f0 | |||
| d67de76770 | |||
| 3e7a7cefc6 | |||
| 9c57ac3985 | |||
| 0d1e1b7281 | |||
| 55dee43279 | |||
| e8c1698995 | |||
| eabf4670fb | |||
| 4ff85f496c | |||
| 67b4e9879a | |||
| fb007628d6 | |||
| 1a5dd77d37 | |||
| 4ed717ad31 | |||
| b7155950d3 | |||
| 6425f611d8 | |||
| b925c96781 | |||
| a6a1ad3d0a | |||
| 5958fb4996 | |||
| c95c24e743 | |||
| 801482be6a | |||
| 208c832b28 |
+9
-1
@@ -1,3 +1,11 @@
|
||||
*.pyc
|
||||
*.o
|
||||
wsproxy
|
||||
*.so
|
||||
other/.lein-deps-sum
|
||||
other/classes
|
||||
other/lib
|
||||
other/node_modules
|
||||
.project
|
||||
.pydevproject
|
||||
target.cfg
|
||||
target.cfg.d
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
[submodule "include/web-socket-js-project"]
|
||||
path = include/web-socket-js-project
|
||||
url = https://github.com/gimite/web-socket-js.git
|
||||
+68
@@ -0,0 +1,68 @@
|
||||
Changes
|
||||
=======
|
||||
|
||||
0.6.1 - May 11, 2015
|
||||
--------------------
|
||||
|
||||
* **PATCH RELEASE**: Fixes a bug causing file_only to not be passed properly
|
||||
|
||||
0.6.0 - Feb 18, 2014
|
||||
--------------------
|
||||
|
||||
* **NOTE** : 0.6.0 will break existing code that sub-classes WebsocketProxy
|
||||
* Refactor to use standard SocketServer RequestHandler design
|
||||
* Fix zombie process bug on certain systems when using multiprocessing
|
||||
* Add better unit tests
|
||||
* Log information via python `logging` module
|
||||
|
||||
0.5.1 - Jun 27, 2013
|
||||
--------------------
|
||||
|
||||
* use upstream einaros/ws (>=0.4.27) with websockify.js
|
||||
* file_only and no_parent security options for WSRequestHandler
|
||||
* Update build of web-socket-js (c0855c6cae)
|
||||
* add include/web-socket-js-project submodule to gimite/web-socket-js
|
||||
for DSFG compliance.
|
||||
* drop Hixie protocol support
|
||||
|
||||
0.4.1 - Mar 12, 2013
|
||||
--------------------
|
||||
|
||||
* ***NOTE*** : 0.5.0 will drop Hixie protocol support
|
||||
* add include/ directory and remove some dev files from source
|
||||
distribution.
|
||||
|
||||
0.4.0 - Mar 12, 2013
|
||||
--------------------
|
||||
|
||||
* ***NOTE*** : 0.5.0 will drop Hixie protocol support
|
||||
* use Buffer base64 support in Node.js implementation
|
||||
|
||||
0.3.0 - Jan 15, 2013
|
||||
--------------------
|
||||
|
||||
* refactor into modules: websocket, websocketproxy
|
||||
* switch to web-socket-js that uses IETF 6455
|
||||
* change to MPL 2.0 license for include/*.js
|
||||
* fix session recording
|
||||
|
||||
0.2.1 - Oct 15, 2012
|
||||
--------------------
|
||||
|
||||
* re-released with updated version number
|
||||
|
||||
0.2.0 - Sep 17, 2012
|
||||
--------------------
|
||||
|
||||
* Binary data support in websock.js
|
||||
* Target config file/dir and multiple targets with token selector
|
||||
* IPv6 fixes
|
||||
* SSL target support
|
||||
* Proxy to/from unix socket
|
||||
|
||||
|
||||
0.1.0 - May 11, 2012
|
||||
--------------------
|
||||
|
||||
* Initial versioned release.
|
||||
|
||||
+11
-6
@@ -1,11 +1,16 @@
|
||||
noVNC is licensed under the LGPL version 3 (see docs/LICENSE.GPL-3 and
|
||||
websockify is licensed under the LGPL version 3 (see docs/LICENSE.GPL-3 and
|
||||
docs/LICENSE.LGPL-3) with the following exceptions:
|
||||
|
||||
include/as3crypto_patched/ : various BSD style licenses
|
||||
include/websock.js : MPL 2.0
|
||||
|
||||
include/base64.js : Dual GPL-2 or LGPL-2.1
|
||||
|
||||
incluee/des.js : Various BSD style licenses
|
||||
include/base64.js : MPL 2.0
|
||||
|
||||
include/web-socket.js/ : New BSD license
|
||||
include/des.js : Various BSD style licenses
|
||||
|
||||
include/web-socket-js/ : New BSD license (3-clause). Source code at
|
||||
https://github.com/gimite/web-socket-js
|
||||
|
||||
other/kumina.c : Simplified BSD license (2 clause).
|
||||
Original source at
|
||||
https://github.com/kumina/wsproxy
|
||||
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
include CHANGES.txt README.md LICENSE.txt
|
||||
graft include
|
||||
@@ -0,0 +1,11 @@
|
||||
TARGETS=rebind.so
|
||||
CFLAGS += -fPIC
|
||||
|
||||
all: $(TARGETS)
|
||||
|
||||
rebind.so: rebind.o
|
||||
$(CC) $(LDFLAGS) $^ -shared -fPIC -ldl -o $@
|
||||
|
||||
clean:
|
||||
rm -f rebind.o rebind.so
|
||||
|
||||
@@ -1,242 +1,183 @@
|
||||
## noVNC: HTML5 VNC Client
|
||||
## websockify: WebSockets support for any application/server
|
||||
|
||||
websockify was formerly named wsproxy and was part of the
|
||||
[noVNC](https://github.com/kanaka/noVNC) project.
|
||||
|
||||
### Description
|
||||
At the most basic level, websockify just translates WebSockets traffic
|
||||
to normal socket traffic. Websockify accepts the WebSockets handshake,
|
||||
parses it, and then begins forwarding traffic between the client and
|
||||
the target in both directions.
|
||||
|
||||
noVNC is a VNC client implemented using HTML5 technologies,
|
||||
specifically Canvas and WebSockets (supports 'wss://' encryption).
|
||||
|
||||
For browsers that do not have builtin WebSockets support, the project
|
||||
includes [web-socket-js](http://github.com/gimite/web-socket-js),
|
||||
a WebSockets emulator using Adobe Flash .
|
||||
|
||||
In addition, [as3crypto](http://github.com/lyokato/as3crypto_patched)
|
||||
has been added to web-socket-js to implement WebSockets SSL/TLS
|
||||
encryption, i.e. the "wss://" URI scheme.
|
||||
|
||||
Special thanks to [Sentry Data Systems](http://www.sentryds.com) for
|
||||
sponsoring ongoing development of this project (and for employing me).
|
||||
### News/help/contact
|
||||
|
||||
Notable commits, announcements and news are posted to
|
||||
@<a href="http://www.twitter.com/noVNC">noVNC</a>
|
||||
<a href="http://www.twitter.com/noVNC">@noVNC</a>
|
||||
|
||||
If you are a websockify developer/integrator/user (or want to be)
|
||||
please join the <a
|
||||
href="https://groups.google.com/forum/?fromgroups#!forum/novnc">noVNC/websockify
|
||||
discussion group</a>
|
||||
|
||||
Bugs and feature requests can be submitted via [github
|
||||
issues](https://github.com/kanaka/websockify/issues).
|
||||
|
||||
If you want to show appreciation for websockify you could donate to a great
|
||||
non-profits such as: [Compassion
|
||||
International](http://www.compassion.com/), [SIL](http://www.sil.org),
|
||||
[Habitat for Humanity](http://www.habitat.org), [Electronic Frontier
|
||||
Foundation](https://www.eff.org/), [Against Malaria
|
||||
Foundation](http://www.againstmalaria.com/), [Nothing But
|
||||
Nets](http://www.nothingbutnets.net/), etc. Please tweet <a
|
||||
href="http://www.twitter.com/noVNC">@noVNC</a> if you do.
|
||||
|
||||
### WebSockets binary data
|
||||
|
||||
Starting with websockify 0.5.0, only the HyBi / IETF
|
||||
6455 WebSocket protocol is supported.
|
||||
|
||||
Websockify negotiates whether to base64 encode traffic to and from the
|
||||
client via the subprotocol header (Sec-WebSocket-Protocol). The valid
|
||||
subprotocol values are 'binary' and 'base64' and if the client sends
|
||||
both then the server (the python implementation) will prefer 'binary'.
|
||||
The 'binary' subprotocol indicates that the data will be sent raw
|
||||
using binary WebSocket frames. Some HyBi clients (such as the Flash
|
||||
fallback and older Chrome and iOS versions) do not support binary data
|
||||
which is why the negotiation is necessary.
|
||||
|
||||
|
||||
### Screenshots
|
||||
### Encrypted WebSocket connections (wss://)
|
||||
|
||||
Running in Chrome before and after connecting:
|
||||
To encrypt the traffic using the WebSocket 'wss://' URI scheme you
|
||||
need to generate a certificate for websockify to load. By default websockify
|
||||
loads a certificate file name `self.pem` but the `--cert=CERT` option can
|
||||
override the file name. You can generate a self-signed certificate using
|
||||
openssl. When asked for the common name, use the hostname of the server where
|
||||
the proxy will be running:
|
||||
|
||||
<img src="http://kanaka.github.com/noVNC/img/noVNC-1.jpg" width=400> <img src="http://kanaka.github.com/noVNC/img/noVNC-2.jpg" width=400>
|
||||
|
||||
See more screenshots <a href="http://kanaka.github.com/noVNC/screenshots.html">here</a>.
|
||||
```
|
||||
openssl req -new -x509 -days 365 -nodes -out self.pem -keyout self.pem
|
||||
```
|
||||
|
||||
|
||||
### Requirements
|
||||
|
||||
Unless you are using a VNC server with support for WebSockets
|
||||
connections (only my [fork of libvncserver](http://github.com/kanaka/libvncserver)
|
||||
currently), you need to use a WebSockets to TCP socket proxy. There is
|
||||
a python proxy included ('wsproxy'). One advantage of using the proxy
|
||||
is that it has builtin support for SSL/TLS encryption (i.e. "wss://").
|
||||
|
||||
There a few reasons why a proxy is required:
|
||||
|
||||
1. WebSockets is not a pure socket protocol. There is an initial HTTP
|
||||
like handshake to allow easy hand-off by web servers and allow
|
||||
some origin policy exchange. Also, each WebSockets frame begins
|
||||
with 0 ('\x00') and ends with 255 ('\xff').
|
||||
|
||||
2. Javascript itself does not have the ability to handle pure byte
|
||||
arrays. The python proxy encodes the data as base64 so that the
|
||||
Javascript client can decode the data as an integer array.
|
||||
### Websock Javascript library
|
||||
|
||||
|
||||
### Quick Start
|
||||
The `include/websock.js` Javascript library library provides a Websock
|
||||
object that is similar to the standard WebSocket object but Websock
|
||||
enables communication with raw TCP sockets (i.e. the binary stream)
|
||||
via websockify. This is accomplished by base64 encoding the data
|
||||
stream between Websock and websockify.
|
||||
|
||||
* Use the launch script to start a mini-webserver and the WebSockets
|
||||
proxy. The `--vnc` option is used to specify the location of
|
||||
a running VNC server:
|
||||
Websock has built-in receive queue buffering; the message event
|
||||
does not contain actual data but is simply a notification that
|
||||
there is new data available. Several rQ* methods are available to
|
||||
read binary data off of the receive queue.
|
||||
|
||||
`./utils/launch.sh --vnc localhost:5901`
|
||||
The Websock API is documented on the [websock.js API wiki page](https://github.com/kanaka/websockify/wiki/websock.js)
|
||||
|
||||
* Point your browser to the cut-and-paste URL that is output by the
|
||||
launch script. Enter a password if the VNC server has one
|
||||
configured. Hit the Connect button and enjoy!
|
||||
See the "Wrap a Program" section below for an example of using Websock
|
||||
and websockify as a browser telnet client (`wstelnet.html`).
|
||||
|
||||
|
||||
### Advanced usage
|
||||
### Additional websockify features
|
||||
|
||||
* To encrypt the traffic using the WebSocket 'wss://' URI scheme you
|
||||
need to generate a certificate for the proxy to load. By default the
|
||||
proxy loads a certificate file name `self.pem` but the `--cert=CERT`
|
||||
option can override the file name. You can generate a self-signed
|
||||
certificate using openssl. When asked for the common name, use the
|
||||
hostname of the server where the proxy will be running:
|
||||
These are not necessary for the basic operation.
|
||||
|
||||
`openssl req -new -x509 -days 365 -nodes -out self.pem -keyout self.pem`
|
||||
* Daemonizing: When the `-D` option is specified, websockify runs
|
||||
in the background as a daemon process.
|
||||
|
||||
* `tightvnc` provide a nice startup script that can be used to run
|
||||
a separate X desktop that is served by VNC. To install and run the
|
||||
server under Ubuntu you would do something like this:
|
||||
* SSL (the wss:// WebSockets URI): This is detected automatically by
|
||||
websockify by sniffing the first byte sent from the client and then
|
||||
wrapping the socket if the data starts with '\x16' or '\x80'
|
||||
(indicating SSL).
|
||||
|
||||
`sudo apt-get install tightvncserver`
|
||||
* Flash security policy: websockify detects flash security policy
|
||||
requests (again by sniffing the first packet) and answers with an
|
||||
appropriate flash security policy response (and then closes the
|
||||
port). This means no separate flash security policy server is needed
|
||||
for supporting the flash WebSockets fallback emulator.
|
||||
|
||||
`vncserver :1`
|
||||
* Session recording: This feature that allows recording of the traffic
|
||||
sent and received from the client to a file using the `--record`
|
||||
option.
|
||||
|
||||
The VNC server will run in the background. The port that it runs
|
||||
on is the display number + 5900 (i.e. 5901 in the case above).
|
||||
* Mini-webserver: websockify can detect and respond to normal web
|
||||
requests on the same port as the WebSockets proxy and Flash security
|
||||
policy. This functionality is activate with the `--web DIR` option
|
||||
where DIR is the root of the web directory to serve.
|
||||
|
||||
* `x11vnc` can be used to share your current X desktop. Note that if
|
||||
you run noVNC on the X desktop you are connecting to via VNC you
|
||||
will get a neat hall of mirrors effect, but the the client and
|
||||
server will fight over the mouse.
|
||||
|
||||
`sudo apt-get install x11vnc`
|
||||
|
||||
`x11vnc -forever -display :0`
|
||||
|
||||
Without the `-forever` option, x11vnc will exit after the first
|
||||
disconnect. The `-display` option indicates the exiting X display to
|
||||
share. The port that it runs on is the display number + 5900 (i.e.
|
||||
5900 in the case above).
|
||||
|
||||
* To run the python proxy directly without using launch script (to
|
||||
pass additional options for example):
|
||||
|
||||
`./utils/wsproxy.py -f source_port target_addr:target_port`
|
||||
|
||||
`./utils/wsproxy.py -f 8787 localhost:5901`
|
||||
|
||||
* To run the mini python web server without the launch script:
|
||||
|
||||
`./utils/web.py PORT`
|
||||
|
||||
`./utils/web.py 8080`
|
||||
|
||||
* Point your web browser at http://localhost:8080/vnc.html
|
||||
(or whatever port you used above to run the web server). Specify the
|
||||
host and port where the proxy is running and the password that the
|
||||
vnc server is using (if any). Hit the Connect button.
|
||||
* Wrap a program: see the "Wrap a Program" section below.
|
||||
|
||||
|
||||
### Browser Support
|
||||
### Implementations of websockify
|
||||
|
||||
In the following table Jaunty is Ubuntu 9.04 and WinXP is Windows XP.
|
||||
The primary implementation of websockify is in python. There are
|
||||
several alternate implementations in other languages (C, Node.js,
|
||||
Clojure, Ruby) in the `other/` subdirectory (with varying levels of
|
||||
functionality).
|
||||
|
||||
#### Linux (Ubuntu 9.04)
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<th>OS</th> <th>Browser</th>
|
||||
<th>Status</th>
|
||||
<th>Notes</th>
|
||||
</tr> <tr>
|
||||
<td>Jaunty</td> <td>Chrome 5.0.375.29</td>
|
||||
<td>Excellent</td>
|
||||
<td>Very fast. Native WebSockets.</td>
|
||||
</tr> <tr>
|
||||
<td>Jaunty</td> <td>Firefox 3.5</td>
|
||||
<td>Good</td>
|
||||
<td>Large full-color images are somewhat slow from web-socket-js overhead.</td>
|
||||
</tr> <tr>
|
||||
<td>Jaunty</td> <td>Firefox 3.0.17</td>
|
||||
<td>Fair</td>
|
||||
<td>Works fine but is slow.</td>
|
||||
</tr> <tr>
|
||||
<td>Jaunty</td> <td>Opera 10.60</td>
|
||||
<td>Poor</td>
|
||||
<td>web-socket-js problems, mouse/keyboard issues. See note 1</td>
|
||||
</tr> <tr>
|
||||
<td>Jaunty</td> <td>Arora 0.5</td>
|
||||
<td>Good</td>
|
||||
<td>Broken putImageData so large full-color images
|
||||
are slow. Uses web-socket-js.</td>
|
||||
</tr> <tr>
|
||||
<td>Jaunty</td> <td>Konqueror 4.2.2</td>
|
||||
<td><strong>Broken</strong></td>
|
||||
<td>web-socket-js never loads</td>
|
||||
</tr> <tr>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
</tr> <tr>
|
||||
<td>WinXP</td> <td>Chrome 5.0.375.99</td>
|
||||
<td>Excellent</td>
|
||||
<td>Very fast. Native WebSockets.</td>
|
||||
</tr> <tr>
|
||||
<td>WinXP</td> <td>Firefox 3.0.19</td>
|
||||
<td>Good</td>
|
||||
<td>Some overhead from web-socket-js.</td>
|
||||
</tr> <tr>
|
||||
<td>WinXP</td> <td>Safari 5.0</td>
|
||||
<td>Fair</td>
|
||||
<td>Fast. Native WebSockets. Broken 'wss://' (SSL) - weird client header</td>
|
||||
</tr> <tr>
|
||||
<td>WinXP</td> <td>IE 6, 7, 8</td>
|
||||
<td><strong>Non-starter</strong></td>
|
||||
<td>No basic Canvas support. Javascript painfully slow.</td>
|
||||
</tr>
|
||||
</table>
|
||||
In addition there are several other external projects that implement
|
||||
the websockify "protocol". See the alternate implementation [Feature
|
||||
Matrix](https://github.com/kanaka/websockify/wiki/Feature_Matrix) for
|
||||
more information.
|
||||
|
||||
|
||||
* Note 1: Opera interacts poorly with web-socket-js. After two
|
||||
disconnects the browser tab or Flash often hang. Although Javascript
|
||||
is faster than Firefox 3.5, the high variability of web-socket-js
|
||||
performance results in overall performance being lower. Middle mouse
|
||||
clicks and keyboard events need some work to work properly under
|
||||
Opera. Also, Opera does not have support for setting the cursor
|
||||
style url to a data URI scheme, so cursor pseudo-encoding is
|
||||
disabled.
|
||||
### Wrap a Program
|
||||
|
||||
In addition to proxying from a source address to a target address
|
||||
(which may be on a different system), websockify has the ability to
|
||||
launch a program on the local system and proxy WebSockets traffic to
|
||||
a normal TCP port owned/bound by the program.
|
||||
|
||||
The is accomplished with a small LD_PRELOAD library (`rebind.so`)
|
||||
which intercepts bind() system calls by the program. The specified
|
||||
port is moved to a new localhost/loopback free high port. websockify
|
||||
then proxies WebSockets traffic directed to the original port to the
|
||||
new (moved) port of the program.
|
||||
|
||||
The program wrap mode is invoked by replacing the target with `--`
|
||||
followed by the program command line to wrap.
|
||||
|
||||
`./run 2023 -- PROGRAM ARGS`
|
||||
|
||||
The `--wrap-mode` option can be used to indicate what action to take
|
||||
when the wrapped program exits or daemonizes.
|
||||
|
||||
Here is an example of using websockify to wrap the vncserver command
|
||||
(which backgrounds itself) for use with
|
||||
[noVNC](https://github.com/kanaka/noVNC):
|
||||
|
||||
`./run 5901 --wrap-mode=ignore -- vncserver -geometry 1024x768 :1`
|
||||
|
||||
Here is an example of wrapping telnetd (from krb5-telnetd). telnetd
|
||||
exits after the connection closes so the wrap mode is set to respawn
|
||||
the command:
|
||||
|
||||
`sudo ./run 2023 --wrap-mode=respawn -- telnetd -debug 2023`
|
||||
|
||||
The `wstelnet.html` page demonstrates a simple WebSockets based telnet
|
||||
client (use 'localhost' and '2023' for the host and port
|
||||
respectively).
|
||||
|
||||
|
||||
### Integration
|
||||
### Building the Python ssl module (for python 2.5 and older)
|
||||
|
||||
The client is designed to be easily integrated with existing web
|
||||
structure and style.
|
||||
* Install the build dependencies. On Ubuntu use this command:
|
||||
|
||||
At a minimum you must include the `vnc.js` and `default_controls.js`
|
||||
scripts and call DefaultControls.load(). For example:
|
||||
`sudo aptitude install python-dev bluetooth-dev`
|
||||
|
||||
<head>
|
||||
<script src='include/vnc.js'></script>
|
||||
<script src="include/default_controls.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div id='vnc'>Loading</div>
|
||||
* At the top level of the websockify repostory, download, build and
|
||||
symlink the ssl module:
|
||||
|
||||
<script>
|
||||
window.onload = function () {
|
||||
DefaultControls.load('vnc');
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
`wget --no-check-certificate http://pypi.python.org/packages/source/s/ssl/ssl-1.15.tar.gz`
|
||||
|
||||
See `vnc.html` and `vnc_auto.html` for examples. The file
|
||||
`include/plain.css` has a list of stylable elements.
|
||||
`tar xvzf ssl-1.15.tar.gz`
|
||||
|
||||
The `vnc.js` also includes other scripts within the `include`
|
||||
sub-directory. The `VNC_uri_prefix` variable can be use override the
|
||||
URL path to the `include` sub-directory.
|
||||
`cd ssl-1.15`
|
||||
|
||||
`make`
|
||||
|
||||
### Troubleshooting
|
||||
`cd ../`
|
||||
|
||||
You will need console logging support in the browser. Recent Chrome
|
||||
and Opera versions have built in support. Firefox has a nice extension
|
||||
called "firebug" that gives console logging support.
|
||||
`ln -sf ssl-1.15/build/lib.linux-*/ssl ssl`
|
||||
|
||||
First, load the noVNC page with `logging=debug` added to the query string.
|
||||
For example `vnc.html?logging=debug`.
|
||||
|
||||
Then, activate the console logger in your browser. With Chrome it can
|
||||
be activate using Ctrl+Shift+J and then switching to the "Console"
|
||||
tab. With firefox+firebug, it can be activated using Ctrl+F12.
|
||||
|
||||
Now reproduce the problem. The console log output will give more
|
||||
information about what is going wrong and where in the code the
|
||||
problem is located.
|
||||
|
||||
If you file a issue/bug, it is very helpful for me to have the last
|
||||
page of console output leading up the problem in the issue report.
|
||||
Other helpful issue/bug information: browser version, OS version,
|
||||
noVNC git version, and VNC server name/version.
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
-----------------------------------
|
||||
Windows noVNC Websockify Service
|
||||
-----------------------------------
|
||||
|
||||
The "noVNC Websocket Service.exe" file is a windows service wrapper created with Visual Studio 2010 to create a windows service to start stop the noVNC Websocket Server. All files used to create the wrapper can be found in 'noVNC Websocket Service Project' folder.
|
||||
|
||||
To download the precompiled executables please grab the zip in the downloads section of websockify project:
|
||||
https://github.com/kanaka/websockify
|
||||
|
||||
---------------------------
|
||||
Installation
|
||||
---------------------------
|
||||
|
||||
1. This service requires websockify.exe be in the same directory. Instructions on how to compile websockify python script as a windows executable can be found here:
|
||||
https://github.com/kanaka/websockify/wiki/Compiling-Websockify-as-Windows-Executable
|
||||
|
||||
2.To add this service to a Windows PC you need to run the commandline as administrator and then run this line:
|
||||
|
||||
sc create "noVNC Websocket Server" binPath= "PATH TO noVNC eg C:\noVNC\utils\Windows\Websocket Service.exe" DisplayName= "noVNC Websocket Server"
|
||||
|
||||
3 .Once this is run you will be able to access the service via Control Panel > Admin Tools > Services. In here you can specify whether you want the service to run automatically and start at stop the service.
|
||||
|
||||
---------------------------
|
||||
Configuration
|
||||
---------------------------
|
||||
The file noVNCConfig.ini must be in the same directory as "noVNC Websocket Service.exe".
|
||||
|
||||
This file contains a single line which is the websockify.exe statup arguements. An example is:
|
||||
192.168.0.1:5901 192.168.0.1:5900
|
||||
|
||||
All websockify supported arguements will work if added here.
|
||||
|
||||
---------------------------
|
||||
Deletion
|
||||
---------------------------
|
||||
|
||||
You can delete the service at any time by running the commandline as admin and using this command:
|
||||
sc delete "noVNC Websocket Server".
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.ServiceProcess;
|
||||
using System.Text;
|
||||
|
||||
namespace MELT_Command_Websocket
|
||||
{
|
||||
static class Program
|
||||
{
|
||||
/// <summary>
|
||||
/// The main entry point for the application.
|
||||
/// </summary>
|
||||
static void Main()
|
||||
{
|
||||
ServiceBase[] ServicesToRun;
|
||||
ServicesToRun = new ServiceBase[]
|
||||
{
|
||||
new Service1()
|
||||
};
|
||||
ServiceBase.Run(ServicesToRun);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
namespace MELT_Command_Websocket
|
||||
{
|
||||
partial class ProjectInstaller
|
||||
{
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
/// </summary>
|
||||
private System.ComponentModel.IContainer components = null;
|
||||
|
||||
/// <summary>
|
||||
/// Clean up any resources being used.
|
||||
/// </summary>
|
||||
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing && (components != null))
|
||||
{
|
||||
components.Dispose();
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#region Component Designer generated code
|
||||
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
this.serviceProcessInstaller1 = new System.ServiceProcess.ServiceProcessInstaller();
|
||||
this.serviceInstaller1 = new System.ServiceProcess.ServiceInstaller();
|
||||
//
|
||||
// serviceProcessInstaller1
|
||||
//
|
||||
this.serviceProcessInstaller1.Account = System.ServiceProcess.ServiceAccount.NetworkService;
|
||||
this.serviceProcessInstaller1.Installers.AddRange(new System.Configuration.Install.Installer[] {
|
||||
this.serviceInstaller1});
|
||||
this.serviceProcessInstaller1.Password = null;
|
||||
this.serviceProcessInstaller1.Username = null;
|
||||
//
|
||||
// serviceInstaller1
|
||||
//
|
||||
this.serviceInstaller1.Description = "noVNC Websocket Service";
|
||||
this.serviceInstaller1.DisplayName = "noVNC Websocket Service";
|
||||
this.serviceInstaller1.ServiceName = "noVNC Websocket Service";
|
||||
this.serviceInstaller1.StartType = System.ServiceProcess.ServiceStartMode.Automatic;
|
||||
//
|
||||
// ProjectInstaller
|
||||
//
|
||||
this.Installers.AddRange(new System.Configuration.Install.Installer[] {
|
||||
this.serviceProcessInstaller1});
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private System.ServiceProcess.ServiceProcessInstaller serviceProcessInstaller1;
|
||||
private System.ServiceProcess.ServiceInstaller serviceInstaller1;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Configuration.Install;
|
||||
using System.Linq;
|
||||
|
||||
|
||||
namespace MELT_Command_Websocket
|
||||
{
|
||||
[RunInstaller(true)]
|
||||
public partial class ProjectInstaller : System.Configuration.Install.Installer
|
||||
{
|
||||
public ProjectInstaller()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,129 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<metadata name="serviceProcessInstaller1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>17, 56</value>
|
||||
</metadata>
|
||||
<metadata name="serviceInstaller1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>196, 17</value>
|
||||
</metadata>
|
||||
<metadata name="$this.TrayLargeIcon" type="System.Boolean, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</metadata>
|
||||
</root>
|
||||
@@ -0,0 +1,36 @@
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyTitle("MELT Command Websocket")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("Microsoft")]
|
||||
[assembly: AssemblyProduct("MELT Command Websocket")]
|
||||
[assembly: AssemblyCopyright("Copyright © Microsoft 2011")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// Setting ComVisible to false makes the types in this assembly not visible
|
||||
// to COM components. If you need to access a type in this assembly from
|
||||
// COM, set the ComVisible attribute to true on that type.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||
[assembly: Guid("5ab831cb-6852-4ce1-849c-b26725b0e10b")]
|
||||
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
||||
@@ -0,0 +1,37 @@
|
||||
namespace MELT_Command_Websocket
|
||||
{
|
||||
partial class Service1
|
||||
{
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
/// </summary>
|
||||
private System.ComponentModel.IContainer components = null;
|
||||
|
||||
/// <summary>
|
||||
/// Clean up any resources being used.
|
||||
/// </summary>
|
||||
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing && (components != null))
|
||||
{
|
||||
components.Dispose();
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#region Component Designer generated code
|
||||
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
components = new System.ComponentModel.Container();
|
||||
this.ServiceName = "Service1";
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Data;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.ServiceProcess;
|
||||
using System.Text;
|
||||
using System.IO;
|
||||
|
||||
namespace MELT_Command_Websocket
|
||||
{
|
||||
public partial class Service1 : ServiceBase
|
||||
{
|
||||
Process websockify;
|
||||
public Service1()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
protected override void OnStart(string[] args)
|
||||
{
|
||||
|
||||
string configpath = AppDomain.CurrentDomain.BaseDirectory + "\\noVNCConfig.ini";
|
||||
string sockifypath = AppDomain.CurrentDomain.BaseDirectory + "\\websockify.exe";
|
||||
//Load commandline arguements from config file.
|
||||
StreamReader streamReader = new StreamReader(configpath);
|
||||
string arguements = streamReader.ReadLine();
|
||||
streamReader.Close();
|
||||
|
||||
//Start websockify.
|
||||
websockify = System.Diagnostics.Process.Start(sockifypath, arguements);
|
||||
}
|
||||
|
||||
protected override void OnStop()
|
||||
{
|
||||
//Service stopped. Close websockify.
|
||||
websockify.Kill();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">x86</Platform>
|
||||
<ProductVersion>8.0.30703</ProductVersion>
|
||||
<SchemaVersion>2.0</SchemaVersion>
|
||||
<ProjectGuid>{6B86AE7B-6BBD-4E74-8802-5995E8B6D27D}</ProjectGuid>
|
||||
<OutputType>WinExe</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>noVNC_Websocket_Service</RootNamespace>
|
||||
<AssemblyName>noVNC Websocket Service</AssemblyName>
|
||||
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Configuration.Install" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Management" />
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
<Reference Include="System.Data.DataSetExtensions" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.ServiceProcess" />
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="ProjectInstaller.cs">
|
||||
<SubType>Component</SubType>
|
||||
</Compile>
|
||||
<Compile Include="ProjectInstaller.Designer.cs">
|
||||
<DependentUpon>ProjectInstaller.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Service1.cs">
|
||||
<SubType>Component</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Service1.Designer.cs">
|
||||
<DependentUpon>Service1.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Program.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Include="ProjectInstaller.resx">
|
||||
<DependentUpon>ProjectInstaller.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
</Target>
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
</Project>
|
||||
@@ -0,0 +1,20 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 11.00
|
||||
# Visual Studio 2010
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "noVNC Websocket", "noVNC Websocket.csproj", "{6B86AE7B-6BBD-4E74-8802-5995E8B6D27D}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|x86 = Debug|x86
|
||||
Release|x86 = Release|x86
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{6B86AE7B-6BBD-4E74-8802-5995E8B6D27D}.Debug|x86.ActiveCfg = Debug|x86
|
||||
{6B86AE7B-6BBD-4E74-8802-5995E8B6D27D}.Debug|x86.Build.0 = Debug|x86
|
||||
{6B86AE7B-6BBD-4E74-8802-5995E8B6D27D}.Release|x86.ActiveCfg = Release|x86
|
||||
{6B86AE7B-6BBD-4E74-8802-5995E8B6D27D}.Release|x86.Build.0 = Release|x86
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
@@ -0,0 +1,373 @@
|
||||
Mozilla Public License Version 2.0
|
||||
==================================
|
||||
|
||||
1. Definitions
|
||||
--------------
|
||||
|
||||
1.1. "Contributor"
|
||||
means each individual or legal entity that creates, contributes to
|
||||
the creation of, or owns Covered Software.
|
||||
|
||||
1.2. "Contributor Version"
|
||||
means the combination of the Contributions of others (if any) used
|
||||
by a Contributor and that particular Contributor's Contribution.
|
||||
|
||||
1.3. "Contribution"
|
||||
means Covered Software of a particular Contributor.
|
||||
|
||||
1.4. "Covered Software"
|
||||
means Source Code Form to which the initial Contributor has attached
|
||||
the notice in Exhibit A, the Executable Form of such Source Code
|
||||
Form, and Modifications of such Source Code Form, in each case
|
||||
including portions thereof.
|
||||
|
||||
1.5. "Incompatible With Secondary Licenses"
|
||||
means
|
||||
|
||||
(a) that the initial Contributor has attached the notice described
|
||||
in Exhibit B to the Covered Software; or
|
||||
|
||||
(b) that the Covered Software was made available under the terms of
|
||||
version 1.1 or earlier of the License, but not also under the
|
||||
terms of a Secondary License.
|
||||
|
||||
1.6. "Executable Form"
|
||||
means any form of the work other than Source Code Form.
|
||||
|
||||
1.7. "Larger Work"
|
||||
means a work that combines Covered Software with other material, in
|
||||
a separate file or files, that is not Covered Software.
|
||||
|
||||
1.8. "License"
|
||||
means this document.
|
||||
|
||||
1.9. "Licensable"
|
||||
means having the right to grant, to the maximum extent possible,
|
||||
whether at the time of the initial grant or subsequently, any and
|
||||
all of the rights conveyed by this License.
|
||||
|
||||
1.10. "Modifications"
|
||||
means any of the following:
|
||||
|
||||
(a) any file in Source Code Form that results from an addition to,
|
||||
deletion from, or modification of the contents of Covered
|
||||
Software; or
|
||||
|
||||
(b) any new file in Source Code Form that contains any Covered
|
||||
Software.
|
||||
|
||||
1.11. "Patent Claims" of a Contributor
|
||||
means any patent claim(s), including without limitation, method,
|
||||
process, and apparatus claims, in any patent Licensable by such
|
||||
Contributor that would be infringed, but for the grant of the
|
||||
License, by the making, using, selling, offering for sale, having
|
||||
made, import, or transfer of either its Contributions or its
|
||||
Contributor Version.
|
||||
|
||||
1.12. "Secondary License"
|
||||
means either the GNU General Public License, Version 2.0, the GNU
|
||||
Lesser General Public License, Version 2.1, the GNU Affero General
|
||||
Public License, Version 3.0, or any later versions of those
|
||||
licenses.
|
||||
|
||||
1.13. "Source Code Form"
|
||||
means the form of the work preferred for making modifications.
|
||||
|
||||
1.14. "You" (or "Your")
|
||||
means an individual or a legal entity exercising rights under this
|
||||
License. For legal entities, "You" includes any entity that
|
||||
controls, is controlled by, or is under common control with You. For
|
||||
purposes of this definition, "control" means (a) the power, direct
|
||||
or indirect, to cause the direction or management of such entity,
|
||||
whether by contract or otherwise, or (b) ownership of more than
|
||||
fifty percent (50%) of the outstanding shares or beneficial
|
||||
ownership of such entity.
|
||||
|
||||
2. License Grants and Conditions
|
||||
--------------------------------
|
||||
|
||||
2.1. Grants
|
||||
|
||||
Each Contributor hereby grants You a world-wide, royalty-free,
|
||||
non-exclusive license:
|
||||
|
||||
(a) under intellectual property rights (other than patent or trademark)
|
||||
Licensable by such Contributor to use, reproduce, make available,
|
||||
modify, display, perform, distribute, and otherwise exploit its
|
||||
Contributions, either on an unmodified basis, with Modifications, or
|
||||
as part of a Larger Work; and
|
||||
|
||||
(b) under Patent Claims of such Contributor to make, use, sell, offer
|
||||
for sale, have made, import, and otherwise transfer either its
|
||||
Contributions or its Contributor Version.
|
||||
|
||||
2.2. Effective Date
|
||||
|
||||
The licenses granted in Section 2.1 with respect to any Contribution
|
||||
become effective for each Contribution on the date the Contributor first
|
||||
distributes such Contribution.
|
||||
|
||||
2.3. Limitations on Grant Scope
|
||||
|
||||
The licenses granted in this Section 2 are the only rights granted under
|
||||
this License. No additional rights or licenses will be implied from the
|
||||
distribution or licensing of Covered Software under this License.
|
||||
Notwithstanding Section 2.1(b) above, no patent license is granted by a
|
||||
Contributor:
|
||||
|
||||
(a) for any code that a Contributor has removed from Covered Software;
|
||||
or
|
||||
|
||||
(b) for infringements caused by: (i) Your and any other third party's
|
||||
modifications of Covered Software, or (ii) the combination of its
|
||||
Contributions with other software (except as part of its Contributor
|
||||
Version); or
|
||||
|
||||
(c) under Patent Claims infringed by Covered Software in the absence of
|
||||
its Contributions.
|
||||
|
||||
This License does not grant any rights in the trademarks, service marks,
|
||||
or logos of any Contributor (except as may be necessary to comply with
|
||||
the notice requirements in Section 3.4).
|
||||
|
||||
2.4. Subsequent Licenses
|
||||
|
||||
No Contributor makes additional grants as a result of Your choice to
|
||||
distribute the Covered Software under a subsequent version of this
|
||||
License (see Section 10.2) or under the terms of a Secondary License (if
|
||||
permitted under the terms of Section 3.3).
|
||||
|
||||
2.5. Representation
|
||||
|
||||
Each Contributor represents that the Contributor believes its
|
||||
Contributions are its original creation(s) or it has sufficient rights
|
||||
to grant the rights to its Contributions conveyed by this License.
|
||||
|
||||
2.6. Fair Use
|
||||
|
||||
This License is not intended to limit any rights You have under
|
||||
applicable copyright doctrines of fair use, fair dealing, or other
|
||||
equivalents.
|
||||
|
||||
2.7. Conditions
|
||||
|
||||
Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted
|
||||
in Section 2.1.
|
||||
|
||||
3. Responsibilities
|
||||
-------------------
|
||||
|
||||
3.1. Distribution of Source Form
|
||||
|
||||
All distribution of Covered Software in Source Code Form, including any
|
||||
Modifications that You create or to which You contribute, must be under
|
||||
the terms of this License. You must inform recipients that the Source
|
||||
Code Form of the Covered Software is governed by the terms of this
|
||||
License, and how they can obtain a copy of this License. You may not
|
||||
attempt to alter or restrict the recipients' rights in the Source Code
|
||||
Form.
|
||||
|
||||
3.2. Distribution of Executable Form
|
||||
|
||||
If You distribute Covered Software in Executable Form then:
|
||||
|
||||
(a) such Covered Software must also be made available in Source Code
|
||||
Form, as described in Section 3.1, and You must inform recipients of
|
||||
the Executable Form how they can obtain a copy of such Source Code
|
||||
Form by reasonable means in a timely manner, at a charge no more
|
||||
than the cost of distribution to the recipient; and
|
||||
|
||||
(b) You may distribute such Executable Form under the terms of this
|
||||
License, or sublicense it under different terms, provided that the
|
||||
license for the Executable Form does not attempt to limit or alter
|
||||
the recipients' rights in the Source Code Form under this License.
|
||||
|
||||
3.3. Distribution of a Larger Work
|
||||
|
||||
You may create and distribute a Larger Work under terms of Your choice,
|
||||
provided that You also comply with the requirements of this License for
|
||||
the Covered Software. If the Larger Work is a combination of Covered
|
||||
Software with a work governed by one or more Secondary Licenses, and the
|
||||
Covered Software is not Incompatible With Secondary Licenses, this
|
||||
License permits You to additionally distribute such Covered Software
|
||||
under the terms of such Secondary License(s), so that the recipient of
|
||||
the Larger Work may, at their option, further distribute the Covered
|
||||
Software under the terms of either this License or such Secondary
|
||||
License(s).
|
||||
|
||||
3.4. Notices
|
||||
|
||||
You may not remove or alter the substance of any license notices
|
||||
(including copyright notices, patent notices, disclaimers of warranty,
|
||||
or limitations of liability) contained within the Source Code Form of
|
||||
the Covered Software, except that You may alter any license notices to
|
||||
the extent required to remedy known factual inaccuracies.
|
||||
|
||||
3.5. Application of Additional Terms
|
||||
|
||||
You may choose to offer, and to charge a fee for, warranty, support,
|
||||
indemnity or liability obligations to one or more recipients of Covered
|
||||
Software. However, You may do so only on Your own behalf, and not on
|
||||
behalf of any Contributor. You must make it absolutely clear that any
|
||||
such warranty, support, indemnity, or liability obligation is offered by
|
||||
You alone, and You hereby agree to indemnify every Contributor for any
|
||||
liability incurred by such Contributor as a result of warranty, support,
|
||||
indemnity or liability terms You offer. You may include additional
|
||||
disclaimers of warranty and limitations of liability specific to any
|
||||
jurisdiction.
|
||||
|
||||
4. Inability to Comply Due to Statute or Regulation
|
||||
---------------------------------------------------
|
||||
|
||||
If it is impossible for You to comply with any of the terms of this
|
||||
License with respect to some or all of the Covered Software due to
|
||||
statute, judicial order, or regulation then You must: (a) comply with
|
||||
the terms of this License to the maximum extent possible; and (b)
|
||||
describe the limitations and the code they affect. Such description must
|
||||
be placed in a text file included with all distributions of the Covered
|
||||
Software under this License. Except to the extent prohibited by statute
|
||||
or regulation, such description must be sufficiently detailed for a
|
||||
recipient of ordinary skill to be able to understand it.
|
||||
|
||||
5. Termination
|
||||
--------------
|
||||
|
||||
5.1. The rights granted under this License will terminate automatically
|
||||
if You fail to comply with any of its terms. However, if You become
|
||||
compliant, then the rights granted under this License from a particular
|
||||
Contributor are reinstated (a) provisionally, unless and until such
|
||||
Contributor explicitly and finally terminates Your grants, and (b) on an
|
||||
ongoing basis, if such Contributor fails to notify You of the
|
||||
non-compliance by some reasonable means prior to 60 days after You have
|
||||
come back into compliance. Moreover, Your grants from a particular
|
||||
Contributor are reinstated on an ongoing basis if such Contributor
|
||||
notifies You of the non-compliance by some reasonable means, this is the
|
||||
first time You have received notice of non-compliance with this License
|
||||
from such Contributor, and You become compliant prior to 30 days after
|
||||
Your receipt of the notice.
|
||||
|
||||
5.2. If You initiate litigation against any entity by asserting a patent
|
||||
infringement claim (excluding declaratory judgment actions,
|
||||
counter-claims, and cross-claims) alleging that a Contributor Version
|
||||
directly or indirectly infringes any patent, then the rights granted to
|
||||
You by any and all Contributors for the Covered Software under Section
|
||||
2.1 of this License shall terminate.
|
||||
|
||||
5.3. In the event of termination under Sections 5.1 or 5.2 above, all
|
||||
end user license agreements (excluding distributors and resellers) which
|
||||
have been validly granted by You or Your distributors under this License
|
||||
prior to termination shall survive termination.
|
||||
|
||||
************************************************************************
|
||||
* *
|
||||
* 6. Disclaimer of Warranty *
|
||||
* ------------------------- *
|
||||
* *
|
||||
* Covered Software is provided under this License on an "as is" *
|
||||
* basis, without warranty of any kind, either expressed, implied, or *
|
||||
* statutory, including, without limitation, warranties that the *
|
||||
* Covered Software is free of defects, merchantable, fit for a *
|
||||
* particular purpose or non-infringing. The entire risk as to the *
|
||||
* quality and performance of the Covered Software is with You. *
|
||||
* Should any Covered Software prove defective in any respect, You *
|
||||
* (not any Contributor) assume the cost of any necessary servicing, *
|
||||
* repair, or correction. This disclaimer of warranty constitutes an *
|
||||
* essential part of this License. No use of any Covered Software is *
|
||||
* authorized under this License except under this disclaimer. *
|
||||
* *
|
||||
************************************************************************
|
||||
|
||||
************************************************************************
|
||||
* *
|
||||
* 7. Limitation of Liability *
|
||||
* -------------------------- *
|
||||
* *
|
||||
* Under no circumstances and under no legal theory, whether tort *
|
||||
* (including negligence), contract, or otherwise, shall any *
|
||||
* Contributor, or anyone who distributes Covered Software as *
|
||||
* permitted above, be liable to You for any direct, indirect, *
|
||||
* special, incidental, or consequential damages of any character *
|
||||
* including, without limitation, damages for lost profits, loss of *
|
||||
* goodwill, work stoppage, computer failure or malfunction, or any *
|
||||
* and all other commercial damages or losses, even if such party *
|
||||
* shall have been informed of the possibility of such damages. This *
|
||||
* limitation of liability shall not apply to liability for death or *
|
||||
* personal injury resulting from such party's negligence to the *
|
||||
* extent applicable law prohibits such limitation. Some *
|
||||
* jurisdictions do not allow the exclusion or limitation of *
|
||||
* incidental or consequential damages, so this exclusion and *
|
||||
* limitation may not apply to You. *
|
||||
* *
|
||||
************************************************************************
|
||||
|
||||
8. Litigation
|
||||
-------------
|
||||
|
||||
Any litigation relating to this License may be brought only in the
|
||||
courts of a jurisdiction where the defendant maintains its principal
|
||||
place of business and such litigation shall be governed by laws of that
|
||||
jurisdiction, without reference to its conflict-of-law provisions.
|
||||
Nothing in this Section shall prevent a party's ability to bring
|
||||
cross-claims or counter-claims.
|
||||
|
||||
9. Miscellaneous
|
||||
----------------
|
||||
|
||||
This License represents the complete agreement concerning the subject
|
||||
matter hereof. If any provision of this License is held to be
|
||||
unenforceable, such provision shall be reformed only to the extent
|
||||
necessary to make it enforceable. Any law or regulation which provides
|
||||
that the language of a contract shall be construed against the drafter
|
||||
shall not be used to construe this License against a Contributor.
|
||||
|
||||
10. Versions of the License
|
||||
---------------------------
|
||||
|
||||
10.1. New Versions
|
||||
|
||||
Mozilla Foundation is the license steward. Except as provided in Section
|
||||
10.3, no one other than the license steward has the right to modify or
|
||||
publish new versions of this License. Each version will be given a
|
||||
distinguishing version number.
|
||||
|
||||
10.2. Effect of New Versions
|
||||
|
||||
You may distribute the Covered Software under the terms of the version
|
||||
of the License under which You originally received the Covered Software,
|
||||
or under the terms of any subsequent version published by the license
|
||||
steward.
|
||||
|
||||
10.3. Modified Versions
|
||||
|
||||
If you create software not governed by this License, and you want to
|
||||
create a new license for such software, you may create and use a
|
||||
modified version of this License if you rename the license and remove
|
||||
any references to the name of the license steward (except to note that
|
||||
such modified license differs from this License).
|
||||
|
||||
10.4. Distributing Source Code Form that is Incompatible With Secondary
|
||||
Licenses
|
||||
|
||||
If You choose to distribute Source Code Form that is Incompatible With
|
||||
Secondary Licenses under the terms of this version of the License, the
|
||||
notice described in Exhibit B of this License must be attached.
|
||||
|
||||
Exhibit A - Source Code Form License Notice
|
||||
-------------------------------------------
|
||||
|
||||
This Source Code Form is subject to the terms of the Mozilla Public
|
||||
License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
If it is not possible or desirable to put the notice in a particular
|
||||
file, then You may include the notice in a location (such as a LICENSE
|
||||
file in a relevant directory) where a recipient would be likely to look
|
||||
for such a notice.
|
||||
|
||||
You may add additional accurate notices of copyright ownership.
|
||||
|
||||
Exhibit B - "Incompatible With Secondary Licenses" Notice
|
||||
---------------------------------------------------------
|
||||
|
||||
This Source Code Form is "Incompatible With Secondary Licenses", as
|
||||
defined by the Mozilla Public License, v. 2.0.
|
||||
@@ -1,51 +1,6 @@
|
||||
Short Term:
|
||||
|
||||
- Proper Javascript namespacing for Canvas and RFB (using function for
|
||||
true local variables and functions).
|
||||
|
||||
- Timing delta between frames in proxy record log, for playback
|
||||
support (for demo and test).
|
||||
|
||||
- Playback/demo on website.
|
||||
|
||||
- Test on IE 9 preview 3.
|
||||
|
||||
- Fix cursor URI detection in Arora:
|
||||
- allows data URI, but doesn't actually work
|
||||
|
||||
|
||||
Medium Term:
|
||||
|
||||
- Viewport support
|
||||
|
||||
- Status bar menu/buttons:
|
||||
- Explanatory hover text over buttons
|
||||
|
||||
- Configuration menu:
|
||||
- Tunable: speed vs. bandwidth selection
|
||||
- Tunable: CPU use versus latency.
|
||||
- shared mode
|
||||
- Scaling
|
||||
|
||||
- Keyboard menu:
|
||||
- Ctrl Lock, Alt Lock, SysRq Lock
|
||||
- Highlight menu icon when keys are locked
|
||||
|
||||
- Clipboard button -> popup:
|
||||
- text, clear and send buttons
|
||||
|
||||
|
||||
Longer Term:
|
||||
|
||||
- Implement UI option for VNC shared mode.
|
||||
|
||||
- Get web-socket-js RFC2817 proxying working again.
|
||||
|
||||
- Implement tight and ZRLE encoding
|
||||
|
||||
- Support for Spice protocol.
|
||||
|
||||
- Consider RDP protocol.
|
||||
|
||||
- Consider NX protocol.
|
||||
- Go implementation
|
||||
- Rust implementation
|
||||
- Add sub-protocol support to upstream einaros/ws module and use that
|
||||
instead of the patched module.
|
||||
- wstelnet: support CSI L and CSI M
|
||||
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
Manual setup:
|
||||
|
||||
DATA="echo \'<cross-domain-policy><allow-access-from domain=\\\"*\\\" to-ports=\\\"*\\\" /></cross-domain-policy>\'"
|
||||
/usr/bin/socat -T 1 TCP-L:843,reuseaddr,fork,crlf SYSTEM:"$DATA"
|
||||
@@ -0,0 +1,114 @@
|
||||
This data is raw copy from the latency tester set to send a frame with
|
||||
a little over 2000 KB of data every 10ms.
|
||||
|
||||
The number of packets sent and received is just a visual counter and
|
||||
is just the total when I chose to stop the test (around 3000 or so
|
||||
packets).
|
||||
|
||||
The latency measure are from the point the packet was sent to when it
|
||||
was received back again in milliseconds. One notable data point
|
||||
missing from this is how long it actually took for the client to send
|
||||
3000 packets because sending large packets can put load on the browser
|
||||
and it may be a lot longer than 10ms before the timer event to
|
||||
send the next packet fires. So even with low latency numbers, the
|
||||
actual send rate may be fairly low because sending the WebSockets
|
||||
frames is impacting the performance of the browser in general.
|
||||
|
||||
|
||||
------------------------------------------------------------
|
||||
|
||||
Native WebSockets implementations, 2000 byte payload, 10ms delay
|
||||
|
||||
Chrome 8.0.552 - native WebSockets
|
||||
Packets sent: 2998
|
||||
Packets Received: 2998
|
||||
Average Latency: 1.84
|
||||
40 Frame Running Average Latency: 1.90
|
||||
Minimum Latency: 1.00
|
||||
Maximum Latency: 10.00
|
||||
|
||||
firefox 4.0b9 - WebSockets enabled
|
||||
Packets sent: 3011
|
||||
Packets Received: 3011
|
||||
Average Latency: 6.45
|
||||
40 Frame Running Average Latency: 6.08
|
||||
Minimum Latency: 5.00
|
||||
Maximum Latency: 119.00
|
||||
|
||||
Opera 11 - WebSockets enabled
|
||||
Packets sent: 3065
|
||||
Packets Received: 3064
|
||||
Average Latency: 9.56
|
||||
40 Frame Running Average Latency: 8.15
|
||||
Minimum Latency: 4.00
|
||||
Maximum Latency: 53.00
|
||||
|
||||
------------------------------------------------------------
|
||||
|
||||
New web-socket-js (20f837425d4), 2000 byte payload, 10ms delay
|
||||
|
||||
firefox 4.0b9 - no WebSockets
|
||||
Packets sent: 3088
|
||||
Packets Received: 3087
|
||||
Average Latency: 16.71
|
||||
40 Frame Running Average Latency: 16.80
|
||||
Minimum Latency: 7.00
|
||||
Maximum Latency: 75.00
|
||||
|
||||
- First 1000 sent in 13 seconds
|
||||
- Second 1000 sent in 12 seconds
|
||||
- Third 1000 sent in 12 seconds
|
||||
|
||||
firefox 3.6.10 - no WebSockets
|
||||
Packets sent: 3100
|
||||
Packets Received: 3099
|
||||
Average Latency: 17.32
|
||||
40 Frame Running Average Latency: 16.73
|
||||
Minimum Latency: 6.00
|
||||
Maximum Latency: 72.00
|
||||
|
||||
Opera 11 - no WebSockets
|
||||
Packets sent: 3007
|
||||
Packets Received: 3007
|
||||
Average Latency: 465.91
|
||||
40 Frame Running Average Latency: 147.95
|
||||
Minimum Latency: 12.00
|
||||
Maximum Latency: 9143.00
|
||||
|
||||
- average starts at around 28ms
|
||||
- time for each 500 packets: 13s, 16s, 25s, 37s, 50s, 72s
|
||||
- also start seeing sent, receive lags around 1200 packets
|
||||
|
||||
---------------------------------------------------------------
|
||||
|
||||
Old web-socket-js (9e7663771), 2000 byte payload, 10ms delay
|
||||
|
||||
firefox 4.0b9 - no WebSockets
|
||||
Packets sent: 3024
|
||||
Packets Received: 3020
|
||||
Average Latency: 80.59
|
||||
40 Frame Running Average Latency: 60.15
|
||||
Minimum Latency: 10.00
|
||||
Maximm Latency: 348.00
|
||||
|
||||
|
||||
firefox 3.6.10 - no WebSockets
|
||||
Packets sent: 2777
|
||||
Packets Received: 2775
|
||||
Average Latency: 34.89
|
||||
40 Frame Running Average Latency: 24.50
|
||||
Minimum Latency: 10.00
|
||||
Maximum Latency: 208.00
|
||||
|
||||
|
||||
Opera 11 - no Websockets
|
||||
Packets sent: 3012
|
||||
Packets Received: 3011
|
||||
Average Latency: 380.87
|
||||
40 Frame Running Average Latency: 341.90
|
||||
Minimum Latency: 28.00
|
||||
Maximum Latency: 2175.00
|
||||
|
||||
- average starts at around 290ms
|
||||
- time for each 1000 packets: 23s, 38s, 65s
|
||||
|
||||
-66
@@ -1,66 +0,0 @@
|
||||
New tight PNG protocol:
|
||||
http://wiki.qemu.org/VNC_Tight_PNG
|
||||
http://xf.iksaif.net/blog/index.php?post/2010/06/14/QEMU:-Tight-PNG-and-some-profiling
|
||||
|
||||
RFB protocol and extensions:
|
||||
http://tigervnc.org/cgi-bin/rfbproto
|
||||
|
||||
Canvas Browser Compatibility:
|
||||
http://philip.html5.org/tests/canvas/suite/tests/results.html
|
||||
|
||||
WebSockets API standard:
|
||||
http://www.whatwg.org/specs/web-apps/current-work/complete.html#websocket
|
||||
http://dev.w3.org/html5/websockets/
|
||||
http://www.ietf.org/id/draft-ietf-hybi-thewebsocketprotocol-00.txt
|
||||
|
||||
Browser Keyboard Events detailed:
|
||||
http://unixpapa.com/js/key.html
|
||||
|
||||
ActionScript (Flash) WebSocket implementation:
|
||||
http://github.com/gimite/web-socket-js
|
||||
|
||||
ActionScript (Flash) crypto/TLS library:
|
||||
http://code.google.com/p/as3crypto
|
||||
http://github.com/lyokato/as3crypto_patched
|
||||
|
||||
TLS Protocol:
|
||||
http://en.wikipedia.org/wiki/Transport_Layer_Security
|
||||
|
||||
Generate self-signed certificate:
|
||||
http://docs.python.org/dev/library/ssl.html#certificates
|
||||
|
||||
Cursor appearance/style (for Cursor pseudo-encoding):
|
||||
http://en.wikipedia.org/wiki/ICO_(file_format)
|
||||
http://www.daubnet.com/en/file-format-cur
|
||||
https://developer.mozilla.org/en/Using_URL_values_for_the_cursor_property
|
||||
|
||||
|
||||
Related projects:
|
||||
|
||||
guacamole: http://guacamole.sourceforge.net/
|
||||
|
||||
- Web client, but Java servlet does pre-processing
|
||||
|
||||
jsvnc: http://code.google.com/p/jsvnc/
|
||||
|
||||
- No releases
|
||||
|
||||
webvnc: http://code.google.com/p/webvnc/
|
||||
|
||||
- Jetty web server gateway, no updates since April 2008.
|
||||
|
||||
RealVNC Java applet: http://www.realvnc.com/support/javavncviewer.html
|
||||
|
||||
- Java applet
|
||||
|
||||
Flashlight-VNC: http://www.wizhelp.com/flashlight-vnc/
|
||||
|
||||
- Adobe Flash implementation
|
||||
|
||||
FVNC: http://osflash.org/fvnc
|
||||
|
||||
- Adbove Flash implementation
|
||||
|
||||
CanVNC: http://canvnc.sourceforge.net/
|
||||
|
||||
- HTML client with REST to VNC python proxy. Mostly vapor.
|
||||
+14
-34
@@ -4,41 +4,21 @@ There is an included flash object (web-socket-js) that is used to
|
||||
emulate websocket support on browsers without websocket support
|
||||
(currently only Chrome has WebSocket support).
|
||||
|
||||
The performance on Chrome is great. It only takes about 150ms on my
|
||||
system to render a complete 800x600 hextile frame. Most updates are
|
||||
partial or use copyrect which is much faster.
|
||||
|
||||
When using the flash websocket emulator, packets event aren't always
|
||||
delivered in order. This may be a bug in the way I'm using the
|
||||
FABridge interface. Or a bug in FABridge itself, or just a browser
|
||||
event delivery issue. Anyways, to get around this problem, when the
|
||||
flash emulator is being used, the client issues the WebSocket GET
|
||||
request with the "seq_num" variable. This switches on in-band sequence
|
||||
numbering of the packets in the proxy, and the client has a queue of
|
||||
out-of-order packets (20 deep currently) that it uses to re-order.
|
||||
Gross!
|
||||
|
||||
The performance on firefox 3.5 is usable. It takes 2.3 seconds to
|
||||
render a 800x600 hextile frame on my system (the initial connect).
|
||||
Once the initial first update is done though, it's quite usable (as
|
||||
above, most updates are partial or copyrect). I haven't tested firefox
|
||||
3.7 yet, it might be a lot faster.
|
||||
|
||||
Opera sucks big time. The flash websocket emulator fails to deliver as
|
||||
many as 40% of packet events when used on Opera. It may or not be
|
||||
Opera's fault, but something goes badly wrong at the FABridge
|
||||
boundary.
|
||||
|
||||
Javascript doesn't have a bytearray type, so what you get out of
|
||||
a WebSocket object is just Javascript strings. I believe that
|
||||
Javascript has UTF-16 unicode strings and anything sent through the
|
||||
WebSocket gets converted to UTF-8 and vice-versa. So, one additional
|
||||
(and necessary) function of the proxy is base64 encoding/decoding what
|
||||
is sent to/from the browser. Another option that I want to explore is
|
||||
UTF-8 encoding in the proxy.
|
||||
|
||||
a WebSocket object is just Javascript strings. Javascript has UTF-16
|
||||
unicode strings and anything sent through the WebSocket gets converted
|
||||
to UTF-8 and vice-versa. So, one additional (and necessary) function
|
||||
of wsproxy is base64 encoding/decoding what is sent to/from the
|
||||
browser.
|
||||
|
||||
Building web-socket-js emulator:
|
||||
|
||||
cd include/web-socket-js/flash-src
|
||||
mxmlc -static-link-runtime-shared-libraries WebSocketMain.as
|
||||
cd include/web-socket-js/flash-src
|
||||
mxmlc -static-link-runtime-shared-libraries WebSocketMain.as
|
||||
|
||||
Building release tarball:
|
||||
- not really necessary since tagged revision can be downloaded
|
||||
from github as tarballs
|
||||
|
||||
git archive --format=tar --prefix=websockify-${WVER}/ v${WVER} > websockify-${WVER}.tar
|
||||
gzip websockify-${WVER}.tar
|
||||
|
||||
@@ -1,67 +0,0 @@
|
||||
Description of the WebSockets to TCP Proxy
|
||||
|
||||
|
||||
At the most basic level, the proxy just translates WebSockets traffic
|
||||
to normal socket traffic. The proxy accepts the WebSockets header,
|
||||
parses it, and then begins forwarding traffic between the client and
|
||||
the target in both directions. At a minimum the proxy needs to base64
|
||||
encode traffic destined for the client and decode it coming from the
|
||||
client. Also, WebSockets traffic starts with '\0' (0) and ends with
|
||||
'\xff' (255) so that needs to be added/stripped by the proxy. There
|
||||
is a little bit of buffering you need to do in case the data from the
|
||||
client isn't a full WebSockets frame (i.e. doesn't end in 255).
|
||||
|
||||
|
||||
Other proxy features (that aren't necessary for the basic operation):
|
||||
|
||||
|
||||
SSL (the wss:// WebSockets URI):
|
||||
|
||||
This is detected automatically by the proxy by sniffing the first byte
|
||||
of the client's connection and then wrapping the socket if the data
|
||||
starts with '\x16' (indicating SSL).
|
||||
|
||||
|
||||
Sequence Numbering:
|
||||
|
||||
When the client doesn't have native WebSockets support in the browser
|
||||
(currently only Chrome and Safari 5), a flash emulator fallback is
|
||||
used. Unfortunately, when this is used, frame ordering is not 100%,
|
||||
so the GET URI in the initial handshake has "seq_num=1". This tells
|
||||
the proxy to add sequence numbers to every WebSockets frame so that
|
||||
the browser can reorder them.
|
||||
|
||||
|
||||
UTF-8 encoding:
|
||||
|
||||
In addition to the base64 encoding of the data, the proxy also
|
||||
supports UTF-8 encoding of the data (the native WebSockets encoding).
|
||||
However, in order to not burden the browser too much, the encoding
|
||||
doesn't use the full UTF-8 value space, but only uses the first 256
|
||||
values. This actually makes UTF-8 encoding slightly less space
|
||||
efficient than base64. Also, flash cannot handle byte arrays with 0's
|
||||
in them properly, so the values are actually 1-256 (rather than 0-255)
|
||||
and the browser does modulus 256 on the data. For these two reasons,
|
||||
base64 is the default and is indicated in the GET string by
|
||||
"base64=1".
|
||||
|
||||
|
||||
Flash security policy:
|
||||
|
||||
The proxy detects flash security policy requests (again by sniffing
|
||||
the first packet) and answers with an appropriate flash security
|
||||
policy response (and then closes the port). This means no separate
|
||||
flash security policy server is needed for supporting the flash
|
||||
WebSockets fallback emulator.
|
||||
|
||||
|
||||
Daemonizing:
|
||||
|
||||
The proxy also supports daemonizing (when the -f option is not
|
||||
specified).
|
||||
|
||||
|
||||
Record:
|
||||
|
||||
Finally, there is a debug feature that allows recording of the traffic
|
||||
sent and received from the client to a file (the --record option).
|
||||
@@ -0,0 +1,13 @@
|
||||
- Update setup.py, CHANGES.txt and other/package.json and commit
|
||||
- Create version tag and tarball from tag
|
||||
WVER=0.1.0
|
||||
git tag v${WVER}
|
||||
git push origin master
|
||||
git push origin v${WVER}
|
||||
- Register with pypi.python.org (once):
|
||||
python setup.py register
|
||||
- Upload the source distribution to pypi
|
||||
python setup.py sdist upload
|
||||
- Register with npmjs.org (once)
|
||||
- Upload websockify.js npmjs.org package
|
||||
npm publish other/js
|
||||
-147
@@ -1,147 +0,0 @@
|
||||
5.1.1 ProtocolVersion: 12, 12 bytes
|
||||
|
||||
- Sent by server, max supported
|
||||
12 ascii - "RFB 003.008\n"
|
||||
- Response by client, version to use
|
||||
12 ascii - "RFB 003.003\n"
|
||||
|
||||
5.1.2 Authentication: >=4, [16, 4] bytes
|
||||
|
||||
- Sent by server
|
||||
CARD32 - authentication-scheme
|
||||
0 - connection failed
|
||||
CARD32 - length
|
||||
length - reason
|
||||
1 - no authentication
|
||||
|
||||
2 - VNC authentication
|
||||
16 CARD8 - challenge (random bytes)
|
||||
|
||||
- Response by client (if VNC authentication)
|
||||
16 CARD8 - client encrypts the challenge with DES, using user
|
||||
password as key, sends resulting 16 byte response
|
||||
|
||||
- Response by server (if VNC authentication)
|
||||
CARD32 - 0 - OK
|
||||
1 - failed
|
||||
2 - too-many
|
||||
|
||||
5.1.3 ClientInitialisation: 1 byte
|
||||
- Sent by client
|
||||
CARD8 - shared-flag, 0 exclusive, non-zero shared
|
||||
|
||||
5.1.4 ServerInitialisation: >=24 bytes
|
||||
- Sent by server
|
||||
CARD16 - framebuffer-width
|
||||
CARD16 - framebuffer-height
|
||||
16 byte PIXEL_FORMAT - server-pixel-format
|
||||
CARD8 - bits-per-pixel
|
||||
CARD8 - depth
|
||||
CARD8 - big-endian-flag, non-zero is big endian
|
||||
CARD8 - true-color-flag, non-zero then next 6 apply
|
||||
CARD16 - red-max
|
||||
CARD16 - green-max
|
||||
CARD16 - blue-max
|
||||
CARD8 - red-shift
|
||||
CARD8 - green-shift
|
||||
CARD8 - blue-shift
|
||||
3 bytes - padding
|
||||
CARD32 - name-length
|
||||
|
||||
CARD8[length] - name-string
|
||||
|
||||
|
||||
|
||||
Client to Server Messages:
|
||||
|
||||
5.2.1 SetPixelFormat: 20 bytes
|
||||
CARD8: 0 - message-type
|
||||
...
|
||||
|
||||
5.2.2 FixColourMapEntries: >=6 bytes
|
||||
CARD8: 1 - message-type
|
||||
...
|
||||
|
||||
5.2.3 SetEncodings: >=8 bytes
|
||||
CARD8: 2 - message-type
|
||||
CARD8 - padding
|
||||
CARD16 - numer-of-encodings
|
||||
|
||||
CARD32 - encoding-type in preference order
|
||||
0 - raw
|
||||
1 - copy-rectangle
|
||||
2 - RRE
|
||||
4 - CoRRE
|
||||
5 - hextile
|
||||
|
||||
5.2.4 FramebufferUpdateRequest (10 bytes)
|
||||
CARD8: 3 - message-type
|
||||
CARD8 - incremental (0 for full-update, non-zero for incremental)
|
||||
CARD16 - x-position
|
||||
CARD16 - y-position
|
||||
CARD16 - width
|
||||
CARD16 - height
|
||||
|
||||
|
||||
5.2.5 KeyEvent: 8 bytes
|
||||
CARD8: 4 - message-type
|
||||
CARD8 - down-flag
|
||||
2 bytes - padding
|
||||
CARD32 - key (X-Windows keysym values)
|
||||
|
||||
5.2.6 PointerEvent: 6 bytes
|
||||
CARD8: 5 - message-type
|
||||
CARD8 - button-mask
|
||||
CARD16 - x-position
|
||||
CARD16 - y-position
|
||||
|
||||
5.2.7 ClientCutText: >=9 bytes
|
||||
CARD8: 6 - message-type
|
||||
...
|
||||
|
||||
|
||||
Server to Client Messages:
|
||||
|
||||
5.3.1 FramebufferUpdate
|
||||
CARD8: 0 - message-type
|
||||
1 byte - padding
|
||||
CARD16 - number-of-rectangles
|
||||
|
||||
CARD16 - x-position
|
||||
CARD16 - y-position
|
||||
CARD16 - width
|
||||
CARD16 - height
|
||||
CARD16 - encoding-type:
|
||||
0 - raw
|
||||
1 - copy rectangle
|
||||
2 - RRE
|
||||
4 - CoRRE
|
||||
5 - hextile
|
||||
|
||||
raw:
|
||||
- width x height pixel values
|
||||
|
||||
copy rectangle:
|
||||
CARD16 - src-x-position
|
||||
CARD16 - src-y-position
|
||||
|
||||
RRE:
|
||||
CARD32 - N number-of-subrectangles
|
||||
Nxd bytes - background-pixel-value (d bits-per-pixel)
|
||||
|
||||
...
|
||||
|
||||
5.3.2 SetColourMapEntries (no support)
|
||||
CARD8: 1 - message-type
|
||||
...
|
||||
|
||||
5.3.3 Bell
|
||||
CARD8: 2 - message-type
|
||||
|
||||
5.3.4 ServerCutText
|
||||
CARD8: 3 - message-type
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,110 @@
|
||||
.TH websockify 1 "June 7, 2012" "version 0.3" "USER COMMANDS"
|
||||
|
||||
.SH NAME
|
||||
|
||||
websockify - WebSockets to TCP socket bridge
|
||||
|
||||
.SH SYNOPSIS
|
||||
|
||||
websockify [options] [source_addr:]source_port target_addr:target_port
|
||||
websockify [options] [source_addr:]source_port \-\- WRAP_COMMAND_LINE
|
||||
|
||||
.SH OPTIONS
|
||||
|
||||
-h, --help show this help message and exit
|
||||
-v, --verbose verbose messages and per frame traffic
|
||||
--record=FILE record sessions to FILE.[session_number]
|
||||
-D, --daemon become a daemon (background process)
|
||||
--run-once handle a single WebSocket connection and exit
|
||||
--timeout=TIMEOUT after TIMEOUT seconds exit when not connected
|
||||
--cert=CERT SSL certificate file
|
||||
--key=KEY SSL key file (if separate from cert)
|
||||
--ssl-only disallow non-encrypted connections
|
||||
--web=DIR run webserver on same port. Serve files from DIR.
|
||||
--wrap-mode=MODE action to take when the wrapped program exits or
|
||||
daemonizes: exit (default), ignore, respawn
|
||||
|
||||
.SH DESCRIPTION
|
||||
|
||||
At the most basic level, websockify just translates WebSockets traffic to normal TCP socket traffic. Websockify accepts the WebSockets handshake, parses it, and then begins forwarding traffic between the client and the target in both directions.
|
||||
|
||||
websockify was formerly named wsproxy and was part of the noVNC project.
|
||||
|
||||
.SH NOTES
|
||||
|
||||
.SS WebSockets binary data
|
||||
|
||||
Websockify supports all versions of the WebSockets protocol (Hixie and HyBI). The older Hixie versions of the protocol only support UTF-8 text payloads. In order to transport binary data over UTF-8 an encoding must used to encapsulate the data within UTF-8. Websockify uses base64 to encode all traffic to and from the client. This does not affect the data between websockify and the server.
|
||||
|
||||
.SS Encrypted WebSocket connections (wss://)
|
||||
|
||||
To encrypt the traffic using the WebSocket 'wss://' URI scheme you need to generate a certificate for websockify to load. By default websockify loads a certificate file name self.pem but the --cert=CERT option can override the file name. You can generate a self-signed certificate using openssl. When asked for the common name, use the hostname of the server where the proxy will be running:
|
||||
|
||||
openssl req -new -x509 -days 365 -nodes -out self.pem -keyout self.pem
|
||||
|
||||
.SS Websock Javascript library
|
||||
|
||||
The websock.js (see https://github.com/kanaka/websockify) Javascript library library provides a Websock object that is similar to the standard WebSocket object but Websock enables communication with raw TCP sockets (i.e. the binary stream) via websockify. This is accomplished by base64 encoding the data stream between Websock and websockify.
|
||||
|
||||
Websock has built-in receive queue buffering; the message event does not contain actual data but is simply a notification that there is new data available. Several rQ* methods are available to read binary data off of the receive queue.
|
||||
|
||||
The Websock API is documented on the websock.js API wiki page:
|
||||
|
||||
https://github.com/kanaka/websockify/wiki/websock.js
|
||||
|
||||
See the "Wrap a Program" section below for an example of using Websock and websockify as a browser telnet client (wstelnet.html).
|
||||
|
||||
.SS Additional websockify features
|
||||
|
||||
These are not necessary for the basic operation.
|
||||
|
||||
.IP *
|
||||
Daemonizing: When the -D option is specified, websockify runs in the background as a daemon process.
|
||||
|
||||
.IP *
|
||||
SSL (the wss:// WebSockets URI): This is detected automatically by websockify by sniffing the first byte sent from the client and then wrapping the socket if the data starts with '\\x16' or '\\x80' (indicating SSL).
|
||||
|
||||
.IP *
|
||||
Flash security policy: websockify detects flash security policy requests (again by sniffing the first packet) and answers with an appropriate flash security policy response (and then closes the port). This means no separate flash security policy server is needed for supporting the flash WebSockets fallback emulator.
|
||||
|
||||
.IP *
|
||||
Session recording: This feature that allows recording of the traffic sent and received from the client to a file using the --record option.
|
||||
|
||||
.IP *
|
||||
Mini-webserver: websockify can detect and respond to normal web requests on the same port as the WebSockets proxy and Flash security policy. This functionality is activate with the --web DIR option where DIR is the root of the web directory to serve.
|
||||
|
||||
.IP *
|
||||
Wrap a program: see the "Wrap a Program" section below.
|
||||
|
||||
.SS Wrap a Program
|
||||
|
||||
In addition to proxying from a source address to a target address (which may be on a different system), websockify has the ability to launch a program on the local system and proxy WebSockets traffic to a normal TCP port owned/bound by the program.
|
||||
|
||||
The is accomplished with a small LD_PRELOAD library (rebind.so) which intercepts bind() system calls by the program. The specified port is moved to a new localhost/loopback free high port. websockify then proxies WebSockets traffic directed to the original port to the new (moved) port of the program.
|
||||
|
||||
The program wrap mode is invoked by replacing the target with -- followed by the program command line to wrap.
|
||||
|
||||
`./websockify 2023 -- PROGRAM ARGS`
|
||||
|
||||
The --wrap-mode option can be used to indicate what action to take when the wrapped program exits or daemonizes.
|
||||
|
||||
Here is an example of using websockify to wrap the vncserver command (which backgrounds itself) for use with noVNC:
|
||||
|
||||
`./websockify 5901 --wrap-mode=ignore -- vncserver -geometry 1024x768 :1`
|
||||
|
||||
Here is an example of wrapping telnetd (from krb5-telnetd).telnetd exits after the connection closes so the wrap mode is set to respawn the command:
|
||||
|
||||
`sudo ./websockify 2023 --wrap-mode=respawn -- telnetd -debug 2023`
|
||||
|
||||
The wstelnet.html page demonstrates a simple WebSockets based telnet client.
|
||||
|
||||
|
||||
.SH AUTHOR
|
||||
Joel Martin (github@martintribe.org)
|
||||
|
||||
.SH SEE ALSO
|
||||
|
||||
https://github.com/kanaka/websockify/
|
||||
|
||||
https://github.com/kanaka/websockify/wiki/
|
||||
|
||||
@@ -0,0 +1,919 @@
|
||||
// VT100.js -- a text terminal emulator in JavaScript with a ncurses-like
|
||||
// interface and a POSIX-like interface. (The POSIX-like calls are
|
||||
// implemented on top of the ncurses-like calls, not the other way round.)
|
||||
//
|
||||
// Released under the GNU LGPL v2.1, by Frank Bi <bi@zompower.tk>
|
||||
//
|
||||
// 2007-08-12 - refresh():
|
||||
// - factor out colour code to html_colours_()
|
||||
// - fix handling of A_REVERSE | A_DIM
|
||||
// - simplify initial <br /> output code
|
||||
// - fix underlining colour
|
||||
// - fix attron() not to turn off attributes
|
||||
// - decouple A_STANDOUT and A_BOLD
|
||||
// 2007-08-11 - getch() now calls refresh()
|
||||
// 2007-08-06 - Safari compat fix -- turn '\r' into '\n' for onkeypress
|
||||
// 2007-08-05 - Opera compat fixes for onkeypress
|
||||
// 2007-07-30 - IE compat fixes:
|
||||
// - change key handling code
|
||||
// - add <br />...<br /> so that 1st and last lines align
|
||||
// 2007-07-28 - change wrapping behaviour -- writing at the right edge no
|
||||
// longer causes the cursor to immediately wrap around
|
||||
// - add <b>...</b> to output to make A_STANDOUT stand out more
|
||||
// - add handling of backspace, tab, return keys
|
||||
// - fix doc. of VT100() constructor
|
||||
// - change from GPL to LGPL
|
||||
// 2007-07-09 - initial release
|
||||
//
|
||||
// class VT100
|
||||
// A_NORMAL, A_UNDERLINE, A_REVERSE, A_BLINK, A_DIM, A_BOLD, A_STANDOUT
|
||||
// =class constants=
|
||||
// Attribute constants.
|
||||
// VT100(wd, ht, scr_id) =constructor=
|
||||
// Creates a virtual terminal with width `wd', and
|
||||
// height `ht'. The terminal will be displayed between
|
||||
// <pre>...</pre> tags which have element ID `scr_id'.
|
||||
// addch(ch [, attr])
|
||||
// Writes out the character `ch'. If `attr' is given,
|
||||
// it specifies the attributes for the character,
|
||||
// otherwise the current attributes are used.
|
||||
// addstr(stuff) Writes out the string `stuff' using the current
|
||||
// attributes.
|
||||
// attroff(mode) Turns off any current options given in mode.
|
||||
// attron(mode) Turns on any options given in mode.
|
||||
// attrset(mode) Sets the current options to mode.
|
||||
// bkgdset(attr) Sets the background attributes to attr.
|
||||
// clear() Clears the terminal using the background attributes,
|
||||
// and homes the cursor.
|
||||
// clrtobol() Clears the portion of the terminal from the cursor
|
||||
// to the bottom.
|
||||
// clrtoeol() Clears the portion of the current line after the
|
||||
// cursor.
|
||||
// curs_set(vis [, grab])
|
||||
// If `vis' is 0, makes the cursor invisible; otherwise
|
||||
// make it visible. If `grab' is given and true, starts
|
||||
// capturing keyboard events (for `getch()'); if given
|
||||
// and false, stops capturing events.
|
||||
// echo() Causes key strokes to be automatically echoed on the
|
||||
// terminal.
|
||||
// erase() Same as `clear()'.
|
||||
// getch(isr) Arranges to call `isr' when a key stroke is
|
||||
// received. The received character and the terminal
|
||||
// object are passed as arguments to `isr'.
|
||||
// getmaxyx() Returns an associative array with the maximum row
|
||||
// (`y') and column (`x') numbers for the terminal.
|
||||
// getyx() Returns an associative array with the current row
|
||||
// (`y') and column (`x') of the cursor.
|
||||
// move(r, c) Moves the cursor to row `r', column `c'.
|
||||
// noecho() Stops automatically echoing key strokes.
|
||||
// refresh() Updates the display.
|
||||
// scroll() Scrolls the terminal up one line.
|
||||
// standend() Same as `attrset(VT100.A_NORMAL)'.
|
||||
// standout() Same as `attron(VT100.A_STANDOUT)'.
|
||||
// write(stuff) Writes `stuff' to the terminal and immediately
|
||||
// updates the display; (some) escape sequences are
|
||||
// interpreted and acted on.
|
||||
|
||||
// constructor
|
||||
function VT100(wd, ht, scr_id)
|
||||
{
|
||||
var r;
|
||||
var c;
|
||||
var scr = document.getElementById(scr_id);
|
||||
this.wd_ = wd;
|
||||
this.ht_ = ht;
|
||||
this.scrolled_ = 0;
|
||||
this.bkgd_ = {
|
||||
mode: VT100.A_NORMAL,
|
||||
fg: VT100.COLOR_WHITE,
|
||||
bg: VT100.COLOR_BLACK
|
||||
};
|
||||
this.c_attr_ = {
|
||||
mode: VT100.A_NORMAL,
|
||||
fg: VT100.COLOR_WHITE,
|
||||
bg: VT100.COLOR_BLACK
|
||||
};
|
||||
this.text_ = new Array(ht);
|
||||
this.attr_ = new Array(ht);
|
||||
for (r = 0; r < ht; ++r) {
|
||||
this.text_[r] = new Array(wd);
|
||||
this.attr_[r] = new Array(wd);
|
||||
}
|
||||
this.scr_ = scr;
|
||||
this.cursor_vis_ = true;
|
||||
this.grab_events_ = false;
|
||||
this.getch_isr_ = undefined;
|
||||
this.key_buf_ = [];
|
||||
this.echo_ = true;
|
||||
this.esc_state_ = 0;
|
||||
// Internal debug setting.
|
||||
this.debug_ = 0;
|
||||
this.clear();
|
||||
this.refresh();
|
||||
}
|
||||
|
||||
// public constants -- colours and colour pairs
|
||||
VT100.COLOR_BLACK = 0;
|
||||
VT100.COLOR_BLUE = 1;
|
||||
VT100.COLOR_GREEN = 2;
|
||||
VT100.COLOR_CYAN = 3;
|
||||
VT100.COLOR_RED = 4;
|
||||
VT100.COLOR_MAGENTA = 5;
|
||||
VT100.COLOR_YELLOW = 6;
|
||||
VT100.COLOR_WHITE = 7;
|
||||
VT100.COLOR_PAIRS = 256;
|
||||
VT100.COLORS = 8;
|
||||
// public constants -- attributes
|
||||
VT100.A_NORMAL = 0;
|
||||
VT100.A_UNDERLINE = 1;
|
||||
VT100.A_REVERSE = 2;
|
||||
VT100.A_BLINK = 4;
|
||||
VT100.A_DIM = 8;
|
||||
VT100.A_BOLD = 16;
|
||||
VT100.A_STANDOUT = 32;
|
||||
VT100.A_PROTECT = VT100.A_INVIS = 0; // ?
|
||||
// other public constants
|
||||
VT100.TABSIZE = 8;
|
||||
// private constants
|
||||
VT100.ATTR_FLAGS_ = VT100.A_UNDERLINE | VT100.A_REVERSE | VT100.A_BLINK |
|
||||
VT100.A_DIM | VT100.A_BOLD | VT100.A_STANDOUT |
|
||||
VT100.A_PROTECT | VT100.A_INVIS;
|
||||
VT100.COLOR_SHIFT_ = 6;
|
||||
VT100.browser_ie_ = (navigator.appName.indexOf("Microsoft") != -1);
|
||||
VT100.browser_opera_ = (navigator.appName.indexOf("Opera") != -1);
|
||||
// class variables
|
||||
VT100.the_vt_ = undefined;
|
||||
|
||||
// class methods
|
||||
|
||||
// this is actually an event handler
|
||||
VT100.handle_onkeypress_ = function VT100_handle_onkeypress(event)
|
||||
{
|
||||
var vt = VT100.the_vt_, ch;
|
||||
if (vt === undefined)
|
||||
return true;
|
||||
if (VT100.browser_ie_ || VT100.browser_opera_) {
|
||||
ch = event.keyCode;
|
||||
if (ch == 13)
|
||||
ch = 10;
|
||||
else if (ch > 255 || (ch < 32 && ch != 8))
|
||||
return true;
|
||||
ch = String.fromCharCode(ch);
|
||||
} else {
|
||||
ch = event.charCode;
|
||||
//dump("ch: " + ch + "\n");
|
||||
//dump("ctrl?: " + event.ctrlKey + "\n");
|
||||
vt.debug("onkeypress:: keyCode: " + event.keyCode + ", ch: " + event.charCode);
|
||||
if (ch) {
|
||||
if (ch > 255)
|
||||
return true;
|
||||
if (event.ctrlKey && event.shiftKey) {
|
||||
// Don't send the copy/paste commands.
|
||||
var charStr = String.fromCharCode(ch);
|
||||
if (charStr == 'C' || charStr == 'V') {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (event.ctrlKey) {
|
||||
ch = String.fromCharCode(ch - 96);
|
||||
} else {
|
||||
ch = String.fromCharCode(ch);
|
||||
if (ch == '\r')
|
||||
ch = '\n';
|
||||
}
|
||||
} else {
|
||||
switch (event.keyCode) {
|
||||
case event.DOM_VK_BACK_SPACE:
|
||||
ch = '\b';
|
||||
break;
|
||||
case event.DOM_VK_TAB:
|
||||
ch = '\t';
|
||||
// Stop tab from moving to another element.
|
||||
event.preventDefault();
|
||||
break;
|
||||
case event.DOM_VK_RETURN:
|
||||
case event.DOM_VK_ENTER:
|
||||
ch = '\n';
|
||||
break;
|
||||
case event.DOM_VK_UP:
|
||||
ch = '\x1b[A';
|
||||
break;
|
||||
case event.DOM_VK_DOWN:
|
||||
ch = '\x1b[B';
|
||||
break;
|
||||
case event.DOM_VK_RIGHT:
|
||||
ch = '\x1b[C';
|
||||
break;
|
||||
case event.DOM_VK_LEFT:
|
||||
ch = '\x1b[D';
|
||||
break;
|
||||
case event.DOM_VK_DELETE:
|
||||
ch = '\x1b[3~';
|
||||
break;
|
||||
case event.DOM_VK_HOME:
|
||||
ch = '\x1b[H';
|
||||
break;
|
||||
case event.DOM_VK_ESCAPE:
|
||||
ch = '\x1bc';
|
||||
break;
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
vt.key_buf_.push(ch);
|
||||
setTimeout(VT100.go_getch_, 0);
|
||||
return false;
|
||||
}
|
||||
|
||||
// this is actually an event handler
|
||||
VT100.handle_onkeydown_ = function VT100_handle_onkeydown()
|
||||
{
|
||||
var vt = VT100.the_vt_, ch;
|
||||
switch (event.keyCode) {
|
||||
case 8:
|
||||
ch = '\b'; break;
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
vt.key_buf_.push(ch);
|
||||
setTimeout(VT100.go_getch_, 0);
|
||||
return false;
|
||||
}
|
||||
|
||||
VT100.go_getch_ = function VT100_go_getch()
|
||||
{
|
||||
var vt = VT100.the_vt_;
|
||||
if (vt === undefined)
|
||||
return;
|
||||
var isr = vt.getch_isr_;
|
||||
vt.getch_isr_ = undefined;
|
||||
if (isr === undefined)
|
||||
return;
|
||||
var ch = vt.key_buf_.shift();
|
||||
if (ch === undefined) {
|
||||
vt.getch_isr_ = isr;
|
||||
return;
|
||||
}
|
||||
if (vt.echo_)
|
||||
vt.addch(ch);
|
||||
isr(ch, vt);
|
||||
}
|
||||
|
||||
// object methods
|
||||
|
||||
VT100.prototype.may_scroll_ = function()
|
||||
{
|
||||
var ht = this.ht_, cr = this.row_;
|
||||
while (cr >= ht) {
|
||||
this.scroll();
|
||||
--cr;
|
||||
}
|
||||
this.row_ = cr;
|
||||
}
|
||||
|
||||
VT100.prototype.html_colours_ = function(attr)
|
||||
{
|
||||
var fg, bg, co0, co1;
|
||||
fg = attr.fg;
|
||||
bg = attr.bg;
|
||||
switch (attr.mode & (VT100.A_REVERSE | VT100.A_DIM | VT100.A_BOLD)) {
|
||||
case 0:
|
||||
case VT100.A_DIM | VT100.A_BOLD:
|
||||
co0 = '00'; co1 = 'c0';
|
||||
break;
|
||||
case VT100.A_BOLD:
|
||||
co0 = '00'; co1 = 'ff';
|
||||
break;
|
||||
case VT100.A_DIM:
|
||||
if (fg == VT100.COLOR_BLACK)
|
||||
co0 = '40';
|
||||
else
|
||||
co0 = '00';
|
||||
co1 = '40';
|
||||
break;
|
||||
case VT100.A_REVERSE:
|
||||
case VT100.A_REVERSE | VT100.A_DIM | VT100.A_BOLD:
|
||||
co0 = 'c0'; co1 = '40';
|
||||
break;
|
||||
case VT100.A_REVERSE | VT100.A_BOLD:
|
||||
co0 = 'c0'; co1 = '00';
|
||||
break;
|
||||
default:
|
||||
if (fg == VT100.COLOR_BLACK)
|
||||
co0 = '80';
|
||||
else
|
||||
co0 = 'c0';
|
||||
co1 = 'c0';
|
||||
}
|
||||
return {
|
||||
f: '#' + (fg & 4 ? co1 : co0) +
|
||||
(fg & 2 ? co1 : co0) +
|
||||
(fg & 1 ? co1 : co0),
|
||||
b: '#' + (bg & 4 ? co1 : co0) +
|
||||
(bg & 2 ? co1 : co0) +
|
||||
(bg & 1 ? co1 : co0)
|
||||
};
|
||||
}
|
||||
|
||||
VT100.prototype.addch = function(ch, attr)
|
||||
{
|
||||
var cc = this.col_;
|
||||
this.debug("addch:: ch: " + ch + ", attr: " + attr);
|
||||
switch (ch) {
|
||||
case '\b':
|
||||
if (cc != 0)
|
||||
--cc;
|
||||
break;
|
||||
case '\n':
|
||||
++this.row_;
|
||||
cc = 0;
|
||||
this.clrtoeol();
|
||||
this.may_scroll_();
|
||||
break;
|
||||
case '\r':
|
||||
this.may_scroll_();
|
||||
cc = 0;
|
||||
break;
|
||||
case '\t':
|
||||
this.may_scroll_();
|
||||
cc += VT100.TABSIZE - cc % VT100.TABSIZE;
|
||||
if (cc >= this.wd_) {
|
||||
++this.row_;
|
||||
cc -= this.wd_;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if (attr === undefined)
|
||||
attr = this._cloneAttr(this.c_attr_);
|
||||
if (cc >= this.wd_) {
|
||||
++this.row_;
|
||||
cc = 0;
|
||||
}
|
||||
this.may_scroll_();
|
||||
this.text_[this.row_][cc] = ch;
|
||||
this.attr_[this.row_][cc] = attr;
|
||||
++cc;
|
||||
}
|
||||
this.col_ = cc;
|
||||
}
|
||||
|
||||
VT100.prototype.addstr = function(stuff)
|
||||
{
|
||||
for (var i = 0; i < stuff.length; ++i)
|
||||
this.addch(stuff.charAt(i));
|
||||
}
|
||||
|
||||
VT100.prototype._cloneAttr = function VT100_cloneAttr(a)
|
||||
{
|
||||
return {
|
||||
mode: a.mode,
|
||||
fg: a.fg,
|
||||
bg: a.bg
|
||||
};
|
||||
}
|
||||
|
||||
VT100.prototype.attroff = function(a)
|
||||
{
|
||||
//dump("attroff: " + a + "\n");
|
||||
a &= VT100.ATTR_FLAGS_;
|
||||
this.c_attr_.mode &= ~a;
|
||||
}
|
||||
|
||||
VT100.prototype.attron = function(a)
|
||||
{
|
||||
//dump("attron: " + a + "\n");
|
||||
a &= VT100.ATTR_FLAGS_;
|
||||
this.c_attr_.mode |= a;
|
||||
}
|
||||
|
||||
VT100.prototype.attrset = function(a)
|
||||
{
|
||||
//dump("attrset: " + a + "\n");
|
||||
this.c_attr_.mode = a;
|
||||
}
|
||||
|
||||
VT100.prototype.fgset = function(fg)
|
||||
{
|
||||
//dump("fgset: " + fg + "\n");
|
||||
this.c_attr_.fg = fg;
|
||||
}
|
||||
|
||||
VT100.prototype.bgset = function(bg)
|
||||
{
|
||||
//dump("bgset: " + bg + "\n");
|
||||
if (bg !== 0) {
|
||||
this.warn("bgset: " + bg + "\n");
|
||||
}
|
||||
this.c_attr_.bg = bg;
|
||||
}
|
||||
|
||||
VT100.prototype.bkgdset = function(a)
|
||||
{
|
||||
this.bkgd_ = a;
|
||||
}
|
||||
|
||||
VT100.prototype.clear = function()
|
||||
{
|
||||
this.debug("clear");
|
||||
this.row_ = this.col_ = 0;
|
||||
this.scrolled_ = 0;
|
||||
for (r = 0; r < this.ht_; ++r) {
|
||||
for (c = 0; c < this.wd_; ++c) {
|
||||
this.text_[r][c] = ' ';
|
||||
this.attr_[r][c] = this._cloneAttr(this.bkgd_);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
VT100.prototype.clrtobot = function()
|
||||
{
|
||||
this.debug("clrtobot, row: " + this.row_);
|
||||
var ht = this.ht_;
|
||||
var wd = this.wd_;
|
||||
this.clrtoeol();
|
||||
for (var r = this.row_ + 1; r < ht; ++r) {
|
||||
for (var c = 0; c < wd; ++c) {
|
||||
this.text_[r][c] = ' ';
|
||||
this.attr_[r][c] = this.bkgd_;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
VT100.prototype.clrtoeol = function()
|
||||
{
|
||||
this.debug("clrtoeol, col: " + this.col_);
|
||||
var r = this.row_;
|
||||
if (r >= this.ht_)
|
||||
return;
|
||||
for (var c = this.col_; c < this.wd_; ++c) {
|
||||
this.text_[r][c] = ' ';
|
||||
this.attr_[r][c] = this.bkgd_;
|
||||
}
|
||||
}
|
||||
|
||||
VT100.prototype.clearpos = function(row, col)
|
||||
{
|
||||
this.debug("clearpos (" + row + ", " + col + ")");
|
||||
if (row < 0 || row >= this.ht_)
|
||||
return;
|
||||
if (col < 0 || col >= this.wd_)
|
||||
return;
|
||||
this.text_[row][col] = ' ';
|
||||
this.attr_[row][col] = this.bkgd_;
|
||||
}
|
||||
|
||||
VT100.prototype.curs_set = function(vis, grab, eventist)
|
||||
{
|
||||
this.debug("curs_set:: vis: " + vis + ", grab: " + grab);
|
||||
if (vis !== undefined)
|
||||
this.cursor_vis_ = (vis > 0);
|
||||
if (eventist === undefined)
|
||||
eventist = window;
|
||||
if (grab === true || grab === false) {
|
||||
if (grab === this.grab_events_)
|
||||
return;
|
||||
if (grab) {
|
||||
this.grab_events_ = true;
|
||||
VT100.the_vt_ = this;
|
||||
eventist.addEventListener("keypress", VT100.handle_onkeypress_, false);
|
||||
if (VT100.browser_ie_)
|
||||
document.onkeydown = VT100.handle_onkeydown_;
|
||||
} else {
|
||||
eventist.removeEventListener("keypress", VT100.handle_onkeypress_, false);
|
||||
if (VT100.browser_ie_)
|
||||
document.onkeydown = VT100.handle_onkeydown_;
|
||||
this.grab_events_ = false;
|
||||
VT100.the_vt_ = undefined;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
VT100.prototype.echo = function()
|
||||
{
|
||||
this.debug("echo on");
|
||||
this.echo_ = true;
|
||||
}
|
||||
|
||||
VT100.prototype.erase = VT100.prototype.clear;
|
||||
|
||||
VT100.prototype.getch = function(isr)
|
||||
{
|
||||
this.debug("getch");
|
||||
this.refresh();
|
||||
this.getch_isr_ = isr;
|
||||
setTimeout(VT100.go_getch_, 0);
|
||||
}
|
||||
|
||||
VT100.prototype.getmaxyx = function()
|
||||
{
|
||||
return { y: this.ht_ - 1, x: this.wd_ - 1 };
|
||||
}
|
||||
|
||||
VT100.prototype.getyx = function()
|
||||
{
|
||||
return { y: this.row_, x: this.col_ };
|
||||
}
|
||||
|
||||
VT100.prototype.move = function(r, c)
|
||||
{
|
||||
this.debug("move: (" + r + ", " + c + ")");
|
||||
if (r < 0)
|
||||
r = 0;
|
||||
else if (r >= this.ht_)
|
||||
r = this.ht_ - 1;
|
||||
if (c < 0)
|
||||
c = 0;
|
||||
else if (c >= this.wd_)
|
||||
c = this.wd_ - 1;
|
||||
this.row_ = r;
|
||||
this.col_ = c;
|
||||
}
|
||||
|
||||
VT100.prototype.noecho = function()
|
||||
{
|
||||
this.debug("echo off");
|
||||
this.echo_ = false;
|
||||
}
|
||||
|
||||
VT100.prototype.refresh = function()
|
||||
{
|
||||
this.debug("refresh");
|
||||
var r, c, stuff = "", start_tag = "", end_tag = "", at = -1, n_at, ch,
|
||||
pair, cr, cc, ht, wd, cv, added_end_tag;
|
||||
ht = this.ht_;
|
||||
wd = this.wd_;
|
||||
cr = this.row_;
|
||||
cc = this.col_;
|
||||
cv = this.cursor_vis_;
|
||||
var innerHTML = this.scr_.innerHTML;
|
||||
if (cc >= wd)
|
||||
cc = wd - 1;
|
||||
for (r = 0; r < ht; ++r) {
|
||||
if (r > 0) {
|
||||
stuff += '\n';
|
||||
}
|
||||
for (c = 0; c < wd; ++c) {
|
||||
added_end_tag = false;
|
||||
n_at = this.attr_[r][c];
|
||||
if (cv && r == cr && c == cc) {
|
||||
// Draw the cursor here.
|
||||
n_at = this._cloneAttr(n_at);
|
||||
n_at.mode ^= VT100.A_REVERSE;
|
||||
}
|
||||
// If the attributes changed, make a new span.
|
||||
if (n_at.mode != at.mode || n_at.fg != at.fg || n_at.bg != at.bg) {
|
||||
if (c > 0) {
|
||||
stuff += end_tag;
|
||||
}
|
||||
start_tag = "";
|
||||
end_tag = "";
|
||||
if (n_at.mode & VT100.A_BLINK) {
|
||||
start_tag = "<blink>";
|
||||
end_tag = "</blink>" + end_tag;
|
||||
}
|
||||
if (n_at.mode & VT100.A_STANDOUT)
|
||||
n_at.mode |= VT100.A_BOLD;
|
||||
pair = this.html_colours_(n_at);
|
||||
start_tag += '<span style="color:' + pair.f +
|
||||
';background-color:' + pair.b;
|
||||
if (n_at.mode & VT100.A_UNDERLINE)
|
||||
start_tag += ';text-decoration:underline';
|
||||
start_tag += ';">';
|
||||
stuff += start_tag;
|
||||
end_tag = "</span>" + end_tag;
|
||||
at = n_at;
|
||||
added_end_tag = true;
|
||||
} else if (c == 0) {
|
||||
stuff += start_tag;
|
||||
}
|
||||
ch = this.text_[r][c];
|
||||
switch (ch) {
|
||||
case '&':
|
||||
stuff += '&'; break;
|
||||
case '<':
|
||||
stuff += '<'; break;
|
||||
case '>':
|
||||
stuff += '>'; break;
|
||||
case ' ':
|
||||
//stuff += ' '; break;
|
||||
stuff += ' '; break;
|
||||
default:
|
||||
stuff += ch;
|
||||
}
|
||||
}
|
||||
if (!added_end_tag)
|
||||
stuff += end_tag;
|
||||
}
|
||||
this.scr_.innerHTML = "<b>" + stuff + "</b>\n";
|
||||
}
|
||||
|
||||
VT100.prototype.scroll = function()
|
||||
{
|
||||
this.scrolled_ += 1;
|
||||
this.debug("scrolled: " + this.scrolled_);
|
||||
var n_text = this.text_[0], n_attr = this.attr_[0],
|
||||
ht = this.ht_, wd = this.wd_;
|
||||
for (var r = 1; r < ht; ++r) {
|
||||
this.text_[r - 1] = this.text_[r];
|
||||
this.attr_[r - 1] = this.attr_[r];
|
||||
}
|
||||
this.text_[ht - 1] = n_text;
|
||||
this.attr_[ht - 1] = n_attr;
|
||||
for (var c = 0; c < wd; ++c) {
|
||||
n_text[c] = ' ';
|
||||
n_attr[c] = this.bkgd_;
|
||||
}
|
||||
}
|
||||
|
||||
VT100.prototype.standend = function()
|
||||
{
|
||||
//this.debug("standend");
|
||||
this.attrset(0);
|
||||
}
|
||||
|
||||
VT100.prototype.standout = function()
|
||||
{
|
||||
//this.debug("standout");
|
||||
this.attron(VT100.A_STANDOUT);
|
||||
}
|
||||
|
||||
VT100.prototype.write = function(stuff)
|
||||
{
|
||||
var ch, x, r, c, i, j, yx, myx;
|
||||
for (i = 0; i < stuff.length; ++i) {
|
||||
ch = stuff.charAt(i);
|
||||
if (ch == '\x0D') {
|
||||
this.debug("write:: ch: " + ch.charCodeAt(0) + ", '\\x0D'");
|
||||
} else {
|
||||
this.debug("write:: ch: " + ch.charCodeAt(0) + ", '" + (ch == '\x1b' ? "ESC" : ch) + "'");
|
||||
}
|
||||
//dump("ch: " + ch.charCodeAt(0) + ", '" + (ch == '\x1b' ? "ESC" : ch) + "'\n");
|
||||
switch (ch) {
|
||||
case '\x00':
|
||||
case '\x7f':
|
||||
case '\x07': /* bell, ignore it */
|
||||
this.debug("write:: ignoring bell character: " + ch);
|
||||
continue;
|
||||
case '\a':
|
||||
case '\b':
|
||||
case '\t':
|
||||
case '\r':
|
||||
this.addch(ch);
|
||||
continue;
|
||||
case '\n':
|
||||
case '\v':
|
||||
case '\f': // what a mess
|
||||
yx = this.getyx();
|
||||
myx = this.getmaxyx();
|
||||
if (yx.y >= myx.y) {
|
||||
this.scroll();
|
||||
this.move(myx.y, 0);
|
||||
} else
|
||||
this.move(yx.y + 1, 0);
|
||||
continue;
|
||||
case '\x18':
|
||||
case '\x1a':
|
||||
this.esc_state_ = 0;
|
||||
this.debug("write:: set escape state: 0");
|
||||
continue;
|
||||
case '\x1b':
|
||||
this.esc_state_ = 1;
|
||||
this.debug("write:: set escape state: 1");
|
||||
continue;
|
||||
case '\x9b':
|
||||
this.esc_state_ = 2;
|
||||
this.debug("write:: set escape state: 2");
|
||||
continue;
|
||||
}
|
||||
// not a recognized control character
|
||||
switch (this.esc_state_) {
|
||||
case 0: // not in escape sequence
|
||||
this.addch(ch);
|
||||
break;
|
||||
case 1: // just saw ESC
|
||||
switch (ch) {
|
||||
case '[':
|
||||
this.esc_state_ = 2;
|
||||
this.debug("write:: set escape state: 2");
|
||||
break;
|
||||
case '=':
|
||||
/* Set keypade mode (ignored) */
|
||||
this.debug("write:: set keypade mode: ignored");
|
||||
this.esc_state_ = 0;
|
||||
break;
|
||||
case '>':
|
||||
/* Reset keypade mode (ignored) */
|
||||
this.debug("write:: reset keypade mode: ignored");
|
||||
this.esc_state_ = 0;
|
||||
break;
|
||||
case 'H':
|
||||
/* Set tab at cursor column (ignored) */
|
||||
this.debug("write:: set tab cursor column: ignored");
|
||||
this.esc_state_ = 0;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 2: // just saw CSI
|
||||
switch (ch) {
|
||||
case 'K':
|
||||
/* Erase in Line */
|
||||
this.esc_state_ = 0;
|
||||
this.clrtoeol();
|
||||
continue;
|
||||
case 'H':
|
||||
/* Move to (0,0). */
|
||||
this.esc_state_ = 0;
|
||||
this.move(0, 0);
|
||||
continue;
|
||||
case 'J':
|
||||
/* Clear to the bottom. */
|
||||
this.esc_state_ = 0;
|
||||
this.clrtobot();
|
||||
continue;
|
||||
case '?':
|
||||
/* Special VT100 mode handling. */
|
||||
this.esc_state_ = 5;
|
||||
this.debug("write:: special vt100 mode");
|
||||
continue;
|
||||
}
|
||||
// Drop through to next case.
|
||||
this.csi_parms_ = [0];
|
||||
this.debug("write:: set escape state: 3");
|
||||
this.esc_state_ = 3;
|
||||
case 3: // saw CSI and parameters
|
||||
switch (ch) {
|
||||
case '0':
|
||||
case '1':
|
||||
case '2':
|
||||
case '3':
|
||||
case '4':
|
||||
case '5':
|
||||
case '6':
|
||||
case '7':
|
||||
case '8':
|
||||
case '9':
|
||||
x = this.csi_parms_.pop();
|
||||
this.csi_parms_.push(x * 10 + ch * 1);
|
||||
this.debug("csi_parms_: " + this.csi_parms_);
|
||||
continue;
|
||||
case ';':
|
||||
if (this.csi_parms_.length < 17)
|
||||
this.csi_parms_.push(0);
|
||||
continue;
|
||||
}
|
||||
this.esc_state_ = 0;
|
||||
switch (ch) {
|
||||
case 'A':
|
||||
// Cursor Up <ESC>[{COUNT}A
|
||||
this.move(this.row_ - Math.max(1, this.csi_parms_[0]),
|
||||
this.col_);
|
||||
break;
|
||||
case 'B':
|
||||
// Cursor Down <ESC>[{COUNT}B
|
||||
this.move(this.row_ + Math.max(1, this.csi_parms_[0]),
|
||||
this.col_);
|
||||
break;
|
||||
case 'C':
|
||||
// Cursor Forward <ESC>[{COUNT}C
|
||||
this.move(this.row_,
|
||||
this.col_ + Math.max(1, this.csi_parms_[0]));
|
||||
break;
|
||||
case 'c':
|
||||
this.warn("write:: got TERM query");
|
||||
break;
|
||||
case 'D':
|
||||
// Cursor Backward <ESC>[{COUNT}D
|
||||
this.move(this.row_,
|
||||
this.col_ - Math.max(1, this.csi_parms_[0]));
|
||||
break;
|
||||
case 'f':
|
||||
case 'H':
|
||||
// Cursor Home <ESC>[{ROW};{COLUMN}H
|
||||
this.csi_parms_.push(0);
|
||||
this.move(this.csi_parms_[0] - 1,
|
||||
this.csi_parms_[1] - 1);
|
||||
break;
|
||||
case 'J':
|
||||
switch (this.csi_parms_[0]) {
|
||||
case 0:
|
||||
this.clrtobot();
|
||||
break;
|
||||
case 2:
|
||||
this.clear();
|
||||
this.move(0, 0);
|
||||
}
|
||||
break;
|
||||
case 'm':
|
||||
for (j=0; j<this.csi_parms_.length; ++j) {
|
||||
x = this.csi_parms_[j];
|
||||
switch (x) {
|
||||
case 0:
|
||||
this.standend();
|
||||
this.fgset(this.bkgd_.fg);
|
||||
this.bgset(this.bkgd_.bg);
|
||||
break;
|
||||
case 1:
|
||||
this.attron(VT100.A_BOLD);
|
||||
break;
|
||||
case 30:
|
||||
this.fgset(VT100.COLOR_BLACK);
|
||||
break;
|
||||
case 31:
|
||||
this.fgset(VT100.COLOR_RED);
|
||||
break;
|
||||
case 32:
|
||||
this.fgset(VT100.COLOR_GREEN);
|
||||
break;
|
||||
case 33:
|
||||
this.fgset(VT100.COLOR_YELLOW);
|
||||
break;
|
||||
case 34:
|
||||
this.fgset(VT100.COLOR_BLUE);
|
||||
break;
|
||||
case 35:
|
||||
this.fgset(VT100.COLOR_MAGENTA);
|
||||
break;
|
||||
case 36:
|
||||
this.fgset(VT100.COLOR_CYAN);
|
||||
break;
|
||||
case 37:
|
||||
this.fgset(VT100.COLOR_WHITE);
|
||||
break;
|
||||
case 40:
|
||||
this.bgset(VT100.COLOR_BLACK);
|
||||
break;
|
||||
case 41:
|
||||
this.bgset(VT100.COLOR_RED);
|
||||
break;
|
||||
case 42:
|
||||
this.bgset(VT100.COLOR_GREEN);
|
||||
break;
|
||||
case 44:
|
||||
this.bgset(VT100.COLOR_YELLOW);
|
||||
break;
|
||||
case 44:
|
||||
this.bgset(VT100.COLOR_BLUE);
|
||||
break;
|
||||
case 45:
|
||||
this.bgset(VT100.COLOR_MAGENTA);
|
||||
break;
|
||||
case 46:
|
||||
this.bgset(VT100.COLOR_CYAN);
|
||||
break;
|
||||
case 47:
|
||||
this.bgset(VT100.COLOR_WHITE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'r':
|
||||
// 1,24r - set scrolling region (ignored)
|
||||
break;
|
||||
case '[':
|
||||
this.debug("write:: set escape state: 4");
|
||||
this.esc_state_ = 4;
|
||||
break;
|
||||
case 'g':
|
||||
// 0g: clear tab at cursor (ignored)
|
||||
// 3g: clear all tabs (ignored)
|
||||
break;
|
||||
default:
|
||||
this.warn("write:: unknown command: " + ch);
|
||||
this.csi_parms_ = [];
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 4: // saw CSI [
|
||||
this.esc_state_ = 0; // gobble char.
|
||||
break;
|
||||
case 5: // Special mode handling, saw <ESC>[?
|
||||
// Expect a number - the reset type
|
||||
this.csi_parms_ = [ch];
|
||||
this.esc_state_ = 6;
|
||||
break;
|
||||
case 6: // Reset mode handling, saw <ESC>[?1
|
||||
// Expect a letter - the mode target, example:
|
||||
// <ESC>[?1l : cursor key mode = cursor
|
||||
// <ESC>[?1h : save current screen, create new empty
|
||||
// screen and position at 0,0
|
||||
// <ESC>[?5l : White on blk
|
||||
// XXX: Ignored for now.
|
||||
//dump("Saw reset mode: <ESC>[?" + this.csi_parms_[0] + ch + "\n");
|
||||
this.esc_state_ = 0;
|
||||
this.debug("write:: set escape state: 0");
|
||||
break;
|
||||
}
|
||||
}
|
||||
this.refresh();
|
||||
}
|
||||
|
||||
VT100.prototype.debug = function(message) {
|
||||
if (this.debug_) {
|
||||
dump(message + "\n");
|
||||
}
|
||||
}
|
||||
|
||||
VT100.prototype.warn = function(message) {
|
||||
dump(message + "\n");
|
||||
}
|
||||
@@ -1,75 +0,0 @@
|
||||
This software is covered under the following copyright:
|
||||
|
||||
/*
|
||||
* Copyright (c) 2007 Henri Torgemane
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* BigInteger, RSA, Random and ARC4 are derivative works of the jsbn library
|
||||
* (http://www-cs-students.stanford.edu/~tjw/jsbn/)
|
||||
* The jsbn library is Copyright (c) 2003-2005 Tom Wu (tjw@cs.Stanford.EDU)
|
||||
*
|
||||
* MD5, SHA1, and SHA256 are derivative works (http://pajhome.org.uk/crypt/md5/)
|
||||
* Those are Copyright (c) 1998-2002 Paul Johnston & Contributors (paj@pajhome.org.uk)
|
||||
*
|
||||
* SHA256 is a derivative work of jsSHA2 (http://anmar.eu.org/projects/jssha2/)
|
||||
* jsSHA2 is Copyright (c) 2003-2004 Angel Marin (anmar@gmx.net)
|
||||
*
|
||||
* AESKey is a derivative work of aestable.c (http://www.geocities.com/malbrain/aestable_c.html)
|
||||
* aestable.c is Copyright (c) Karl Malbrain (malbrain@yahoo.com)
|
||||
*
|
||||
* BlowFishKey, DESKey and TripeDESKey are derivative works of the Bouncy Castle Crypto Package (http://www.bouncycastle.org)
|
||||
* Those are Copyright (c) 2000-2004 The Legion Of The Bouncy Castle
|
||||
*
|
||||
* Base64 is copyright (c) 2006 Steve Webster (http://dynamicflash.com/goodies/base64)
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice, this list
|
||||
* of conditions and the following disclaimer. Redistributions in binary form must
|
||||
* reproduce the above copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* Neither the name of the author nor the names of its contributors may be used to endorse
|
||||
* or promote products derived from this software without specific prior written permission.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
|
||||
* WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* IN NO EVENT SHALL TOM WU BE LIABLE FOR ANY SPECIAL, INCIDENTAL,
|
||||
* INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER
|
||||
* RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT ADVISED OF
|
||||
* THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF LIABILITY, ARISING OUT
|
||||
* OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
Address all questions regarding this license to:
|
||||
|
||||
Henri Torgemane
|
||||
henri_torgemane@yahoo.com
|
||||
|
||||
|
||||
Additionally, the MD5 algorithm is covered by the following notice:
|
||||
|
||||
/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All rights reserved.
|
||||
*
|
||||
* License to copy and use this software is granted provided that it
|
||||
* is identified as the "RSA Data Security, Inc. MD5 Message-Digest
|
||||
* Algorithm" in all material mentioning or referencing this software
|
||||
* or this function.
|
||||
*
|
||||
* License is also granted to make and use derivative works provided
|
||||
* that such works are identified as "derived from the RSA Data
|
||||
* Security, Inc. MD5 Message-Digest Algorithm" in all material
|
||||
* mentioning or referencing the derived work.
|
||||
*
|
||||
* RSA Data Security, Inc. makes no representations concerning either
|
||||
* the merchantability of this software or the suitability of this
|
||||
* software for any particular purpose. It is provided "as is"
|
||||
* without express or implied warranty of any kind.
|
||||
*
|
||||
* These notices must be retained in any copies of any part of this
|
||||
* documentation and/or software.
|
||||
*/
|
||||
@@ -1,13 +0,0 @@
|
||||
|
||||
= DESCRIPTION
|
||||
|
||||
as3crypto 1.3 has some bugs, at r28(latest version of original svn-repository),
|
||||
many of them are fixed, but there are another bugs around a new ASN1 parser.
|
||||
so I copied some features from r28 to 1.3
|
||||
version, and fixed them to be built without error.
|
||||
and added build-swc.xml
|
||||
|
||||
= LICENSE
|
||||
|
||||
See LICENCE.txt,
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
require 'rubygems'
|
||||
require 'airake'
|
||||
|
||||
ENV["AIRAKE_ROOT"] = File.dirname(__FILE__)
|
||||
ENV["AIRAKE_ENV"] = "development"
|
||||
|
||||
# Aliases
|
||||
task :test => [ "air:test" ] do; end
|
||||
task :compile => [ "air:compile" ] do; end
|
||||
task :package => [ "air:package" ] do; end
|
||||
task :certificate => [ "air:certificate" ] do; end
|
||||
task :adl => [ "air:adl" ] do; end
|
||||
task :docs => [ "air:docs" ] do; end
|
||||
task :clean => [ "air:clean" ] do; end
|
||||
task :acompc => [ "air:acompc" ] do; end
|
||||
@@ -1,21 +0,0 @@
|
||||
---
|
||||
mxml_path: src/As3crypto.mxml
|
||||
appxml_path: src/As3crypto-app.xml
|
||||
|
||||
src_dirs: [ 'src' ]
|
||||
lib_dir: lib
|
||||
|
||||
air_path: bin/As3crypto.air
|
||||
swf_path: bin/As3crypto.swf
|
||||
assets: src/assets
|
||||
certificate: cert.pfx
|
||||
|
||||
development:
|
||||
debug: true
|
||||
|
||||
test:
|
||||
swf_path: bin/Test.swf
|
||||
mxml_path: test/Test.mxml
|
||||
appxml_path: test/Test-app.xml
|
||||
src_dirs: [ 'src', 'test' ]
|
||||
debug: true
|
||||
Binary file not shown.
@@ -1,109 +0,0 @@
|
||||
<!--
|
||||
To build as3crypto.swc, use
|
||||
|
||||
compc -load-config=build-swc.xml
|
||||
|
||||
If you need Flash Player 9 support, change the path below to something more
|
||||
appropriate for your SDK and/or Player version
|
||||
-->
|
||||
<flex-config>
|
||||
<benchmark>true</benchmark>
|
||||
<compiler>
|
||||
<external-library-path>
|
||||
<path-element>${flexlib}/libs/player/10.0/playerglobal.swc</path-element>
|
||||
</external-library-path>
|
||||
<source-path>
|
||||
<path-element>./src</path-element>
|
||||
</source-path>
|
||||
</compiler>
|
||||
<include-classes>
|
||||
<class>com.hurlant.crypto.Crypto</class>
|
||||
<class>com.hurlant.crypto.cert.MozillaRootCertificates</class>
|
||||
<class>com.hurlant.crypto.cert.X509Certificate</class>
|
||||
<class>com.hurlant.crypto.cert.X509CertificateCollection</class>
|
||||
<class>com.hurlant.crypto.hash.HMAC</class>
|
||||
<class>com.hurlant.crypto.hash.IHMAC</class>
|
||||
<class>com.hurlant.crypto.hash.IHash</class>
|
||||
<class>com.hurlant.crypto.hash.MAC</class>
|
||||
<class>com.hurlant.crypto.hash.MD2</class>
|
||||
<class>com.hurlant.crypto.hash.MD5</class>
|
||||
<class>com.hurlant.crypto.hash.SHA1</class>
|
||||
<class>com.hurlant.crypto.hash.SHA224</class>
|
||||
<class>com.hurlant.crypto.hash.SHA256</class>
|
||||
<class>com.hurlant.crypto.hash.SHABase</class>
|
||||
<class>com.hurlant.crypto.prng.ARC4</class>
|
||||
<class>com.hurlant.crypto.prng.IPRNG</class>
|
||||
<class>com.hurlant.crypto.prng.Random</class>
|
||||
<class>com.hurlant.crypto.prng.TLSPRF</class>
|
||||
<class>com.hurlant.crypto.rsa.RSAKey</class>
|
||||
<class>com.hurlant.crypto.symmetric.AESKey</class>
|
||||
<class>com.hurlant.crypto.symmetric.BlowFishKey</class>
|
||||
<class>com.hurlant.crypto.symmetric.CBCMode</class>
|
||||
<class>com.hurlant.crypto.symmetric.CFB8Mode</class>
|
||||
<class>com.hurlant.crypto.symmetric.CFBMode</class>
|
||||
<class>com.hurlant.crypto.symmetric.CTRMode</class>
|
||||
<class>com.hurlant.crypto.symmetric.DESKey</class>
|
||||
<class>com.hurlant.crypto.symmetric.ECBMode</class>
|
||||
<class>com.hurlant.crypto.symmetric.ICipher</class>
|
||||
<class>com.hurlant.crypto.symmetric.IMode</class>
|
||||
<class>com.hurlant.crypto.symmetric.IPad</class>
|
||||
<class>com.hurlant.crypto.symmetric.IStreamCipher</class>
|
||||
<class>com.hurlant.crypto.symmetric.ISymmetricKey</class>
|
||||
<class>com.hurlant.crypto.symmetric.IVMode</class>
|
||||
<class>com.hurlant.crypto.symmetric.NullPad</class>
|
||||
<class>com.hurlant.crypto.symmetric.OFBMode</class>
|
||||
<class>com.hurlant.crypto.symmetric.PKCS5</class>
|
||||
<class>com.hurlant.crypto.symmetric.SimpleIVMode</class>
|
||||
<class>com.hurlant.crypto.symmetric.TLSPad</class>
|
||||
<class>com.hurlant.crypto.symmetric.SSLPad</class>
|
||||
<class>com.hurlant.crypto.symmetric.TripleDESKey</class>
|
||||
<class>com.hurlant.crypto.symmetric.XTeaKey</class>
|
||||
<class>com.hurlant.crypto.tls.BulkCiphers</class>
|
||||
<class>com.hurlant.crypto.tls.CipherSuites</class>
|
||||
<class>com.hurlant.crypto.tls.KeyExchanges</class>
|
||||
<class>com.hurlant.crypto.tls.MACs</class>
|
||||
<class>com.hurlant.crypto.tls.TLSConfig</class>
|
||||
<class>com.hurlant.crypto.tls.IConnectionState</class>
|
||||
<class>com.hurlant.crypto.tls.TLSConnectionState</class>
|
||||
<class>com.hurlant.crypto.tls.SSLConnectionState</class>
|
||||
<class>com.hurlant.crypto.tls.TLSEngine</class>
|
||||
<class>com.hurlant.crypto.tls.TLSError</class>
|
||||
<class>com.hurlant.crypto.tls.TLSSocketEvent</class>
|
||||
<class>com.hurlant.crypto.tls.TLSEvent</class>
|
||||
<class>com.hurlant.crypto.tls.SSLEvent</class>
|
||||
<class>com.hurlant.crypto.tls.ISecurityParameters</class>
|
||||
<class>com.hurlant.crypto.tls.TLSSecurityParameters</class>
|
||||
<class>com.hurlant.crypto.tls.SSLSecurityParameters</class>
|
||||
<class>com.hurlant.crypto.tls.TLSSocket</class>
|
||||
<class>com.hurlant.util.ArrayUtil</class>
|
||||
<class>com.hurlant.util.Base64</class>
|
||||
<class>com.hurlant.util.Hex</class>
|
||||
<class>com.hurlant.util.Memory</class>
|
||||
<class>com.hurlant.util.der.ByteString</class>
|
||||
<class>com.hurlant.util.der.DER</class>
|
||||
<class>com.hurlant.util.der.IAsn1Type</class>
|
||||
<class>com.hurlant.util.der.Integer</class>
|
||||
<class>com.hurlant.util.der.OID</class>
|
||||
<class>com.hurlant.util.der.ObjectIdentifier</class>
|
||||
<class>com.hurlant.util.der.PEM</class>
|
||||
<class>com.hurlant.util.der.PrintableString</class>
|
||||
<class>com.hurlant.util.der.Sequence</class>
|
||||
<class>com.hurlant.util.der.Set</class>
|
||||
<class>com.hurlant.util.der.Type</class>
|
||||
<class>com.hurlant.util.der.UTCTime</class>
|
||||
<class>com.hurlant.math.BarrettReduction</class>
|
||||
<class>com.hurlant.math.BigInteger</class>
|
||||
<class>com.hurlant.math.ClassicReduction</class>
|
||||
<class>com.hurlant.math.IReduction</class>
|
||||
<class>com.hurlant.math.MontgomeryReduction</class>
|
||||
<class>com.hurlant.math.NullReduction</class>
|
||||
<class>com.hurlant.math.bi_internal</class>
|
||||
</include-classes>
|
||||
<metadata>
|
||||
<creator>Henri Torgemane</creator>
|
||||
<description>http://crypto.hurlant.com/</description>
|
||||
<language>EN</language>
|
||||
<title>AS3 Cryptography Library</title>
|
||||
</metadata>
|
||||
<output>bin/as3crypto_patched.swc</output>
|
||||
</flex-config>
|
||||
Binary file not shown.
Binary file not shown.
@@ -1,14 +0,0 @@
|
||||
#!/usr/bin/env ruby
|
||||
APP_ROOT = File.expand_path(File.join(File.dirname(__FILE__), '..'))
|
||||
|
||||
begin
|
||||
require 'rubigen'
|
||||
rescue LoadError
|
||||
require 'rubygems'
|
||||
require 'rubigen'
|
||||
end
|
||||
require 'rubigen/scripts/destroy'
|
||||
|
||||
ARGV.shift if ['--help', '-h'].include?(ARGV[0])
|
||||
RubiGen::Base.use_component_sources! [:air, :airake, :test_unit]
|
||||
RubiGen::Scripts::Destroy.new.run(ARGV)
|
||||
@@ -1,14 +0,0 @@
|
||||
#!/usr/bin/env ruby
|
||||
APP_ROOT = File.expand_path(File.join(File.dirname(__FILE__), '..'))
|
||||
|
||||
begin
|
||||
require 'rubigen'
|
||||
rescue LoadError
|
||||
require 'rubygems'
|
||||
require 'rubigen'
|
||||
end
|
||||
require 'rubigen/scripts/generate'
|
||||
|
||||
ARGV.shift if ['--help', '-h'].include?(ARGV[0])
|
||||
RubiGen::Base.use_component_sources! [:air, :airake, :test_unit]
|
||||
RubiGen::Scripts::Generate.new.run(ARGV)
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 16 KiB |
@@ -1,287 +0,0 @@
|
||||
/**
|
||||
* Crypto
|
||||
*
|
||||
* An abstraction layer to instanciate our crypto algorithms
|
||||
* Copyright (c) 2007 Henri Torgemane
|
||||
*
|
||||
* See LICENSE.txt for full license information.
|
||||
*/
|
||||
package com.hurlant.crypto
|
||||
{
|
||||
import com.hurlant.crypto.hash.HMAC;
|
||||
import com.hurlant.crypto.hash.MAC;
|
||||
import com.hurlant.crypto.hash.IHash;
|
||||
import com.hurlant.crypto.hash.MD2;
|
||||
import com.hurlant.crypto.hash.MD5;
|
||||
import com.hurlant.crypto.hash.SHA1;
|
||||
import com.hurlant.crypto.hash.SHA224;
|
||||
import com.hurlant.crypto.hash.SHA256;
|
||||
import com.hurlant.crypto.prng.ARC4;
|
||||
import com.hurlant.crypto.rsa.RSAKey;
|
||||
import com.hurlant.crypto.symmetric.AESKey;
|
||||
import com.hurlant.crypto.symmetric.BlowFishKey;
|
||||
import com.hurlant.crypto.symmetric.CBCMode;
|
||||
import com.hurlant.crypto.symmetric.CFB8Mode;
|
||||
import com.hurlant.crypto.symmetric.CFBMode;
|
||||
import com.hurlant.crypto.symmetric.CTRMode;
|
||||
import com.hurlant.crypto.symmetric.DESKey;
|
||||
import com.hurlant.crypto.symmetric.ECBMode;
|
||||
import com.hurlant.crypto.symmetric.ICipher;
|
||||
import com.hurlant.crypto.symmetric.IMode;
|
||||
import com.hurlant.crypto.symmetric.IPad;
|
||||
import com.hurlant.crypto.symmetric.ISymmetricKey;
|
||||
import com.hurlant.crypto.symmetric.IVMode;
|
||||
import com.hurlant.crypto.symmetric.NullPad;
|
||||
import com.hurlant.crypto.symmetric.OFBMode;
|
||||
import com.hurlant.crypto.symmetric.PKCS5;
|
||||
import com.hurlant.crypto.symmetric.SimpleIVMode;
|
||||
import com.hurlant.crypto.symmetric.TripleDESKey;
|
||||
import com.hurlant.crypto.symmetric.XTeaKey;
|
||||
import com.hurlant.util.Base64;
|
||||
|
||||
import flash.utils.ByteArray;
|
||||
|
||||
/**
|
||||
* A class to make it easy to use the rest of the framework.
|
||||
* As a side-effect, using this class will cause most of the framework
|
||||
* to be linked into your application, which is not always what you want.
|
||||
*
|
||||
* If you want to optimize your download size, don't use this class.
|
||||
* (But feel free to read it to get ideas on how to get the algorithm you want.)
|
||||
*/
|
||||
public class Crypto
|
||||
{
|
||||
private var b64:Base64; // we don't use it, but we want the swc to include it, so cheap trick.
|
||||
|
||||
public function Crypto(){
|
||||
}
|
||||
|
||||
/**
|
||||
* Things that should work, among others:
|
||||
* "aes"
|
||||
* "aes-128-ecb"
|
||||
* "aes-128-cbc"
|
||||
* "aes-128-cfb"
|
||||
* "aes-128-cfb8"
|
||||
* "aes-128-ofb"
|
||||
* "aes-192-cfb"
|
||||
* "aes-256-ofb"
|
||||
* "blowfish-cbc"
|
||||
* "des-ecb"
|
||||
* "xtea"
|
||||
* "xtea-ecb"
|
||||
* "xtea-cbc"
|
||||
* "xtea-cfb"
|
||||
* "xtea-cfb8"
|
||||
* "xtea-ofb"
|
||||
* "rc4"
|
||||
* "simple-aes-cbc"
|
||||
*/
|
||||
public static function getCipher(name:String, key:ByteArray, pad:IPad=null):ICipher {
|
||||
// split name into an array.
|
||||
var keys:Array = name.split("-");
|
||||
switch (keys[0]) {
|
||||
/**
|
||||
* "simple" is a special case. It means:
|
||||
* "If using an IV mode, prepend the IV to the ciphertext"
|
||||
*/
|
||||
case "simple":
|
||||
keys.shift();
|
||||
name = keys.join("-");
|
||||
var cipher:ICipher = getCipher(name, key, pad);
|
||||
if (cipher is IVMode) {
|
||||
return new SimpleIVMode(cipher as IVMode);
|
||||
} else {
|
||||
return cipher;
|
||||
}
|
||||
/**
|
||||
* we support both "aes-128" and "aes128"
|
||||
* Technically, you could use "aes192-128", but you'd
|
||||
* only be hurting yourself.
|
||||
*/
|
||||
case "aes":
|
||||
case "aes128":
|
||||
case "aes192":
|
||||
case "aes256":
|
||||
keys.shift();
|
||||
if (key.length*8==keys[0]) {
|
||||
// support for "aes-128-..." and such.
|
||||
keys.shift();
|
||||
}
|
||||
return getMode(keys[0], new AESKey(key), pad);
|
||||
break;
|
||||
case "bf":
|
||||
case "blowfish":
|
||||
keys.shift();
|
||||
return getMode(keys[0], new BlowFishKey(key), pad);
|
||||
/**
|
||||
* des-ede and des-ede3 are both equivalent to des3.
|
||||
* the choice between 2tdes and 3tdes is made based
|
||||
* on the length of the key provided.
|
||||
*/
|
||||
case "des":
|
||||
keys.shift();
|
||||
if (keys[0]!="ede" && keys[0]!="ede3") {
|
||||
return getMode(keys[0], new DESKey(key), pad);
|
||||
}
|
||||
if (keys.length==1) {
|
||||
keys.push("ecb"); // default mode for 2tdes and 3tdes with openssl enc
|
||||
}
|
||||
// fall-through to triple des
|
||||
case "3des":
|
||||
case "des3":
|
||||
keys.shift();
|
||||
return getMode(keys[0], new TripleDESKey(key), pad);
|
||||
case "xtea":
|
||||
keys.shift();
|
||||
return getMode(keys[0], new XTeaKey(key), pad);
|
||||
break;
|
||||
/**
|
||||
* Technically, you could say "rc4-128" or whatever,
|
||||
* but really, the length of the key is what counts here.
|
||||
*/
|
||||
case "rc4":
|
||||
keys.shift();
|
||||
return new ARC4(key);
|
||||
break;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the size of a key for a given cipher identifier.
|
||||
*/
|
||||
public static function getKeySize(name:String):uint {
|
||||
var keys:Array = name.split("-");
|
||||
switch (keys[0]) {
|
||||
case "simple":
|
||||
keys.shift();
|
||||
return getKeySize(keys.join("-"));
|
||||
case "aes128":
|
||||
return 16;
|
||||
case "aes192":
|
||||
return 24;
|
||||
case "aes256":
|
||||
return 32;
|
||||
case "aes":
|
||||
keys.shift();
|
||||
return parseInt(keys[0])/8;
|
||||
case "bf":
|
||||
case "blowfish":
|
||||
return 16;
|
||||
case "des":
|
||||
keys.shift();
|
||||
switch (keys[0]) {
|
||||
case "ede":
|
||||
return 16;
|
||||
case "ede3":
|
||||
return 24;
|
||||
default:
|
||||
return 8;
|
||||
}
|
||||
case "3des":
|
||||
case "des3":
|
||||
return 24;
|
||||
case "xtea":
|
||||
return 8;
|
||||
case "rc4":
|
||||
if (parseInt(keys[1])>0) {
|
||||
return parseInt(keys[1])/8;
|
||||
}
|
||||
return 16; // why not.
|
||||
}
|
||||
return 0; // unknown;
|
||||
}
|
||||
|
||||
private static function getMode(name:String, alg:ISymmetricKey, padding:IPad=null):IMode {
|
||||
switch (name) {
|
||||
case "ecb":
|
||||
return new ECBMode(alg, padding);
|
||||
case "cfb":
|
||||
return new CFBMode(alg, padding);
|
||||
case "cfb8":
|
||||
return new CFB8Mode(alg, padding);
|
||||
case "ofb":
|
||||
return new OFBMode(alg, padding);
|
||||
case "ctr":
|
||||
return new CTRMode(alg, padding);
|
||||
case "cbc":
|
||||
default:
|
||||
return new CBCMode(alg, padding);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Things that should work:
|
||||
* "md5"
|
||||
* "sha"
|
||||
* "sha1"
|
||||
* "sha224"
|
||||
* "sha256"
|
||||
*/
|
||||
public static function getHash(name:String):IHash {
|
||||
switch(name) {
|
||||
case "md2":
|
||||
return new MD2;
|
||||
case "md5":
|
||||
return new MD5;
|
||||
case "sha": // let's hope you didn't mean sha-0
|
||||
case "sha1":
|
||||
return new SHA1;
|
||||
case "sha224":
|
||||
return new SHA224;
|
||||
case "sha256":
|
||||
return new SHA256;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Things that should work:
|
||||
* "sha1"
|
||||
* "md5-64"
|
||||
* "hmac-md5-96"
|
||||
* "hmac-sha1-128"
|
||||
* "hmac-sha256-192"
|
||||
* etc.
|
||||
*/
|
||||
public static function getHMAC(name:String):HMAC {
|
||||
var keys:Array = name.split("-");
|
||||
if (keys[0]=="hmac") keys.shift();
|
||||
var bits:uint = 0;
|
||||
if (keys.length>1) {
|
||||
bits = parseInt(keys[1]);
|
||||
}
|
||||
return new HMAC(getHash(keys[0]), bits);
|
||||
}
|
||||
|
||||
|
||||
public static function getMAC(name:String):MAC {
|
||||
|
||||
var keys:Array = name.split("-");
|
||||
if (keys[0]=="mac") keys.shift();
|
||||
var bits:uint = 0;
|
||||
if (keys.length > 1) {
|
||||
bits = parseInt(keys[1]);
|
||||
}
|
||||
return new MAC(getHash(keys[0]), bits);
|
||||
}
|
||||
|
||||
|
||||
public static function getPad(name:String):IPad {
|
||||
switch(name) {
|
||||
case "null":
|
||||
return new NullPad;
|
||||
case "pkcs5":
|
||||
default:
|
||||
return new PKCS5;
|
||||
}
|
||||
}
|
||||
|
||||
/** mostly useless.
|
||||
*/
|
||||
public static function getRSA(E:String, M:String):RSAKey {
|
||||
return RSAKey.parsePublicKey(M,E);
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,218 +0,0 @@
|
||||
/**
|
||||
* X509Certificate
|
||||
*
|
||||
* A representation for a X509 Certificate, with
|
||||
* methods to parse, verify and sign it.
|
||||
* Copyright (c) 2007 Henri Torgemane
|
||||
*
|
||||
* See LICENSE.txt for full license information.
|
||||
*/
|
||||
package com.hurlant.crypto.cert {
|
||||
import com.hurlant.crypto.hash.IHash;
|
||||
import com.hurlant.crypto.hash.MD2;
|
||||
import com.hurlant.crypto.hash.MD5;
|
||||
import com.hurlant.crypto.hash.SHA1;
|
||||
import com.hurlant.crypto.rsa.RSAKey;
|
||||
import com.hurlant.util.ArrayUtil;
|
||||
import com.hurlant.util.Base64;
|
||||
import com.hurlant.util.der.ByteString;
|
||||
import com.hurlant.util.der.DER;
|
||||
import com.hurlant.util.der.OID;
|
||||
import com.hurlant.util.der.ObjectIdentifier;
|
||||
import com.hurlant.util.der.PEM;
|
||||
import com.hurlant.util.der.PrintableString;
|
||||
import com.hurlant.util.der.Sequence;
|
||||
import com.hurlant.util.der.Type;
|
||||
|
||||
import flash.utils.ByteArray;
|
||||
|
||||
public class X509Certificate {
|
||||
private var _loaded:Boolean;
|
||||
private var _param:*;
|
||||
private var _obj:Object;
|
||||
public function X509Certificate(p:*) {
|
||||
_loaded = false;
|
||||
_param = p;
|
||||
// lazy initialization, to avoid unnecessary parsing of every builtin CA at start-up.
|
||||
}
|
||||
private function load():void {
|
||||
if (_loaded) return;
|
||||
var p:* = _param;
|
||||
var b:ByteArray;
|
||||
if (p is String) {
|
||||
b = PEM.readCertIntoArray(p as String);
|
||||
} else if (p is ByteArray) {
|
||||
b = p;
|
||||
}
|
||||
if (b!=null) {
|
||||
_obj = DER.parse(b, Type.TLS_CERT);
|
||||
_loaded = true;
|
||||
} else {
|
||||
throw new Error("Invalid x509 Certificate parameter: "+p);
|
||||
}
|
||||
}
|
||||
public function isSigned(store:X509CertificateCollection, CAs:X509CertificateCollection, time:Date=null):Boolean {
|
||||
load();
|
||||
// check timestamps first. cheapest.
|
||||
if (time==null) {
|
||||
time = new Date;
|
||||
}
|
||||
var notBefore:Date = getNotBefore();
|
||||
var notAfter:Date = getNotAfter();
|
||||
if (time.getTime()<notBefore.getTime()) return false; // cert isn't born yet.
|
||||
if (time.getTime()>notAfter.getTime()) return false; // cert died of old age.
|
||||
// check signature.
|
||||
var subject:String = getIssuerPrincipal();
|
||||
// try from CA first, since they're treated better.
|
||||
var parent:X509Certificate = CAs.getCertificate(subject);
|
||||
var parentIsAuthoritative:Boolean = false;
|
||||
if (parent == null) {
|
||||
parent = store.getCertificate(subject);
|
||||
if (parent == null) {
|
||||
return false; // issuer not found
|
||||
}
|
||||
} else {
|
||||
parentIsAuthoritative = true;
|
||||
}
|
||||
if (parent == this) { // pathological case. avoid infinite loop
|
||||
return false; // isSigned() returns false if we're self-signed.
|
||||
}
|
||||
if (!(parentIsAuthoritative&&parent.isSelfSigned(time)) &&
|
||||
!parent.isSigned(store, CAs, time)) {
|
||||
return false;
|
||||
}
|
||||
var key:RSAKey = parent.getPublicKey();
|
||||
return verifyCertificate(key);
|
||||
}
|
||||
public function isSelfSigned(time:Date):Boolean {
|
||||
load();
|
||||
|
||||
var key:RSAKey = getPublicKey();
|
||||
return verifyCertificate(key);
|
||||
}
|
||||
private function verifyCertificate(key:RSAKey):Boolean {
|
||||
var algo:String = getAlgorithmIdentifier();
|
||||
var hash:IHash;
|
||||
var oid:String;
|
||||
switch (algo) {
|
||||
case OID.SHA1_WITH_RSA_ENCRYPTION:
|
||||
hash = new SHA1;
|
||||
oid = OID.SHA1_ALGORITHM;
|
||||
break;
|
||||
case OID.MD2_WITH_RSA_ENCRYPTION:
|
||||
hash = new MD2;
|
||||
oid = OID.MD2_ALGORITHM;
|
||||
break;
|
||||
case OID.MD5_WITH_RSA_ENCRYPTION:
|
||||
hash = new MD5;
|
||||
oid = OID.MD5_ALGORITHM;
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
var data:ByteArray = _obj.signedCertificate_bin;
|
||||
var buf:ByteArray = new ByteArray;
|
||||
key.verify(_obj.encrypted, buf, _obj.encrypted.length);
|
||||
buf.position=0;
|
||||
data = hash.hash(data);
|
||||
var obj:Object = DER.parse(buf, Type.RSA_SIGNATURE);
|
||||
if (obj.algorithm.algorithmId.toString() != oid) {
|
||||
return false; // wrong algorithm
|
||||
}
|
||||
if (!ArrayUtil.equals(obj.hash, data)) {
|
||||
return false; // hashes don't match
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* This isn't used anywhere so far.
|
||||
* It would become useful if we started to offer facilities
|
||||
* to generate and sign X509 certificates.
|
||||
*
|
||||
* @param key
|
||||
* @param algo
|
||||
* @return
|
||||
*
|
||||
*/
|
||||
private function signCertificate(key:RSAKey, algo:String):ByteArray {
|
||||
var hash:IHash;
|
||||
var oid:String;
|
||||
switch (algo) {
|
||||
case OID.SHA1_WITH_RSA_ENCRYPTION:
|
||||
hash = new SHA1;
|
||||
oid = OID.SHA1_ALGORITHM;
|
||||
break;
|
||||
case OID.MD2_WITH_RSA_ENCRYPTION:
|
||||
hash = new MD2;
|
||||
oid = OID.MD2_ALGORITHM;
|
||||
break;
|
||||
case OID.MD5_WITH_RSA_ENCRYPTION:
|
||||
hash = new MD5;
|
||||
oid = OID.MD5_ALGORITHM;
|
||||
break;
|
||||
default:
|
||||
return null
|
||||
}
|
||||
var data:ByteArray = _obj.signedCertificate_bin;
|
||||
data = hash.hash(data);
|
||||
var seq1:Sequence = new Sequence;
|
||||
seq1[0] = new Sequence;
|
||||
seq1[0][0] = new ObjectIdentifier(0,0, oid);
|
||||
seq1[0][1] = null;
|
||||
seq1[1] = new ByteString;
|
||||
seq1[1].writeBytes(data);
|
||||
data = seq1.toDER();
|
||||
var buf:ByteArray = new ByteArray;
|
||||
key.sign(data, buf, data.length);
|
||||
return buf;
|
||||
}
|
||||
|
||||
public function getPublicKey():RSAKey {
|
||||
load();
|
||||
var pk:ByteArray = _obj.signedCertificate.subjectPublicKeyInfo.subjectPublicKey as ByteArray;
|
||||
pk.position = 0;
|
||||
var rsaKey:Object = DER.parse(pk, [{name:"N"},{name:"E"}]);
|
||||
return new RSAKey(rsaKey.N, rsaKey.E.valueOf());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a subject principal, as an opaque base64 string.
|
||||
* This is only used as a hash key for known certificates.
|
||||
*
|
||||
* Note that this assumes X509 DER-encoded certificates are uniquely encoded,
|
||||
* as we look for exact matches between Issuer and Subject fields.
|
||||
*
|
||||
*/
|
||||
public function getSubjectPrincipal():String {
|
||||
load();
|
||||
return Base64.encodeByteArray(_obj.signedCertificate.subject_bin);
|
||||
}
|
||||
/**
|
||||
* Returns an issuer principal, as an opaque base64 string.
|
||||
* This is only used to quickly find matching parent certificates.
|
||||
*
|
||||
* Note that this assumes X509 DER-encoded certificates are uniquely encoded,
|
||||
* as we look for exact matches between Issuer and Subject fields.
|
||||
*
|
||||
*/
|
||||
public function getIssuerPrincipal():String {
|
||||
load();
|
||||
return Base64.encodeByteArray(_obj.signedCertificate.issuer_bin);
|
||||
}
|
||||
public function getAlgorithmIdentifier():String {
|
||||
return _obj.algorithmIdentifier.algorithmId.toString();
|
||||
}
|
||||
public function getNotBefore():Date {
|
||||
return _obj.signedCertificate.validity.notBefore.date;
|
||||
}
|
||||
public function getNotAfter():Date {
|
||||
return _obj.signedCertificate.validity.notAfter.date;
|
||||
}
|
||||
|
||||
public function getCommonName():String {
|
||||
var subject:Sequence = _obj.signedCertificate.subject;
|
||||
return (subject.findAttributeValue(OID.COMMON_NAME) as PrintableString).getString();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,57 +0,0 @@
|
||||
/**
|
||||
* X509CertificateCollection
|
||||
*
|
||||
* A class to store and index X509 Certificates by Subject.
|
||||
* Copyright (c) 2007 Henri Torgemane
|
||||
*
|
||||
* See LICENSE.txt for full license information.
|
||||
*/
|
||||
package com.hurlant.crypto.cert {
|
||||
|
||||
public class X509CertificateCollection {
|
||||
|
||||
private var _map:Object;
|
||||
|
||||
public function X509CertificateCollection() {
|
||||
_map = {};
|
||||
}
|
||||
|
||||
/**
|
||||
* Mostly meant for built-in CA loading.
|
||||
* This entry-point allows to index CAs without parsing them.
|
||||
*
|
||||
* @param name A friendly name. not currently used
|
||||
* @param subject base64 DER encoded Subject principal for the Cert
|
||||
* @param pem PEM encoded certificate data
|
||||
*
|
||||
*/
|
||||
public function addPEMCertificate(name:String, subject:String, pem:String):void {
|
||||
_map[subject] = new X509Certificate(pem);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a X509 certificate to the collection.
|
||||
* This call will force the certificate to be parsed.
|
||||
*
|
||||
* @param cert A X509 certificate
|
||||
*
|
||||
*/
|
||||
public function addCertificate(cert:X509Certificate):void {
|
||||
var subject:String = cert.getSubjectPrincipal();
|
||||
_map[subject] = cert;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a X509 Certificate present in the collection, given
|
||||
* a base64 DER encoded X500 Subject principal
|
||||
*
|
||||
* @param subject A Base64 DER-encoded Subject principal
|
||||
* @return A matching certificate, or null.
|
||||
*
|
||||
*/
|
||||
public function getCertificate(subject:String):X509Certificate {
|
||||
return _map[subject];
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,65 +0,0 @@
|
||||
K 25
|
||||
svn:wc:ra_dav:version-url
|
||||
V 60
|
||||
/svn/!svn/ver/28/trunk/as3crypto/src/com/hurlant/crypto/hash
|
||||
END
|
||||
MAC.as
|
||||
K 25
|
||||
svn:wc:ra_dav:version-url
|
||||
V 67
|
||||
/svn/!svn/ver/28/trunk/as3crypto/src/com/hurlant/crypto/hash/MAC.as
|
||||
END
|
||||
IHMAC.as
|
||||
K 25
|
||||
svn:wc:ra_dav:version-url
|
||||
V 69
|
||||
/svn/!svn/ver/28/trunk/as3crypto/src/com/hurlant/crypto/hash/IHMAC.as
|
||||
END
|
||||
MD2.as
|
||||
K 25
|
||||
svn:wc:ra_dav:version-url
|
||||
V 67
|
||||
/svn/!svn/ver/28/trunk/as3crypto/src/com/hurlant/crypto/hash/MD2.as
|
||||
END
|
||||
SHA224.as
|
||||
K 25
|
||||
svn:wc:ra_dav:version-url
|
||||
V 69
|
||||
/svn/!svn/ver/3/trunk/as3crypto/src/com/hurlant/crypto/hash/SHA224.as
|
||||
END
|
||||
MD5.as
|
||||
K 25
|
||||
svn:wc:ra_dav:version-url
|
||||
V 67
|
||||
/svn/!svn/ver/28/trunk/as3crypto/src/com/hurlant/crypto/hash/MD5.as
|
||||
END
|
||||
SHABase.as
|
||||
K 25
|
||||
svn:wc:ra_dav:version-url
|
||||
V 71
|
||||
/svn/!svn/ver/28/trunk/as3crypto/src/com/hurlant/crypto/hash/SHABase.as
|
||||
END
|
||||
SHA256.as
|
||||
K 25
|
||||
svn:wc:ra_dav:version-url
|
||||
V 70
|
||||
/svn/!svn/ver/28/trunk/as3crypto/src/com/hurlant/crypto/hash/SHA256.as
|
||||
END
|
||||
HMAC.as
|
||||
K 25
|
||||
svn:wc:ra_dav:version-url
|
||||
V 68
|
||||
/svn/!svn/ver/28/trunk/as3crypto/src/com/hurlant/crypto/hash/HMAC.as
|
||||
END
|
||||
IHash.as
|
||||
K 25
|
||||
svn:wc:ra_dav:version-url
|
||||
V 69
|
||||
/svn/!svn/ver/28/trunk/as3crypto/src/com/hurlant/crypto/hash/IHash.as
|
||||
END
|
||||
SHA1.as
|
||||
K 25
|
||||
svn:wc:ra_dav:version-url
|
||||
V 68
|
||||
/svn/!svn/ver/28/trunk/as3crypto/src/com/hurlant/crypto/hash/SHA1.as
|
||||
END
|
||||
@@ -1,368 +0,0 @@
|
||||
10
|
||||
|
||||
dir
|
||||
28
|
||||
http://as3crypto.googlecode.com/svn/trunk/as3crypto/src/com/hurlant/crypto/hash
|
||||
http://as3crypto.googlecode.com/svn
|
||||
|
||||
|
||||
|
||||
2009-06-04T23:35:21.192697Z
|
||||
28
|
||||
sh0rtwave
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
395c722c-794e-0410-9327-f1aa524df581
|
||||
|
||||
MAC.as
|
||||
file
|
||||
|
||||
|
||||
|
||||
|
||||
2009-11-07T06:59:45.000000Z
|
||||
0bedba9be73ae40adeb26ca35c8237f4
|
||||
2009-06-04T23:35:21.192697Z
|
||||
28
|
||||
sh0rtwave
|
||||
has-props
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
3559
|
||||
|
||||
IHMAC.as
|
||||
file
|
||||
|
||||
|
||||
|
||||
|
||||
2009-11-07T06:59:45.000000Z
|
||||
dac8b7d8c849fe11f90ec290aa5dedf0
|
||||
2009-06-04T23:35:21.192697Z
|
||||
28
|
||||
sh0rtwave
|
||||
has-props
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
599
|
||||
|
||||
MD2.as
|
||||
file
|
||||
|
||||
|
||||
|
||||
|
||||
2009-11-07T06:59:45.000000Z
|
||||
73bf759d445a65186512066a103dbb45
|
||||
2009-06-04T23:35:21.192697Z
|
||||
28
|
||||
sh0rtwave
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
3811
|
||||
|
||||
SHA224.as
|
||||
file
|
||||
|
||||
|
||||
|
||||
|
||||
2009-11-07T06:59:45.000000Z
|
||||
026d3e96099de7100c1d49012720d6f9
|
||||
2008-06-22T05:51:59.360556Z
|
||||
3
|
||||
henrit
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
604
|
||||
|
||||
MD5.as
|
||||
file
|
||||
|
||||
|
||||
|
||||
|
||||
2009-11-07T06:59:45.000000Z
|
||||
60211f6583ee826e2a17ad03605aa7b4
|
||||
2009-06-04T23:35:21.192697Z
|
||||
28
|
||||
sh0rtwave
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
6965
|
||||
|
||||
SHABase.as
|
||||
file
|
||||
|
||||
|
||||
|
||||
|
||||
2009-11-07T06:59:45.000000Z
|
||||
aa1101bf874f26cd364cf16fb7dff6c7
|
||||
2009-06-04T23:35:21.192697Z
|
||||
28
|
||||
sh0rtwave
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
1495
|
||||
|
||||
SHA256.as
|
||||
file
|
||||
|
||||
|
||||
|
||||
|
||||
2009-11-07T06:59:45.000000Z
|
||||
c14bc0555970db81a87f5d2b60e4288c
|
||||
2009-06-04T23:35:21.192697Z
|
||||
28
|
||||
sh0rtwave
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
3459
|
||||
|
||||
HMAC.as
|
||||
file
|
||||
|
||||
|
||||
|
||||
|
||||
2009-11-07T06:59:45.000000Z
|
||||
c96c9bc0e0b64eed7e2d8c27dc29c561
|
||||
2009-06-04T23:35:21.192697Z
|
||||
28
|
||||
sh0rtwave
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
2132
|
||||
|
||||
IHash.as
|
||||
file
|
||||
|
||||
|
||||
|
||||
|
||||
2009-11-07T06:59:45.000000Z
|
||||
71f45750c456debd7ef1f74e6db9dc23
|
||||
2009-06-04T23:35:21.192697Z
|
||||
28
|
||||
sh0rtwave
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
445
|
||||
|
||||
SHA1.as
|
||||
file
|
||||
|
||||
|
||||
|
||||
|
||||
2009-11-07T06:59:45.000000Z
|
||||
ba97b95bebda5bdd3fe2063e9c7e21cd
|
||||
2009-06-04T23:35:21.192697Z
|
||||
28
|
||||
sh0rtwave
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
2642
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
K 14
|
||||
svn:executable
|
||||
V 1
|
||||
*
|
||||
END
|
||||
@@ -1,5 +0,0 @@
|
||||
K 14
|
||||
svn:executable
|
||||
V 1
|
||||
*
|
||||
END
|
||||
@@ -1,82 +0,0 @@
|
||||
/**
|
||||
* HMAC
|
||||
*
|
||||
* An ActionScript 3 implementation of HMAC, Keyed-Hashing for Message
|
||||
* Authentication, as defined by RFC-2104
|
||||
* Copyright (c) 2007 Henri Torgemane
|
||||
*
|
||||
* See LICENSE.txt for full license information.
|
||||
*/
|
||||
package com.hurlant.crypto.hash
|
||||
{
|
||||
import flash.utils.ByteArray;
|
||||
import com.hurlant.util.Hex;
|
||||
|
||||
public class HMAC implements IHMAC
|
||||
{
|
||||
private var hash:IHash;
|
||||
private var bits:uint;
|
||||
|
||||
/**
|
||||
* Create a HMAC object, using a Hash function, and
|
||||
* optionally a number of bits to return.
|
||||
* The HMAC will be truncated to that size if needed.
|
||||
*/
|
||||
public function HMAC(hash:IHash, bits:uint=0) {
|
||||
this.hash = hash;
|
||||
this.bits = bits;
|
||||
}
|
||||
|
||||
|
||||
public function getHashSize():uint {
|
||||
if (bits!=0) {
|
||||
return bits/8;
|
||||
} else {
|
||||
return hash.getHashSize();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Compute a HMAC using a key and some data.
|
||||
* It doesn't modify either, and returns a new ByteArray with the HMAC value.
|
||||
*/
|
||||
public function compute(key:ByteArray, data:ByteArray):ByteArray {
|
||||
var hashKey:ByteArray;
|
||||
if (key.length>hash.getInputSize()) {
|
||||
hashKey = hash.hash(key);
|
||||
} else {
|
||||
hashKey = new ByteArray;
|
||||
hashKey.writeBytes(key);
|
||||
}
|
||||
while (hashKey.length<hash.getInputSize()) {
|
||||
hashKey[hashKey.length]=0;
|
||||
}
|
||||
var innerKey:ByteArray = new ByteArray;
|
||||
var outerKey:ByteArray = new ByteArray;
|
||||
for (var i:uint=0;i<hashKey.length;i++) {
|
||||
innerKey[i] = hashKey[i] ^ 0x36;
|
||||
outerKey[i] = hashKey[i] ^ 0x5c;
|
||||
}
|
||||
// inner + data
|
||||
innerKey.position = hashKey.length;
|
||||
innerKey.writeBytes(data);
|
||||
var innerHash:ByteArray = hash.hash(innerKey);
|
||||
// outer + innerHash
|
||||
outerKey.position = hashKey.length;
|
||||
outerKey.writeBytes(innerHash);
|
||||
var outerHash:ByteArray = hash.hash(outerKey);
|
||||
if (bits>0 && bits<8*outerHash.length) {
|
||||
outerHash.length = bits/8;
|
||||
}
|
||||
return outerHash;
|
||||
}
|
||||
public function dispose():void {
|
||||
hash = null;
|
||||
bits = 0;
|
||||
}
|
||||
public function toString():String {
|
||||
return "hmac-"+(bits>0?bits+"-":"")+hash.toString();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
-27
@@ -1,27 +0,0 @@
|
||||
/**
|
||||
* HMAC
|
||||
*
|
||||
* An ActionScript 3 interface for HMAC & MAC
|
||||
* implementations.
|
||||
*
|
||||
* Loosely copyrighted by Bobby Parker
|
||||
*
|
||||
* See LICENSE.txt for full license information.
|
||||
*/
|
||||
package com.hurlant.crypto.hash
|
||||
{
|
||||
import flash.utils.ByteArray;
|
||||
|
||||
public interface IHMAC
|
||||
{
|
||||
function getHashSize():uint;
|
||||
/**
|
||||
* Compute a HMAC using a key and some data.
|
||||
* It doesn't modify either, and returns a new ByteArray with the HMAC value.
|
||||
*/
|
||||
function compute(key:ByteArray, data:ByteArray):ByteArray;
|
||||
function dispose():void;
|
||||
function toString():String;
|
||||
|
||||
}
|
||||
}
|
||||
-21
@@ -1,21 +0,0 @@
|
||||
/**
|
||||
* IHash
|
||||
*
|
||||
* An interface for each hash function to implement
|
||||
* Copyright (c) 2007 Henri Torgemane
|
||||
*
|
||||
* See LICENSE.txt for full license information.
|
||||
*/
|
||||
package com.hurlant.crypto.hash
|
||||
{
|
||||
import flash.utils.ByteArray;
|
||||
|
||||
public interface IHash
|
||||
{
|
||||
function getInputSize():uint;
|
||||
function getHashSize():uint;
|
||||
function hash(src:ByteArray):ByteArray;
|
||||
function toString():String;
|
||||
function getPadSize():int;
|
||||
}
|
||||
}
|
||||
@@ -1,137 +0,0 @@
|
||||
/**
|
||||
* MAC
|
||||
*
|
||||
* An ActionScript 3 implementation of MAC, Message Authentication Code
|
||||
* for use with SSL 3.0.
|
||||
* Loosely copyrighted by Bobby Parker.
|
||||
* As3crypto copyrighted by Henri Torgemane.
|
||||
*
|
||||
* See LICENSE.txt for full license information.
|
||||
*/
|
||||
package com.hurlant.crypto.hash
|
||||
{
|
||||
import flash.utils.ByteArray;
|
||||
import com.hurlant.util.Hex;
|
||||
|
||||
public class MAC implements IHMAC
|
||||
{
|
||||
private var hash:IHash;
|
||||
private var bits:uint;
|
||||
private var pad_1:ByteArray;
|
||||
private var pad_2:ByteArray;
|
||||
private var innerHash:ByteArray;
|
||||
private var outerHash:ByteArray;
|
||||
private var outerKey:ByteArray;
|
||||
private var innerKey:ByteArray;
|
||||
/**
|
||||
* Create a MAC object (for SSL 3.0 ) and
|
||||
* optionally a number of bits to return.
|
||||
* The MAC will be truncated to that size if needed.
|
||||
*/
|
||||
public function MAC(hash:IHash, bits:uint=0) {
|
||||
this.hash = hash;
|
||||
this.bits = bits;
|
||||
innerHash = new ByteArray();
|
||||
outerHash = new ByteArray();
|
||||
innerKey = new ByteArray();
|
||||
outerKey = new ByteArray();
|
||||
|
||||
|
||||
if (hash != null) {
|
||||
var pad_size:int = hash.getPadSize();
|
||||
pad_1 = new ByteArray();
|
||||
pad_2 = new ByteArray();
|
||||
|
||||
for (var x:int = 0; x < pad_size; x++) {
|
||||
pad_1.writeByte(0x36);
|
||||
pad_2.writeByte(0x5c);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function setPadSize(pad_size:int) : void { }
|
||||
|
||||
public function getHashSize():uint {
|
||||
if (bits!=0) {
|
||||
return bits/8;
|
||||
} else {
|
||||
return hash.getHashSize();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Compute a MAC using a key and some data.
|
||||
*
|
||||
*/
|
||||
public function compute(key:ByteArray, data:ByteArray):ByteArray {
|
||||
// take that incoming key and do hash(key + pad_2 + hash(key + pad_1 + sequence + length + record)
|
||||
// note that data = (sequence + type + length + record)
|
||||
|
||||
if (pad_1 == null) {
|
||||
var pad_size:int = hash.getPadSize();
|
||||
pad_1 = new ByteArray();
|
||||
pad_2 = new ByteArray();
|
||||
|
||||
for (var x:int = 0; x < pad_size; x++) {
|
||||
pad_1.writeByte(0x36);
|
||||
pad_2.writeByte(0x5c);
|
||||
}
|
||||
}
|
||||
|
||||
// Do some preliminary checking on stuff
|
||||
/*
|
||||
if (key.length > hash.getInputSize()) {
|
||||
hashKey = hash.hash(key);
|
||||
} else {
|
||||
hashKey = new ByteArray;
|
||||
hashKey.writeBytes(key);
|
||||
}
|
||||
|
||||
while (hashKey.length < hash.getInputSize() ) {
|
||||
hashKey[hashKey.length] = 0;
|
||||
} */
|
||||
// Henri's conventions work just fine here..
|
||||
|
||||
innerKey.length = 0;
|
||||
outerKey.length = 0;
|
||||
// trace("MAC Key: " + Hex.fromArray(key));
|
||||
// trace("Key Length: " + key.length);
|
||||
// trace("Pad_1 : " + Hex.fromArray(pad_1));
|
||||
// inner hash calc
|
||||
innerKey.writeBytes(key);
|
||||
innerKey.writeBytes(pad_1);
|
||||
innerKey.writeBytes(data);
|
||||
// trace("MAC Inner Key: " + Hex.fromArray(innerKey));
|
||||
|
||||
innerHash = hash.hash(innerKey);
|
||||
// trace("MAC Inner Hash: " + Hex.fromArray(innerHash));
|
||||
|
||||
// outer hash calc
|
||||
outerKey.writeBytes(key);
|
||||
outerKey.writeBytes(pad_2);
|
||||
outerKey.writeBytes(innerHash);
|
||||
|
||||
// trace("MAC Outer Key: " + Hex.fromArray(outerKey));
|
||||
outerHash = hash.hash(outerKey);
|
||||
|
||||
|
||||
if (bits > 0 && bits < 8*outerHash.length) {
|
||||
outerHash.length = bits/8;
|
||||
}
|
||||
|
||||
// trace("MAC for record: " + Hex.fromArray(outerHash));
|
||||
return outerHash;
|
||||
|
||||
}
|
||||
|
||||
public function dispose():void {
|
||||
hash = null;
|
||||
bits = 0;
|
||||
}
|
||||
public function toString():String {
|
||||
return "mac-"+(bits>0?bits+"-":"")+hash.toString();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,121 +0,0 @@
|
||||
/**
|
||||
* MD2
|
||||
*
|
||||
* An ActionScript 3 implementation of the RSA Data Security, Inc MD2 Message
|
||||
* Digest Algorithm, as defined in RFC 1319
|
||||
* Copyright (c) 2007 Henri Torgemane
|
||||
*
|
||||
* See LICENSE.txt for full license information.
|
||||
*
|
||||
* Excerpt from http://en.wikipedia.org/wiki/MD2:
|
||||
* >
|
||||
* > Rogier and Chauvaud (1997) described collisions of MD2's compression function,
|
||||
* > although they were unable to extend the attack to the full MD2.
|
||||
* >
|
||||
* > In 2004, MD2 was shown to be vulnerable to a preimage attack with time
|
||||
* > complexity equivalent to 2104 applications of the compression function
|
||||
* > (Muller, 2004).
|
||||
* > The author concludes, "MD2 can no longer be considered a secure one-way
|
||||
* > hash function".
|
||||
*
|
||||
* also, this implementaton is quite slow.
|
||||
*/
|
||||
|
||||
package com.hurlant.crypto.hash
|
||||
{
|
||||
import flash.utils.ByteArray;
|
||||
|
||||
public class MD2 implements IHash
|
||||
{
|
||||
public static const HASH_SIZE:int = 16;
|
||||
public var pad_size:int = 48; // probably will never get used, only here for SSL 3.0 support
|
||||
|
||||
private static const S:Array = [ // PI Digits
|
||||
41, 46, 67, 201, 162, 216, 124, 1, 61, 54, 84, 161, 236, 240, 6, 19,
|
||||
98, 167, 5, 243, 192, 199, 115, 140, 152, 147, 43, 217, 188, 76, 130, 202,
|
||||
30, 155, 87, 60, 253, 212, 224, 22, 103, 66, 111, 24, 138, 23, 229, 18,
|
||||
190, 78, 196, 214, 218, 158, 222, 73, 160, 251, 245, 142, 187, 47, 238, 122,
|
||||
169, 104, 121, 145, 21, 178, 7, 63, 148, 194, 16, 137, 11, 34, 95, 33,
|
||||
128, 127, 93, 154, 90, 144, 50, 39, 53, 62, 204, 231, 191, 247, 151, 3,
|
||||
255, 25, 48, 179, 72, 165, 181, 209, 215, 94, 146, 42, 172, 86, 170, 198,
|
||||
79, 184, 56, 210, 150, 164, 125, 182, 118, 252, 107, 226, 156, 116, 4, 241,
|
||||
69, 157, 112, 89, 100, 113, 135, 32, 134, 91, 207, 101, 230, 45, 168, 2,
|
||||
27, 96, 37, 173, 174, 176, 185, 246, 28, 70, 97, 105, 52, 64, 126, 15,
|
||||
85, 71, 163, 35, 221, 81, 175, 58, 195, 92, 249, 206, 186, 197, 234, 38,
|
||||
44, 83, 13, 110, 133, 40, 132, 9, 211, 223, 205, 244, 65, 129, 77, 82,
|
||||
106, 220, 55, 200, 108, 193, 171, 250, 36, 225, 123, 8, 12, 189, 177, 74,
|
||||
120, 136, 149, 139, 227, 99, 232, 109, 233, 203, 213, 254, 59, 0, 29, 57,
|
||||
242, 239, 183, 14, 102, 88, 208, 228, 166, 119, 114, 248, 235, 117, 75, 10,
|
||||
49, 68, 80, 180, 143, 237, 31, 26, 219, 153, 141, 51, 159, 17, 131, 20 ];
|
||||
|
||||
public function getInputSize():uint
|
||||
{
|
||||
return 16;
|
||||
}
|
||||
|
||||
public function getPadSize():int {
|
||||
return pad_size;
|
||||
}
|
||||
|
||||
public function getHashSize():uint
|
||||
{
|
||||
return HASH_SIZE;
|
||||
}
|
||||
|
||||
public function hash(src:ByteArray):ByteArray
|
||||
{
|
||||
var savedLength:uint = src.length;
|
||||
|
||||
// 3.1 Step 1. Padding
|
||||
var i:uint = (16-src.length%16) || 16;
|
||||
do {
|
||||
src[src.length]=i;
|
||||
} while (src.length%16!=0);
|
||||
|
||||
// 3.2 Step 2. Checksum
|
||||
var len:uint = src.length;
|
||||
var checksum:ByteArray = new ByteArray;
|
||||
var L:uint = 0;
|
||||
for (i = 0;i<len;i+=16) {
|
||||
for (var j:uint=0;j<16;j++) {
|
||||
L = checksum[j] ^= S[src[i+j] ^ L];
|
||||
}
|
||||
}
|
||||
src.position = src.length;
|
||||
src.writeBytes(checksum);
|
||||
len += 16;
|
||||
|
||||
// 3.3 Step 3. MD Buffer
|
||||
var X:ByteArray = new ByteArray;
|
||||
|
||||
// 3.4 Process Message
|
||||
for (i=0;i<len;i+=16) {
|
||||
|
||||
/* Copy block i into X */
|
||||
for (j=0;j<16;j++) {
|
||||
X[32+j] = (X[16+j] = src[i+j])^X[j];
|
||||
}
|
||||
var t:uint=0;
|
||||
/* Do 18 rounds */
|
||||
for (j=0;j<18;j++) {
|
||||
/* Round j. */
|
||||
for (var k:uint=0;k<48;k++) {
|
||||
X[k] = t = X[k]^S[t];
|
||||
}
|
||||
t = (t+j)&0xff;
|
||||
}
|
||||
}
|
||||
// 3.5 Step 5. Output
|
||||
X.length = 16;
|
||||
// restore original length;
|
||||
src.length = savedLength;
|
||||
return X;
|
||||
}
|
||||
|
||||
public function toString():String
|
||||
{
|
||||
return "md2";
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,202 +0,0 @@
|
||||
/**
|
||||
* MD5
|
||||
*
|
||||
* An ActionScript 3 implementation of the RSA Data Security, Inc. MD5 Message
|
||||
* Digest Algorithm, as defined in RFC 1321.
|
||||
* Copyright (c) 2007 Henri Torgemane
|
||||
*
|
||||
* Derived from
|
||||
* A JavaScript implementation of the same.
|
||||
* Version 2.1 Copyright (C) Paul Johnston 1999 - 2002.
|
||||
* Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
|
||||
*
|
||||
* Note:
|
||||
* This algorithm should not be your first choice for new developements, but is
|
||||
* included to allow interoperability with existing codes and protocols.
|
||||
*
|
||||
* See LICENSE.txt for full license information.
|
||||
*/
|
||||
package com.hurlant.crypto.hash
|
||||
{
|
||||
import flash.utils.ByteArray;
|
||||
import flash.utils.Endian;
|
||||
|
||||
public class MD5 implements IHash
|
||||
{
|
||||
public static const HASH_SIZE:int = 16;
|
||||
public var pad_size:int = 48;
|
||||
|
||||
public function getInputSize():uint
|
||||
{
|
||||
return 64;
|
||||
}
|
||||
|
||||
public function getHashSize():uint
|
||||
{
|
||||
return HASH_SIZE;
|
||||
}
|
||||
|
||||
public function getPadSize():int
|
||||
{
|
||||
return pad_size;
|
||||
}
|
||||
|
||||
public function hash(src:ByteArray):ByteArray
|
||||
{
|
||||
var len:uint = src.length *8;
|
||||
var savedEndian:String = src.endian;
|
||||
// pad to nearest int.
|
||||
while (src.length%4!=0) {
|
||||
src[src.length]=0;
|
||||
}
|
||||
// convert ByteArray to an array of uint
|
||||
src.position=0;
|
||||
var a:Array = [];
|
||||
src.endian=Endian.LITTLE_ENDIAN
|
||||
for (var i:uint=0;i<src.length;i+=4) {
|
||||
a.push(src.readUnsignedInt());
|
||||
}
|
||||
var h:Array = core_md5(a, len);
|
||||
var out:ByteArray = new ByteArray;
|
||||
out.endian=Endian.LITTLE_ENDIAN;
|
||||
for (i=0;i<4;i++) {
|
||||
out.writeUnsignedInt(h[i]);
|
||||
}
|
||||
// restore length!
|
||||
src.length = len/8;
|
||||
src.endian = savedEndian;
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
private function core_md5(x:Array, len:uint):Array {
|
||||
/* append padding */
|
||||
x[len >> 5] |= 0x80 << ((len) % 32);
|
||||
x[(((len + 64) >>> 9) << 4) + 14] = len;
|
||||
|
||||
var a:uint = 0x67452301; // 1732584193;
|
||||
var b:uint = 0xEFCDAB89; //-271733879;
|
||||
var c:uint = 0x98BADCFE; //-1732584194;
|
||||
var d:uint = 0x10325476; // 271733878;
|
||||
|
||||
for(var i:uint = 0; i < x.length; i += 16)
|
||||
{
|
||||
x[i]||=0; x[i+1]||=0; x[i+2]||=0; x[i+3]||=0;
|
||||
x[i+4]||=0; x[i+5]||=0; x[i+6]||=0; x[i+7]||=0;
|
||||
x[i+8]||=0; x[i+9]||=0; x[i+10]||=0; x[i+11]||=0;
|
||||
x[i+12]||=0; x[i+13]||=0; x[i+14]||=0; x[i+15]||=0;
|
||||
|
||||
var olda:uint = a;
|
||||
var oldb:uint = b;
|
||||
var oldc:uint = c;
|
||||
var oldd:uint = d;
|
||||
|
||||
a = ff(a, b, c, d, x[i+ 0], 7 , 0xD76AA478);
|
||||
d = ff(d, a, b, c, x[i+ 1], 12, 0xE8C7B756);
|
||||
c = ff(c, d, a, b, x[i+ 2], 17, 0x242070DB);
|
||||
b = ff(b, c, d, a, x[i+ 3], 22, 0xC1BDCEEE);
|
||||
a = ff(a, b, c, d, x[i+ 4], 7 , 0xF57C0FAF);
|
||||
d = ff(d, a, b, c, x[i+ 5], 12, 0x4787C62A);
|
||||
c = ff(c, d, a, b, x[i+ 6], 17, 0xA8304613);
|
||||
b = ff(b, c, d, a, x[i+ 7], 22, 0xFD469501);
|
||||
a = ff(a, b, c, d, x[i+ 8], 7 , 0x698098D8);
|
||||
d = ff(d, a, b, c, x[i+ 9], 12, 0x8B44F7AF);
|
||||
c = ff(c, d, a, b, x[i+10], 17, 0xFFFF5BB1);
|
||||
b = ff(b, c, d, a, x[i+11], 22, 0x895CD7BE);
|
||||
a = ff(a, b, c, d, x[i+12], 7 , 0x6B901122);
|
||||
d = ff(d, a, b, c, x[i+13], 12, 0xFD987193);
|
||||
c = ff(c, d, a, b, x[i+14], 17, 0xA679438E);
|
||||
b = ff(b, c, d, a, x[i+15], 22, 0x49B40821);
|
||||
|
||||
a = gg(a, b, c, d, x[i+ 1], 5 , 0xf61e2562);
|
||||
d = gg(d, a, b, c, x[i+ 6], 9 , 0xc040b340);
|
||||
c = gg(c, d, a, b, x[i+11], 14, 0x265e5a51);
|
||||
b = gg(b, c, d, a, x[i+ 0], 20, 0xe9b6c7aa);
|
||||
a = gg(a, b, c, d, x[i+ 5], 5 , 0xd62f105d);
|
||||
d = gg(d, a, b, c, x[i+10], 9 , 0x2441453);
|
||||
c = gg(c, d, a, b, x[i+15], 14, 0xd8a1e681);
|
||||
b = gg(b, c, d, a, x[i+ 4], 20, 0xe7d3fbc8);
|
||||
a = gg(a, b, c, d, x[i+ 9], 5 , 0x21e1cde6);
|
||||
d = gg(d, a, b, c, x[i+14], 9 , 0xc33707d6);
|
||||
c = gg(c, d, a, b, x[i+ 3], 14, 0xf4d50d87);
|
||||
b = gg(b, c, d, a, x[i+ 8], 20, 0x455a14ed);
|
||||
a = gg(a, b, c, d, x[i+13], 5 , 0xa9e3e905);
|
||||
d = gg(d, a, b, c, x[i+ 2], 9 , 0xfcefa3f8);
|
||||
c = gg(c, d, a, b, x[i+ 7], 14, 0x676f02d9);
|
||||
b = gg(b, c, d, a, x[i+12], 20, 0x8d2a4c8a);
|
||||
|
||||
a = hh(a, b, c, d, x[i+ 5], 4 , 0xfffa3942);
|
||||
d = hh(d, a, b, c, x[i+ 8], 11, 0x8771f681);
|
||||
c = hh(c, d, a, b, x[i+11], 16, 0x6d9d6122);
|
||||
b = hh(b, c, d, a, x[i+14], 23, 0xfde5380c);
|
||||
a = hh(a, b, c, d, x[i+ 1], 4 , 0xa4beea44);
|
||||
d = hh(d, a, b, c, x[i+ 4], 11, 0x4bdecfa9);
|
||||
c = hh(c, d, a, b, x[i+ 7], 16, 0xf6bb4b60);
|
||||
b = hh(b, c, d, a, x[i+10], 23, 0xbebfbc70);
|
||||
a = hh(a, b, c, d, x[i+13], 4 , 0x289b7ec6);
|
||||
d = hh(d, a, b, c, x[i+ 0], 11, 0xeaa127fa);
|
||||
c = hh(c, d, a, b, x[i+ 3], 16, 0xd4ef3085);
|
||||
b = hh(b, c, d, a, x[i+ 6], 23, 0x4881d05);
|
||||
a = hh(a, b, c, d, x[i+ 9], 4 , 0xd9d4d039);
|
||||
d = hh(d, a, b, c, x[i+12], 11, 0xe6db99e5);
|
||||
c = hh(c, d, a, b, x[i+15], 16, 0x1fa27cf8);
|
||||
b = hh(b, c, d, a, x[i+ 2], 23, 0xc4ac5665);
|
||||
|
||||
a = ii(a, b, c, d, x[i+ 0], 6 , 0xf4292244);
|
||||
d = ii(d, a, b, c, x[i+ 7], 10, 0x432aff97);
|
||||
c = ii(c, d, a, b, x[i+14], 15, 0xab9423a7);
|
||||
b = ii(b, c, d, a, x[i+ 5], 21, 0xfc93a039);
|
||||
a = ii(a, b, c, d, x[i+12], 6 , 0x655b59c3);
|
||||
d = ii(d, a, b, c, x[i+ 3], 10, 0x8f0ccc92);
|
||||
c = ii(c, d, a, b, x[i+10], 15, 0xffeff47d);
|
||||
b = ii(b, c, d, a, x[i+ 1], 21, 0x85845dd1);
|
||||
a = ii(a, b, c, d, x[i+ 8], 6 , 0x6fa87e4f);
|
||||
d = ii(d, a, b, c, x[i+15], 10, 0xfe2ce6e0);
|
||||
c = ii(c, d, a, b, x[i+ 6], 15, 0xa3014314);
|
||||
b = ii(b, c, d, a, x[i+13], 21, 0x4e0811a1);
|
||||
a = ii(a, b, c, d, x[i+ 4], 6 , 0xf7537e82);
|
||||
d = ii(d, a, b, c, x[i+11], 10, 0xbd3af235);
|
||||
c = ii(c, d, a, b, x[i+ 2], 15, 0x2ad7d2bb);
|
||||
b = ii(b, c, d, a, x[i+ 9], 21, 0xeb86d391);
|
||||
|
||||
a += olda;
|
||||
b += oldb;
|
||||
c += oldc;
|
||||
d += oldd;
|
||||
|
||||
}
|
||||
return [ a, b, c, d ];
|
||||
}
|
||||
|
||||
/*
|
||||
* Bitwise rotate a 32-bit number to the left.
|
||||
*/
|
||||
private function rol(num:uint, cnt:uint):uint
|
||||
{
|
||||
return (num << cnt) | (num >>> (32 - cnt));
|
||||
}
|
||||
|
||||
/*
|
||||
* These functions implement the four basic operations the algorithm uses.
|
||||
*/
|
||||
private function cmn(q:uint, a:uint, b:uint, x:uint, s:uint, t:uint):uint {
|
||||
return rol(a + q + x + t, s) + b;
|
||||
}
|
||||
private function ff(a:uint, b:uint, c:uint, d:uint, x:uint, s:uint, t:uint):uint {
|
||||
return cmn((b & c) | ((~b) & d), a, b, x, s, t);
|
||||
}
|
||||
private function gg(a:uint, b:uint, c:uint, d:uint, x:uint, s:uint, t:uint):uint {
|
||||
return cmn((b & d) | (c & (~d)), a, b, x, s, t);
|
||||
}
|
||||
private function hh(a:uint, b:uint, c:uint, d:uint, x:uint, s:uint, t:uint):uint {
|
||||
return cmn(b ^ c ^ d, a, b, x, s, t);
|
||||
}
|
||||
private function ii(a:uint, b:uint, c:uint, d:uint, x:uint, s:uint, t:uint):uint {
|
||||
return cmn(c ^ (b | (~d)), a, b, x, s, t);
|
||||
}
|
||||
|
||||
public function toString():String {
|
||||
return "md5";
|
||||
}
|
||||
}
|
||||
}
|
||||
-106
@@ -1,106 +0,0 @@
|
||||
/**
|
||||
* SHA1
|
||||
*
|
||||
* An ActionScript 3 implementation of Secure Hash Algorithm, SHA-1, as defined
|
||||
* in FIPS PUB 180-1
|
||||
* Copyright (c) 2007 Henri Torgemane
|
||||
*
|
||||
* Derived from:
|
||||
* A JavaScript implementation of the Secure Hash Algorithm, SHA-1, as defined
|
||||
* in FIPS PUB 180-1
|
||||
* Version 2.1a Copyright Paul Johnston 2000 - 2002.
|
||||
* Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
|
||||
*
|
||||
* See LICENSE.txt for full license information.
|
||||
*/
|
||||
package com.hurlant.crypto.hash
|
||||
{
|
||||
|
||||
|
||||
public class SHA1 extends SHABase implements IHash
|
||||
{
|
||||
public static const HASH_SIZE:int = 20;
|
||||
|
||||
public override function getHashSize():uint {
|
||||
return HASH_SIZE;
|
||||
}
|
||||
|
||||
protected override function core(x:Array, len:uint):Array
|
||||
{
|
||||
/* append padding */
|
||||
x[len >> 5] |= 0x80 << (24 - len % 32);
|
||||
x[((len + 64 >> 9) << 4) + 15] = len;
|
||||
|
||||
var w:Array = [];
|
||||
var a:uint = 0x67452301; //1732584193;
|
||||
var b:uint = 0xEFCDAB89; //-271733879;
|
||||
var c:uint = 0x98BADCFE; //-1732584194;
|
||||
var d:uint = 0x10325476; //271733878;
|
||||
var e:uint = 0xC3D2E1F0; //-1009589776;
|
||||
|
||||
for(var i:uint = 0; i < x.length; i += 16)
|
||||
{
|
||||
|
||||
var olda:uint = a;
|
||||
var oldb:uint = b;
|
||||
var oldc:uint = c;
|
||||
var oldd:uint = d;
|
||||
var olde:uint = e;
|
||||
|
||||
for(var j:uint = 0; j < 80; j++)
|
||||
{
|
||||
if (j < 16) {
|
||||
w[j] = x[i + j] || 0;
|
||||
} else {
|
||||
w[j] = rol(w[j-3] ^ w[j-8] ^ w[j-14] ^ w[j-16], 1);
|
||||
}
|
||||
var t:uint = rol(a,5) + ft(j,b,c,d) + e + w[j] + kt(j);
|
||||
e = d;
|
||||
d = c;
|
||||
c = rol(b, 30);
|
||||
b = a;
|
||||
a = t;
|
||||
}
|
||||
a += olda;
|
||||
b += oldb;
|
||||
c += oldc;
|
||||
d += oldd;
|
||||
e += olde;
|
||||
}
|
||||
return [ a, b, c, d, e ];
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Bitwise rotate a 32-bit number to the left.
|
||||
*/
|
||||
private function rol(num:uint, cnt:uint):uint
|
||||
{
|
||||
return (num << cnt) | (num >>> (32 - cnt));
|
||||
}
|
||||
|
||||
/*
|
||||
* Perform the appropriate triplet combination function for the current
|
||||
* iteration
|
||||
*/
|
||||
private function ft(t:uint, b:uint, c:uint, d:uint):uint
|
||||
{
|
||||
if(t < 20) return (b & c) | ((~b) & d);
|
||||
if(t < 40) return b ^ c ^ d;
|
||||
if(t < 60) return (b & c) | (b & d) | (c & d);
|
||||
return b ^ c ^ d;
|
||||
}
|
||||
|
||||
/*
|
||||
* Determine the appropriate additive constant for the current iteration
|
||||
*/
|
||||
private function kt(t:uint):uint
|
||||
{
|
||||
return (t < 20) ? 0x5A827999 : (t < 40) ? 0x6ED9EBA1 :
|
||||
(t < 60) ? 0x8F1BBCDC : 0xCA62C1D6;
|
||||
}
|
||||
public override function toString():String {
|
||||
return "sha1";
|
||||
}
|
||||
}
|
||||
}
|
||||
-28
@@ -1,28 +0,0 @@
|
||||
/**
|
||||
* SHA224
|
||||
*
|
||||
* An ActionScript 3 implementation of Secure Hash Algorithm, SHA-224, as defined
|
||||
* in FIPS PUB 180-2
|
||||
* Copyright (c) 2007 Henri Torgemane
|
||||
*
|
||||
* See LICENSE.txt for full license information.
|
||||
*/
|
||||
package com.hurlant.crypto.hash
|
||||
{
|
||||
public class SHA224 extends SHA256
|
||||
{
|
||||
function SHA224() {
|
||||
h = [
|
||||
0xc1059ed8, 0x367cd507, 0x3070dd17, 0xf70e5939,
|
||||
0xffc00b31, 0x68581511, 0x64f98fa7, 0xbefa4fa4
|
||||
];
|
||||
}
|
||||
|
||||
public override function getHashSize():uint {
|
||||
return 28;
|
||||
}
|
||||
public override function toString():String {
|
||||
return "sha224";
|
||||
}
|
||||
}
|
||||
}
|
||||
-115
@@ -1,115 +0,0 @@
|
||||
/**
|
||||
* SHA256
|
||||
*
|
||||
* An ActionScript 3 implementation of Secure Hash Algorithm, SHA-256, as defined
|
||||
* in FIPS PUB 180-2
|
||||
* Copyright (c) 2007 Henri Torgemane
|
||||
*
|
||||
* Derived from:
|
||||
* A JavaScript implementation of the Secure Hash Standard
|
||||
* Version 0.3 Copyright Angel Marin 2003-2004 - http://anmar.eu.org/
|
||||
* Derived from:
|
||||
* A JavaScript implementation of the Secure Hash Algorithm, SHA-1, as defined
|
||||
* in FIPS PUB 180-1
|
||||
* Version 2.1a Copyright Paul Johnston 2000 - 2002.
|
||||
* Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
|
||||
*
|
||||
* See LICENSE.txt for full license information.
|
||||
*/
|
||||
package com.hurlant.crypto.hash
|
||||
{
|
||||
|
||||
|
||||
public class SHA256 extends SHABase implements IHash
|
||||
{
|
||||
|
||||
protected static const k:Array = [
|
||||
0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
|
||||
0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
|
||||
0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
|
||||
0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
|
||||
0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
|
||||
0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
|
||||
0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
|
||||
0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2];
|
||||
protected var h:Array = [
|
||||
0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19
|
||||
];
|
||||
|
||||
public function SHA256(){
|
||||
}
|
||||
|
||||
public override function getHashSize():uint
|
||||
{
|
||||
return 32;
|
||||
}
|
||||
|
||||
protected override function core(x:Array, len:uint):Array {
|
||||
/* append padding */
|
||||
x[len >> 5] |= 0x80 << (24 - len % 32);
|
||||
x[((len + 64 >> 9) << 4) + 15] = len;
|
||||
|
||||
var w:Array = [];
|
||||
var a:uint = h[0];
|
||||
var b:uint = h[1];
|
||||
var c:uint = h[2];
|
||||
var d:uint = h[3];
|
||||
var e:uint = h[4];
|
||||
var f:uint = h[5];
|
||||
var g:uint = h[6];
|
||||
var h:uint = h[7];
|
||||
|
||||
for (var i:uint=0; i<x.length; i+=16) {
|
||||
var olda:uint = a;
|
||||
var oldb:uint = b;
|
||||
var oldc:uint = c;
|
||||
var oldd:uint = d;
|
||||
var olde:uint = e;
|
||||
var oldf:uint = f;
|
||||
var oldg:uint = g;
|
||||
var oldh:uint = h;
|
||||
|
||||
for (var j:uint=0; j<64; j++) {
|
||||
if (j<16) {
|
||||
w[j] = x[i+j] || 0;
|
||||
} else {
|
||||
var s0:uint = rrol(w[j-15],7)^rrol(w[j-15],18)^(w[j-15]>>>3);
|
||||
var s1:uint = rrol(w[j-2], 17)^rrol(w[j-2],19)^(w[j-2]>>>10);
|
||||
w[j] = w[j-16] + s0 + w[j-7] + s1;
|
||||
}
|
||||
var t2:uint = (rrol(a,2) ^ rrol(a,13) ^ rrol(a,22)) + ((a&b) ^ (a&c) ^ (b&c));
|
||||
var t1:uint = h + (rrol(e,6) ^ rrol(e,11) ^ rrol(e,25)) + ((e&f)^(g&~e)) + k[j] + w[j]
|
||||
h = g;
|
||||
g = f;
|
||||
f = e;
|
||||
e = d + t1;
|
||||
d = c;
|
||||
c = b;
|
||||
b = a;
|
||||
a = t1 + t2;
|
||||
|
||||
}
|
||||
a += olda;
|
||||
b += oldb;
|
||||
c += oldc;
|
||||
d += oldd;
|
||||
e += olde;
|
||||
f += oldf;
|
||||
g += oldg;
|
||||
h += oldh;
|
||||
}
|
||||
return [ a,b,c,d,e,f,g,h ];
|
||||
}
|
||||
|
||||
/*
|
||||
* Bitwise rotate a 32-bit number to the right.
|
||||
*/
|
||||
protected function rrol(num:uint, cnt:uint):uint {
|
||||
return (num << (32-cnt)) | (num >>> cnt);
|
||||
}
|
||||
|
||||
public override function toString():String {
|
||||
return "sha256";
|
||||
}
|
||||
}
|
||||
}
|
||||
-68
@@ -1,68 +0,0 @@
|
||||
/**
|
||||
* SHABase
|
||||
*
|
||||
* An ActionScript 3 abstract class for the SHA family of hash functions
|
||||
* Copyright (c) 2007 Henri Torgemane
|
||||
*
|
||||
* See LICENSE.txt for full license information.
|
||||
*/
|
||||
package com.hurlant.crypto.hash
|
||||
{
|
||||
import flash.utils.ByteArray;
|
||||
import flash.utils.Endian;
|
||||
|
||||
public class SHABase implements IHash
|
||||
{
|
||||
public var pad_size:int = 40;
|
||||
public function getInputSize():uint
|
||||
{
|
||||
return 64;
|
||||
}
|
||||
|
||||
public function getHashSize():uint
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
public function getPadSize():int
|
||||
{
|
||||
return pad_size;
|
||||
}
|
||||
|
||||
public function hash(src:ByteArray):ByteArray
|
||||
{
|
||||
var savedLength:uint = src.length;
|
||||
var savedEndian:String = src.endian;
|
||||
|
||||
src.endian = Endian.BIG_ENDIAN;
|
||||
var len:uint = savedLength *8;
|
||||
// pad to nearest int.
|
||||
while (src.length%4!=0) {
|
||||
src[src.length]=0;
|
||||
}
|
||||
// convert ByteArray to an array of uint
|
||||
src.position=0;
|
||||
var a:Array = [];
|
||||
for (var i:uint=0;i<src.length;i+=4) {
|
||||
a.push(src.readUnsignedInt());
|
||||
}
|
||||
var h:Array = core(a, len);
|
||||
var out:ByteArray = new ByteArray;
|
||||
var words:uint = getHashSize()/4;
|
||||
for (i=0;i<words;i++) {
|
||||
out.writeUnsignedInt(h[i]);
|
||||
}
|
||||
// unpad, to leave the source untouched.
|
||||
src.length = savedLength;
|
||||
src.endian = savedEndian;
|
||||
return out;
|
||||
}
|
||||
protected function core(x:Array, len:uint):Array {
|
||||
return null;
|
||||
}
|
||||
|
||||
public function toString():String {
|
||||
return "sha";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,82 +0,0 @@
|
||||
/**
|
||||
* HMAC
|
||||
*
|
||||
* An ActionScript 3 implementation of HMAC, Keyed-Hashing for Message
|
||||
* Authentication, as defined by RFC-2104
|
||||
* Copyright (c) 2007 Henri Torgemane
|
||||
*
|
||||
* See LICENSE.txt for full license information.
|
||||
*/
|
||||
package com.hurlant.crypto.hash
|
||||
{
|
||||
import flash.utils.ByteArray;
|
||||
import com.hurlant.util.Hex;
|
||||
|
||||
public class HMAC implements IHMAC
|
||||
{
|
||||
private var hash:IHash;
|
||||
private var bits:uint;
|
||||
|
||||
/**
|
||||
* Create a HMAC object, using a Hash function, and
|
||||
* optionally a number of bits to return.
|
||||
* The HMAC will be truncated to that size if needed.
|
||||
*/
|
||||
public function HMAC(hash:IHash, bits:uint=0) {
|
||||
this.hash = hash;
|
||||
this.bits = bits;
|
||||
}
|
||||
|
||||
|
||||
public function getHashSize():uint {
|
||||
if (bits!=0) {
|
||||
return bits/8;
|
||||
} else {
|
||||
return hash.getHashSize();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Compute a HMAC using a key and some data.
|
||||
* It doesn't modify either, and returns a new ByteArray with the HMAC value.
|
||||
*/
|
||||
public function compute(key:ByteArray, data:ByteArray):ByteArray {
|
||||
var hashKey:ByteArray;
|
||||
if (key.length>hash.getInputSize()) {
|
||||
hashKey = hash.hash(key);
|
||||
} else {
|
||||
hashKey = new ByteArray;
|
||||
hashKey.writeBytes(key);
|
||||
}
|
||||
while (hashKey.length<hash.getInputSize()) {
|
||||
hashKey[hashKey.length]=0;
|
||||
}
|
||||
var innerKey:ByteArray = new ByteArray;
|
||||
var outerKey:ByteArray = new ByteArray;
|
||||
for (var i:uint=0;i<hashKey.length;i++) {
|
||||
innerKey[i] = hashKey[i] ^ 0x36;
|
||||
outerKey[i] = hashKey[i] ^ 0x5c;
|
||||
}
|
||||
// inner + data
|
||||
innerKey.position = hashKey.length;
|
||||
innerKey.writeBytes(data);
|
||||
var innerHash:ByteArray = hash.hash(innerKey);
|
||||
// outer + innerHash
|
||||
outerKey.position = hashKey.length;
|
||||
outerKey.writeBytes(innerHash);
|
||||
var outerHash:ByteArray = hash.hash(outerKey);
|
||||
if (bits>0 && bits<8*outerHash.length) {
|
||||
outerHash.length = bits/8;
|
||||
}
|
||||
return outerHash;
|
||||
}
|
||||
public function dispose():void {
|
||||
hash = null;
|
||||
bits = 0;
|
||||
}
|
||||
public function toString():String {
|
||||
return "hmac-"+(bits>0?bits+"-":"")+hash.toString();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
/**
|
||||
* HMAC
|
||||
*
|
||||
* An ActionScript 3 interface for HMAC & MAC
|
||||
* implementations.
|
||||
*
|
||||
* Loosely copyrighted by Bobby Parker
|
||||
*
|
||||
* See LICENSE.txt for full license information.
|
||||
*/
|
||||
package com.hurlant.crypto.hash
|
||||
{
|
||||
import flash.utils.ByteArray;
|
||||
|
||||
public interface IHMAC
|
||||
{
|
||||
function getHashSize():uint;
|
||||
/**
|
||||
* Compute a HMAC using a key and some data.
|
||||
* It doesn't modify either, and returns a new ByteArray with the HMAC value.
|
||||
*/
|
||||
function compute(key:ByteArray, data:ByteArray):ByteArray;
|
||||
function dispose():void;
|
||||
function toString():String;
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
/**
|
||||
* IHash
|
||||
*
|
||||
* An interface for each hash function to implement
|
||||
* Copyright (c) 2007 Henri Torgemane
|
||||
*
|
||||
* See LICENSE.txt for full license information.
|
||||
*/
|
||||
package com.hurlant.crypto.hash
|
||||
{
|
||||
import flash.utils.ByteArray;
|
||||
|
||||
public interface IHash
|
||||
{
|
||||
function getInputSize():uint;
|
||||
function getHashSize():uint;
|
||||
function hash(src:ByteArray):ByteArray;
|
||||
function toString():String;
|
||||
function getPadSize():int;
|
||||
}
|
||||
}
|
||||
@@ -1,137 +0,0 @@
|
||||
/**
|
||||
* MAC
|
||||
*
|
||||
* An ActionScript 3 implementation of MAC, Message Authentication Code
|
||||
* for use with SSL 3.0.
|
||||
* Loosely copyrighted by Bobby Parker.
|
||||
* As3crypto copyrighted by Henri Torgemane.
|
||||
*
|
||||
* See LICENSE.txt for full license information.
|
||||
*/
|
||||
package com.hurlant.crypto.hash
|
||||
{
|
||||
import flash.utils.ByteArray;
|
||||
import com.hurlant.util.Hex;
|
||||
|
||||
public class MAC implements IHMAC
|
||||
{
|
||||
private var hash:IHash;
|
||||
private var bits:uint;
|
||||
private var pad_1:ByteArray;
|
||||
private var pad_2:ByteArray;
|
||||
private var innerHash:ByteArray;
|
||||
private var outerHash:ByteArray;
|
||||
private var outerKey:ByteArray;
|
||||
private var innerKey:ByteArray;
|
||||
/**
|
||||
* Create a MAC object (for SSL 3.0 ) and
|
||||
* optionally a number of bits to return.
|
||||
* The MAC will be truncated to that size if needed.
|
||||
*/
|
||||
public function MAC(hash:IHash, bits:uint=0) {
|
||||
this.hash = hash;
|
||||
this.bits = bits;
|
||||
innerHash = new ByteArray();
|
||||
outerHash = new ByteArray();
|
||||
innerKey = new ByteArray();
|
||||
outerKey = new ByteArray();
|
||||
|
||||
|
||||
if (hash != null) {
|
||||
var pad_size:int = hash.getPadSize();
|
||||
pad_1 = new ByteArray();
|
||||
pad_2 = new ByteArray();
|
||||
|
||||
for (var x:int = 0; x < pad_size; x++) {
|
||||
pad_1.writeByte(0x36);
|
||||
pad_2.writeByte(0x5c);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function setPadSize(pad_size:int) : void { }
|
||||
|
||||
public function getHashSize():uint {
|
||||
if (bits!=0) {
|
||||
return bits/8;
|
||||
} else {
|
||||
return hash.getHashSize();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Compute a MAC using a key and some data.
|
||||
*
|
||||
*/
|
||||
public function compute(key:ByteArray, data:ByteArray):ByteArray {
|
||||
// take that incoming key and do hash(key + pad_2 + hash(key + pad_1 + sequence + length + record)
|
||||
// note that data = (sequence + type + length + record)
|
||||
|
||||
if (pad_1 == null) {
|
||||
var pad_size:int = hash.getPadSize();
|
||||
pad_1 = new ByteArray();
|
||||
pad_2 = new ByteArray();
|
||||
|
||||
for (var x:int = 0; x < pad_size; x++) {
|
||||
pad_1.writeByte(0x36);
|
||||
pad_2.writeByte(0x5c);
|
||||
}
|
||||
}
|
||||
|
||||
// Do some preliminary checking on stuff
|
||||
/*
|
||||
if (key.length > hash.getInputSize()) {
|
||||
hashKey = hash.hash(key);
|
||||
} else {
|
||||
hashKey = new ByteArray;
|
||||
hashKey.writeBytes(key);
|
||||
}
|
||||
|
||||
while (hashKey.length < hash.getInputSize() ) {
|
||||
hashKey[hashKey.length] = 0;
|
||||
} */
|
||||
// Henri's conventions work just fine here..
|
||||
|
||||
innerKey.length = 0;
|
||||
outerKey.length = 0;
|
||||
// trace("MAC Key: " + Hex.fromArray(key));
|
||||
// trace("Key Length: " + key.length);
|
||||
// trace("Pad_1 : " + Hex.fromArray(pad_1));
|
||||
// inner hash calc
|
||||
innerKey.writeBytes(key);
|
||||
innerKey.writeBytes(pad_1);
|
||||
innerKey.writeBytes(data);
|
||||
// trace("MAC Inner Key: " + Hex.fromArray(innerKey));
|
||||
|
||||
innerHash = hash.hash(innerKey);
|
||||
// trace("MAC Inner Hash: " + Hex.fromArray(innerHash));
|
||||
|
||||
// outer hash calc
|
||||
outerKey.writeBytes(key);
|
||||
outerKey.writeBytes(pad_2);
|
||||
outerKey.writeBytes(innerHash);
|
||||
|
||||
// trace("MAC Outer Key: " + Hex.fromArray(outerKey));
|
||||
outerHash = hash.hash(outerKey);
|
||||
|
||||
|
||||
if (bits > 0 && bits < 8*outerHash.length) {
|
||||
outerHash.length = bits/8;
|
||||
}
|
||||
|
||||
// trace("MAC for record: " + Hex.fromArray(outerHash));
|
||||
return outerHash;
|
||||
|
||||
}
|
||||
|
||||
public function dispose():void {
|
||||
hash = null;
|
||||
bits = 0;
|
||||
}
|
||||
public function toString():String {
|
||||
return "mac-"+(bits>0?bits+"-":"")+hash.toString();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,124 +0,0 @@
|
||||
/**
|
||||
* MD2
|
||||
*
|
||||
* An ActionScript 3 implementation of the RSA Data Security, Inc MD2 Message
|
||||
* Digest Algorithm, as defined in RFC 1319
|
||||
* Copyright (c) 2007 Henri Torgemane
|
||||
*
|
||||
* See LICENSE.txt for full license information.
|
||||
*
|
||||
* Excerpt from http://en.wikipedia.org/wiki/MD2:
|
||||
* >
|
||||
* > Rogier and Chauvaud (1997) described collisions of MD2's compression function,
|
||||
* > although they were unable to extend the attack to the full MD2.
|
||||
* >
|
||||
* > In 2004, MD2 was shown to be vulnerable to a preimage attack with time
|
||||
* > complexity equivalent to 2104 applications of the compression function
|
||||
* > (Muller, 2004).
|
||||
* > The author concludes, "MD2 can no longer be considered a secure one-way
|
||||
* > hash function".
|
||||
*
|
||||
* also, this implementaton is quite slow.
|
||||
*/
|
||||
|
||||
package com.hurlant.crypto.hash
|
||||
{
|
||||
import flash.utils.ByteArray;
|
||||
|
||||
public class MD2 implements IHash
|
||||
{
|
||||
public static const HASH_SIZE:int = 16;
|
||||
public var pad_size:int = 48; // probably will never get used, only here for SSL 3.0 support
|
||||
|
||||
private static const S:Array = [ // PI Digits
|
||||
41, 46, 67, 201, 162, 216, 124, 1, 61, 54, 84, 161, 236, 240, 6, 19,
|
||||
98, 167, 5, 243, 192, 199, 115, 140, 152, 147, 43, 217, 188, 76, 130, 202,
|
||||
30, 155, 87, 60, 253, 212, 224, 22, 103, 66, 111, 24, 138, 23, 229, 18,
|
||||
190, 78, 196, 214, 218, 158, 222, 73, 160, 251, 245, 142, 187, 47, 238, 122,
|
||||
169, 104, 121, 145, 21, 178, 7, 63, 148, 194, 16, 137, 11, 34, 95, 33,
|
||||
128, 127, 93, 154, 90, 144, 50, 39, 53, 62, 204, 231, 191, 247, 151, 3,
|
||||
255, 25, 48, 179, 72, 165, 181, 209, 215, 94, 146, 42, 172, 86, 170, 198,
|
||||
79, 184, 56, 210, 150, 164, 125, 182, 118, 252, 107, 226, 156, 116, 4, 241,
|
||||
69, 157, 112, 89, 100, 113, 135, 32, 134, 91, 207, 101, 230, 45, 168, 2,
|
||||
27, 96, 37, 173, 174, 176, 185, 246, 28, 70, 97, 105, 52, 64, 126, 15,
|
||||
85, 71, 163, 35, 221, 81, 175, 58, 195, 92, 249, 206, 186, 197, 234, 38,
|
||||
44, 83, 13, 110, 133, 40, 132, 9, 211, 223, 205, 244, 65, 129, 77, 82,
|
||||
106, 220, 55, 200, 108, 193, 171, 250, 36, 225, 123, 8, 12, 189, 177, 74,
|
||||
120, 136, 149, 139, 227, 99, 232, 109, 233, 203, 213, 254, 59, 0, 29, 57,
|
||||
242, 239, 183, 14, 102, 88, 208, 228, 166, 119, 114, 248, 235, 117, 75, 10,
|
||||
49, 68, 80, 180, 143, 237, 31, 26, 219, 153, 141, 51, 159, 17, 131, 20 ];
|
||||
|
||||
|
||||
public function MD2() { }
|
||||
|
||||
public function getInputSize():uint
|
||||
{
|
||||
return 16;
|
||||
}
|
||||
|
||||
public function getPadSize():int {
|
||||
return pad_size;
|
||||
}
|
||||
|
||||
public function getHashSize():uint
|
||||
{
|
||||
return HASH_SIZE;
|
||||
}
|
||||
|
||||
public function hash(src:ByteArray):ByteArray
|
||||
{
|
||||
var savedLength:uint = src.length;
|
||||
|
||||
// 3.1 Step 1. Padding
|
||||
var i:uint = (16-src.length%16) || 16;
|
||||
do {
|
||||
src[src.length]=i;
|
||||
} while (src.length%16!=0);
|
||||
|
||||
// 3.2 Step 2. Checksum
|
||||
var len:uint = src.length;
|
||||
var checksum:ByteArray = new ByteArray;
|
||||
var L:uint = 0;
|
||||
for (i = 0;i<len;i+=16) {
|
||||
for (var j:uint=0;j<16;j++) {
|
||||
L = checksum[j] ^= S[src[i+j] ^ L];
|
||||
}
|
||||
}
|
||||
src.position = src.length;
|
||||
src.writeBytes(checksum);
|
||||
len += 16;
|
||||
|
||||
// 3.3 Step 3. MD Buffer
|
||||
var X:ByteArray = new ByteArray;
|
||||
|
||||
// 3.4 Process Message
|
||||
for (i=0;i<len;i+=16) {
|
||||
|
||||
/* Copy block i into X */
|
||||
for (j=0;j<16;j++) {
|
||||
X[32+j] = (X[16+j] = src[i+j])^X[j];
|
||||
}
|
||||
var t:uint=0;
|
||||
/* Do 18 rounds */
|
||||
for (j=0;j<18;j++) {
|
||||
/* Round j. */
|
||||
for (var k:uint=0;k<48;k++) {
|
||||
X[k] = t = X[k]^S[t];
|
||||
}
|
||||
t = (t+j)&0xff;
|
||||
}
|
||||
}
|
||||
// 3.5 Step 5. Output
|
||||
X.length = 16;
|
||||
// restore original length;
|
||||
src.length = savedLength;
|
||||
return X;
|
||||
}
|
||||
|
||||
public function toString():String
|
||||
{
|
||||
return "md2";
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,204 +0,0 @@
|
||||
/**
|
||||
* MD5
|
||||
*
|
||||
* An ActionScript 3 implementation of the RSA Data Security, Inc. MD5 Message
|
||||
* Digest Algorithm, as defined in RFC 1321.
|
||||
* Copyright (c) 2007 Henri Torgemane
|
||||
*
|
||||
* Derived from
|
||||
* A JavaScript implementation of the same.
|
||||
* Version 2.1 Copyright (C) Paul Johnston 1999 - 2002.
|
||||
* Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
|
||||
*
|
||||
* Note:
|
||||
* This algorithm should not be your first choice for new developements, but is
|
||||
* included to allow interoperability with existing codes and protocols.
|
||||
*
|
||||
* See LICENSE.txt for full license information.
|
||||
*/
|
||||
package com.hurlant.crypto.hash
|
||||
{
|
||||
import flash.utils.ByteArray;
|
||||
import flash.utils.Endian;
|
||||
|
||||
public class MD5 implements IHash
|
||||
{
|
||||
public static const HASH_SIZE:int = 16;
|
||||
public var pad_size:int = 48;
|
||||
|
||||
public function MD5() { }
|
||||
|
||||
public function getInputSize():uint
|
||||
{
|
||||
return 64;
|
||||
}
|
||||
|
||||
public function getHashSize():uint
|
||||
{
|
||||
return HASH_SIZE;
|
||||
}
|
||||
|
||||
public function getPadSize():int
|
||||
{
|
||||
return pad_size;
|
||||
}
|
||||
|
||||
public function hash(src:ByteArray):ByteArray
|
||||
{
|
||||
var len:uint = src.length *8;
|
||||
var savedEndian:String = src.endian;
|
||||
// pad to nearest int.
|
||||
while (src.length%4!=0) {
|
||||
src[src.length]=0;
|
||||
}
|
||||
// convert ByteArray to an array of uint
|
||||
src.position=0;
|
||||
var a:Array = [];
|
||||
src.endian=Endian.LITTLE_ENDIAN
|
||||
for (var i:uint=0;i<src.length;i+=4) {
|
||||
a.push(src.readUnsignedInt());
|
||||
}
|
||||
var h:Array = core_md5(a, len);
|
||||
var out:ByteArray = new ByteArray;
|
||||
out.endian=Endian.LITTLE_ENDIAN;
|
||||
for (i=0;i<4;i++) {
|
||||
out.writeUnsignedInt(h[i]);
|
||||
}
|
||||
// restore length!
|
||||
src.length = len/8;
|
||||
src.endian = savedEndian;
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
private function core_md5(x:Array, len:uint):Array {
|
||||
/* append padding */
|
||||
x[len >> 5] |= 0x80 << ((len) % 32);
|
||||
x[(((len + 64) >>> 9) << 4) + 14] = len;
|
||||
|
||||
var a:uint = 0x67452301; // 1732584193;
|
||||
var b:uint = 0xEFCDAB89; //-271733879;
|
||||
var c:uint = 0x98BADCFE; //-1732584194;
|
||||
var d:uint = 0x10325476; // 271733878;
|
||||
|
||||
for(var i:uint = 0; i < x.length; i += 16)
|
||||
{
|
||||
x[i]||=0; x[i+1]||=0; x[i+2]||=0; x[i+3]||=0;
|
||||
x[i+4]||=0; x[i+5]||=0; x[i+6]||=0; x[i+7]||=0;
|
||||
x[i+8]||=0; x[i+9]||=0; x[i+10]||=0; x[i+11]||=0;
|
||||
x[i+12]||=0; x[i+13]||=0; x[i+14]||=0; x[i+15]||=0;
|
||||
|
||||
var olda:uint = a;
|
||||
var oldb:uint = b;
|
||||
var oldc:uint = c;
|
||||
var oldd:uint = d;
|
||||
|
||||
a = ff(a, b, c, d, x[i+ 0], 7 , 0xD76AA478);
|
||||
d = ff(d, a, b, c, x[i+ 1], 12, 0xE8C7B756);
|
||||
c = ff(c, d, a, b, x[i+ 2], 17, 0x242070DB);
|
||||
b = ff(b, c, d, a, x[i+ 3], 22, 0xC1BDCEEE);
|
||||
a = ff(a, b, c, d, x[i+ 4], 7 , 0xF57C0FAF);
|
||||
d = ff(d, a, b, c, x[i+ 5], 12, 0x4787C62A);
|
||||
c = ff(c, d, a, b, x[i+ 6], 17, 0xA8304613);
|
||||
b = ff(b, c, d, a, x[i+ 7], 22, 0xFD469501);
|
||||
a = ff(a, b, c, d, x[i+ 8], 7 , 0x698098D8);
|
||||
d = ff(d, a, b, c, x[i+ 9], 12, 0x8B44F7AF);
|
||||
c = ff(c, d, a, b, x[i+10], 17, 0xFFFF5BB1);
|
||||
b = ff(b, c, d, a, x[i+11], 22, 0x895CD7BE);
|
||||
a = ff(a, b, c, d, x[i+12], 7 , 0x6B901122);
|
||||
d = ff(d, a, b, c, x[i+13], 12, 0xFD987193);
|
||||
c = ff(c, d, a, b, x[i+14], 17, 0xA679438E);
|
||||
b = ff(b, c, d, a, x[i+15], 22, 0x49B40821);
|
||||
|
||||
a = gg(a, b, c, d, x[i+ 1], 5 , 0xf61e2562);
|
||||
d = gg(d, a, b, c, x[i+ 6], 9 , 0xc040b340);
|
||||
c = gg(c, d, a, b, x[i+11], 14, 0x265e5a51);
|
||||
b = gg(b, c, d, a, x[i+ 0], 20, 0xe9b6c7aa);
|
||||
a = gg(a, b, c, d, x[i+ 5], 5 , 0xd62f105d);
|
||||
d = gg(d, a, b, c, x[i+10], 9 , 0x2441453);
|
||||
c = gg(c, d, a, b, x[i+15], 14, 0xd8a1e681);
|
||||
b = gg(b, c, d, a, x[i+ 4], 20, 0xe7d3fbc8);
|
||||
a = gg(a, b, c, d, x[i+ 9], 5 , 0x21e1cde6);
|
||||
d = gg(d, a, b, c, x[i+14], 9 , 0xc33707d6);
|
||||
c = gg(c, d, a, b, x[i+ 3], 14, 0xf4d50d87);
|
||||
b = gg(b, c, d, a, x[i+ 8], 20, 0x455a14ed);
|
||||
a = gg(a, b, c, d, x[i+13], 5 , 0xa9e3e905);
|
||||
d = gg(d, a, b, c, x[i+ 2], 9 , 0xfcefa3f8);
|
||||
c = gg(c, d, a, b, x[i+ 7], 14, 0x676f02d9);
|
||||
b = gg(b, c, d, a, x[i+12], 20, 0x8d2a4c8a);
|
||||
|
||||
a = hh(a, b, c, d, x[i+ 5], 4 , 0xfffa3942);
|
||||
d = hh(d, a, b, c, x[i+ 8], 11, 0x8771f681);
|
||||
c = hh(c, d, a, b, x[i+11], 16, 0x6d9d6122);
|
||||
b = hh(b, c, d, a, x[i+14], 23, 0xfde5380c);
|
||||
a = hh(a, b, c, d, x[i+ 1], 4 , 0xa4beea44);
|
||||
d = hh(d, a, b, c, x[i+ 4], 11, 0x4bdecfa9);
|
||||
c = hh(c, d, a, b, x[i+ 7], 16, 0xf6bb4b60);
|
||||
b = hh(b, c, d, a, x[i+10], 23, 0xbebfbc70);
|
||||
a = hh(a, b, c, d, x[i+13], 4 , 0x289b7ec6);
|
||||
d = hh(d, a, b, c, x[i+ 0], 11, 0xeaa127fa);
|
||||
c = hh(c, d, a, b, x[i+ 3], 16, 0xd4ef3085);
|
||||
b = hh(b, c, d, a, x[i+ 6], 23, 0x4881d05);
|
||||
a = hh(a, b, c, d, x[i+ 9], 4 , 0xd9d4d039);
|
||||
d = hh(d, a, b, c, x[i+12], 11, 0xe6db99e5);
|
||||
c = hh(c, d, a, b, x[i+15], 16, 0x1fa27cf8);
|
||||
b = hh(b, c, d, a, x[i+ 2], 23, 0xc4ac5665);
|
||||
|
||||
a = ii(a, b, c, d, x[i+ 0], 6 , 0xf4292244);
|
||||
d = ii(d, a, b, c, x[i+ 7], 10, 0x432aff97);
|
||||
c = ii(c, d, a, b, x[i+14], 15, 0xab9423a7);
|
||||
b = ii(b, c, d, a, x[i+ 5], 21, 0xfc93a039);
|
||||
a = ii(a, b, c, d, x[i+12], 6 , 0x655b59c3);
|
||||
d = ii(d, a, b, c, x[i+ 3], 10, 0x8f0ccc92);
|
||||
c = ii(c, d, a, b, x[i+10], 15, 0xffeff47d);
|
||||
b = ii(b, c, d, a, x[i+ 1], 21, 0x85845dd1);
|
||||
a = ii(a, b, c, d, x[i+ 8], 6 , 0x6fa87e4f);
|
||||
d = ii(d, a, b, c, x[i+15], 10, 0xfe2ce6e0);
|
||||
c = ii(c, d, a, b, x[i+ 6], 15, 0xa3014314);
|
||||
b = ii(b, c, d, a, x[i+13], 21, 0x4e0811a1);
|
||||
a = ii(a, b, c, d, x[i+ 4], 6 , 0xf7537e82);
|
||||
d = ii(d, a, b, c, x[i+11], 10, 0xbd3af235);
|
||||
c = ii(c, d, a, b, x[i+ 2], 15, 0x2ad7d2bb);
|
||||
b = ii(b, c, d, a, x[i+ 9], 21, 0xeb86d391);
|
||||
|
||||
a += olda;
|
||||
b += oldb;
|
||||
c += oldc;
|
||||
d += oldd;
|
||||
|
||||
}
|
||||
return [ a, b, c, d ];
|
||||
}
|
||||
|
||||
/*
|
||||
* Bitwise rotate a 32-bit number to the left.
|
||||
*/
|
||||
private function rol(num:uint, cnt:uint):uint
|
||||
{
|
||||
return (num << cnt) | (num >>> (32 - cnt));
|
||||
}
|
||||
|
||||
/*
|
||||
* These functions implement the four basic operations the algorithm uses.
|
||||
*/
|
||||
private function cmn(q:uint, a:uint, b:uint, x:uint, s:uint, t:uint):uint {
|
||||
return rol(a + q + x + t, s) + b;
|
||||
}
|
||||
private function ff(a:uint, b:uint, c:uint, d:uint, x:uint, s:uint, t:uint):uint {
|
||||
return cmn((b & c) | ((~b) & d), a, b, x, s, t);
|
||||
}
|
||||
private function gg(a:uint, b:uint, c:uint, d:uint, x:uint, s:uint, t:uint):uint {
|
||||
return cmn((b & d) | (c & (~d)), a, b, x, s, t);
|
||||
}
|
||||
private function hh(a:uint, b:uint, c:uint, d:uint, x:uint, s:uint, t:uint):uint {
|
||||
return cmn(b ^ c ^ d, a, b, x, s, t);
|
||||
}
|
||||
private function ii(a:uint, b:uint, c:uint, d:uint, x:uint, s:uint, t:uint):uint {
|
||||
return cmn(c ^ (b | (~d)), a, b, x, s, t);
|
||||
}
|
||||
|
||||
public function toString():String {
|
||||
return "md5";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,106 +0,0 @@
|
||||
/**
|
||||
* SHA1
|
||||
*
|
||||
* An ActionScript 3 implementation of Secure Hash Algorithm, SHA-1, as defined
|
||||
* in FIPS PUB 180-1
|
||||
* Copyright (c) 2007 Henri Torgemane
|
||||
*
|
||||
* Derived from:
|
||||
* A JavaScript implementation of the Secure Hash Algorithm, SHA-1, as defined
|
||||
* in FIPS PUB 180-1
|
||||
* Version 2.1a Copyright Paul Johnston 2000 - 2002.
|
||||
* Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
|
||||
*
|
||||
* See LICENSE.txt for full license information.
|
||||
*/
|
||||
package com.hurlant.crypto.hash
|
||||
{
|
||||
|
||||
|
||||
public class SHA1 extends SHABase implements IHash
|
||||
{
|
||||
public static const HASH_SIZE:int = 20;
|
||||
|
||||
public override function getHashSize():uint {
|
||||
return HASH_SIZE;
|
||||
}
|
||||
|
||||
protected override function core(x:Array, len:uint):Array
|
||||
{
|
||||
/* append padding */
|
||||
x[len >> 5] |= 0x80 << (24 - len % 32);
|
||||
x[((len + 64 >> 9) << 4) + 15] = len;
|
||||
|
||||
var w:Array = [];
|
||||
var a:uint = 0x67452301; //1732584193;
|
||||
var b:uint = 0xEFCDAB89; //-271733879;
|
||||
var c:uint = 0x98BADCFE; //-1732584194;
|
||||
var d:uint = 0x10325476; //271733878;
|
||||
var e:uint = 0xC3D2E1F0; //-1009589776;
|
||||
|
||||
for(var i:uint = 0; i < x.length; i += 16)
|
||||
{
|
||||
|
||||
var olda:uint = a;
|
||||
var oldb:uint = b;
|
||||
var oldc:uint = c;
|
||||
var oldd:uint = d;
|
||||
var olde:uint = e;
|
||||
|
||||
for(var j:uint = 0; j < 80; j++)
|
||||
{
|
||||
if (j < 16) {
|
||||
w[j] = x[i + j] || 0;
|
||||
} else {
|
||||
w[j] = rol(w[j-3] ^ w[j-8] ^ w[j-14] ^ w[j-16], 1);
|
||||
}
|
||||
var t:uint = rol(a,5) + ft(j,b,c,d) + e + w[j] + kt(j);
|
||||
e = d;
|
||||
d = c;
|
||||
c = rol(b, 30);
|
||||
b = a;
|
||||
a = t;
|
||||
}
|
||||
a += olda;
|
||||
b += oldb;
|
||||
c += oldc;
|
||||
d += oldd;
|
||||
e += olde;
|
||||
}
|
||||
return [ a, b, c, d, e ];
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Bitwise rotate a 32-bit number to the left.
|
||||
*/
|
||||
private function rol(num:uint, cnt:uint):uint
|
||||
{
|
||||
return (num << cnt) | (num >>> (32 - cnt));
|
||||
}
|
||||
|
||||
/*
|
||||
* Perform the appropriate triplet combination function for the current
|
||||
* iteration
|
||||
*/
|
||||
private function ft(t:uint, b:uint, c:uint, d:uint):uint
|
||||
{
|
||||
if(t < 20) return (b & c) | ((~b) & d);
|
||||
if(t < 40) return b ^ c ^ d;
|
||||
if(t < 60) return (b & c) | (b & d) | (c & d);
|
||||
return b ^ c ^ d;
|
||||
}
|
||||
|
||||
/*
|
||||
* Determine the appropriate additive constant for the current iteration
|
||||
*/
|
||||
private function kt(t:uint):uint
|
||||
{
|
||||
return (t < 20) ? 0x5A827999 : (t < 40) ? 0x6ED9EBA1 :
|
||||
(t < 60) ? 0x8F1BBCDC : 0xCA62C1D6;
|
||||
}
|
||||
public override function toString():String {
|
||||
return "sha1";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
/**
|
||||
* SHA224
|
||||
*
|
||||
* An ActionScript 3 implementation of Secure Hash Algorithm, SHA-224, as defined
|
||||
* in FIPS PUB 180-2
|
||||
* Copyright (c) 2007 Henri Torgemane
|
||||
*
|
||||
* See LICENSE.txt for full license information.
|
||||
*/
|
||||
package com.hurlant.crypto.hash
|
||||
{
|
||||
public class SHA224 extends SHA256
|
||||
{
|
||||
function SHA224() {
|
||||
h = [
|
||||
0xc1059ed8, 0x367cd507, 0x3070dd17, 0xf70e5939,
|
||||
0xffc00b31, 0x68581511, 0x64f98fa7, 0xbefa4fa4
|
||||
];
|
||||
}
|
||||
|
||||
public override function getHashSize():uint {
|
||||
return 28;
|
||||
}
|
||||
public override function toString():String {
|
||||
return "sha224";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,115 +0,0 @@
|
||||
/**
|
||||
* SHA256
|
||||
*
|
||||
* An ActionScript 3 implementation of Secure Hash Algorithm, SHA-256, as defined
|
||||
* in FIPS PUB 180-2
|
||||
* Copyright (c) 2007 Henri Torgemane
|
||||
*
|
||||
* Derived from:
|
||||
* A JavaScript implementation of the Secure Hash Standard
|
||||
* Version 0.3 Copyright Angel Marin 2003-2004 - http://anmar.eu.org/
|
||||
* Derived from:
|
||||
* A JavaScript implementation of the Secure Hash Algorithm, SHA-1, as defined
|
||||
* in FIPS PUB 180-1
|
||||
* Version 2.1a Copyright Paul Johnston 2000 - 2002.
|
||||
* Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
|
||||
*
|
||||
* See LICENSE.txt for full license information.
|
||||
*/
|
||||
package com.hurlant.crypto.hash
|
||||
{
|
||||
|
||||
|
||||
public class SHA256 extends SHABase implements IHash
|
||||
{
|
||||
|
||||
protected static const k:Array = [
|
||||
0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
|
||||
0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
|
||||
0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
|
||||
0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
|
||||
0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
|
||||
0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
|
||||
0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
|
||||
0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2];
|
||||
protected var h:Array = [
|
||||
0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19
|
||||
];
|
||||
|
||||
public function SHA256(){
|
||||
}
|
||||
|
||||
public override function getHashSize():uint
|
||||
{
|
||||
return 32;
|
||||
}
|
||||
|
||||
protected override function core(x:Array, len:uint):Array {
|
||||
/* append padding */
|
||||
x[len >> 5] |= 0x80 << (24 - len % 32);
|
||||
x[((len + 64 >> 9) << 4) + 15] = len;
|
||||
|
||||
var w:Array = [];
|
||||
var a:uint = h[0];
|
||||
var b:uint = h[1];
|
||||
var c:uint = h[2];
|
||||
var d:uint = h[3];
|
||||
var e:uint = h[4];
|
||||
var f:uint = h[5];
|
||||
var g:uint = h[6];
|
||||
var h:uint = h[7];
|
||||
|
||||
for (var i:uint=0; i<x.length; i+=16) {
|
||||
var olda:uint = a;
|
||||
var oldb:uint = b;
|
||||
var oldc:uint = c;
|
||||
var oldd:uint = d;
|
||||
var olde:uint = e;
|
||||
var oldf:uint = f;
|
||||
var oldg:uint = g;
|
||||
var oldh:uint = h;
|
||||
|
||||
for (var j:uint=0; j<64; j++) {
|
||||
if (j<16) {
|
||||
w[j] = x[i+j] || 0;
|
||||
} else {
|
||||
var s0:uint = rrol(w[j-15],7)^rrol(w[j-15],18)^(w[j-15]>>>3);
|
||||
var s1:uint = rrol(w[j-2], 17)^rrol(w[j-2],19)^(w[j-2]>>>10);
|
||||
w[j] = w[j-16] + s0 + w[j-7] + s1;
|
||||
}
|
||||
var t2:uint = (rrol(a,2) ^ rrol(a,13) ^ rrol(a,22)) + ((a&b) ^ (a&c) ^ (b&c));
|
||||
var t1:uint = h + (rrol(e,6) ^ rrol(e,11) ^ rrol(e,25)) + ((e&f)^(g&~e)) + k[j] + w[j]
|
||||
h = g;
|
||||
g = f;
|
||||
f = e;
|
||||
e = d + t1;
|
||||
d = c;
|
||||
c = b;
|
||||
b = a;
|
||||
a = t1 + t2;
|
||||
|
||||
}
|
||||
a += olda;
|
||||
b += oldb;
|
||||
c += oldc;
|
||||
d += oldd;
|
||||
e += olde;
|
||||
f += oldf;
|
||||
g += oldg;
|
||||
h += oldh;
|
||||
}
|
||||
return [ a,b,c,d,e,f,g,h ];
|
||||
}
|
||||
|
||||
/*
|
||||
* Bitwise rotate a 32-bit number to the right.
|
||||
*/
|
||||
protected function rrol(num:uint, cnt:uint):uint {
|
||||
return (num << (32-cnt)) | (num >>> cnt);
|
||||
}
|
||||
|
||||
public override function toString():String {
|
||||
return "sha256";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,71 +0,0 @@
|
||||
/**
|
||||
* SHABase
|
||||
*
|
||||
* An ActionScript 3 abstract class for the SHA family of hash functions
|
||||
* Copyright (c) 2007 Henri Torgemane
|
||||
*
|
||||
* See LICENSE.txt for full license information.
|
||||
*/
|
||||
package com.hurlant.crypto.hash
|
||||
{
|
||||
import flash.utils.ByteArray;
|
||||
import flash.utils.Endian;
|
||||
|
||||
public class SHABase implements IHash
|
||||
{
|
||||
|
||||
public function SHABase() { }
|
||||
|
||||
public var pad_size:int = 40;
|
||||
public function getInputSize():uint
|
||||
{
|
||||
return 64;
|
||||
}
|
||||
|
||||
public function getHashSize():uint
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
public function getPadSize():int
|
||||
{
|
||||
return pad_size;
|
||||
}
|
||||
|
||||
public function hash(src:ByteArray):ByteArray
|
||||
{
|
||||
var savedLength:uint = src.length;
|
||||
var savedEndian:String = src.endian;
|
||||
|
||||
src.endian = Endian.BIG_ENDIAN;
|
||||
var len:uint = savedLength *8;
|
||||
// pad to nearest int.
|
||||
while (src.length%4!=0) {
|
||||
src[src.length]=0;
|
||||
}
|
||||
// convert ByteArray to an array of uint
|
||||
src.position=0;
|
||||
var a:Array = [];
|
||||
for (var i:uint=0;i<src.length;i+=4) {
|
||||
a.push(src.readUnsignedInt());
|
||||
}
|
||||
var h:Array = core(a, len);
|
||||
var out:ByteArray = new ByteArray;
|
||||
var words:uint = getHashSize()/4;
|
||||
for (i=0;i<words;i++) {
|
||||
out.writeUnsignedInt(h[i]);
|
||||
}
|
||||
// unpad, to leave the source untouched.
|
||||
src.length = savedLength;
|
||||
src.endian = savedEndian;
|
||||
return out;
|
||||
}
|
||||
protected function core(x:Array, len:uint):Array {
|
||||
return null;
|
||||
}
|
||||
|
||||
public function toString():String {
|
||||
return "sha";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,90 +0,0 @@
|
||||
/**
|
||||
* ARC4
|
||||
*
|
||||
* An ActionScript 3 implementation of RC4
|
||||
* Copyright (c) 2007 Henri Torgemane
|
||||
*
|
||||
* Derived from:
|
||||
* The jsbn library, Copyright (c) 2003-2005 Tom Wu
|
||||
*
|
||||
* See LICENSE.txt for full license information.
|
||||
*/
|
||||
package com.hurlant.crypto.prng
|
||||
{
|
||||
import com.hurlant.crypto.symmetric.IStreamCipher;
|
||||
import com.hurlant.util.Memory;
|
||||
|
||||
import flash.utils.ByteArray;
|
||||
|
||||
public class ARC4 implements IPRNG, IStreamCipher {
|
||||
private var i:int = 0;
|
||||
private var j:int = 0;
|
||||
private var S:ByteArray;
|
||||
private const psize:uint = 256;
|
||||
public function ARC4(key:ByteArray = null){
|
||||
S = new ByteArray;
|
||||
if (key) {
|
||||
init(key);
|
||||
}
|
||||
}
|
||||
public function getPoolSize():uint {
|
||||
return psize;
|
||||
}
|
||||
public function init(key:ByteArray):void {
|
||||
var i:int;
|
||||
var j:int;
|
||||
var t:int;
|
||||
for (i=0; i<256; ++i) {
|
||||
S[i] = i;
|
||||
}
|
||||
j=0;
|
||||
for (i=0; i<256; ++i) {
|
||||
j = (j + S[i] + key[i%key.length]) & 255;
|
||||
t = S[i];
|
||||
S[i] = S[j];
|
||||
S[j] = t;
|
||||
}
|
||||
this.i=0;
|
||||
this.j=0;
|
||||
}
|
||||
public function next():uint {
|
||||
var t:int;
|
||||
i = (i+1)&255;
|
||||
j = (j+S[i])&255;
|
||||
t = S[i];
|
||||
S[i] = S[j];
|
||||
S[j] = t;
|
||||
return S[(t+S[i])&255];
|
||||
}
|
||||
|
||||
public function getBlockSize():uint {
|
||||
return 1;
|
||||
}
|
||||
|
||||
public function encrypt(block:ByteArray):void {
|
||||
var i:uint = 0;
|
||||
while (i<block.length) {
|
||||
block[i++] ^= next();
|
||||
}
|
||||
}
|
||||
public function decrypt(block:ByteArray):void {
|
||||
encrypt(block); // the beauty of XOR.
|
||||
}
|
||||
public function dispose():void {
|
||||
var i:uint = 0;
|
||||
if (S!=null) {
|
||||
for (i=0;i<S.length;i++) {
|
||||
S[i] = Math.random()*256;
|
||||
}
|
||||
S.length=0;
|
||||
S = null;
|
||||
}
|
||||
this.i = 0;
|
||||
this.j = 0;
|
||||
Memory.gc();
|
||||
}
|
||||
public function toString():String {
|
||||
return "rc4";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
/**
|
||||
* IPRNG
|
||||
*
|
||||
* An interface for classes that can be used a pseudo-random number generators
|
||||
* Copyright (c) 2007 Henri Torgemane
|
||||
*
|
||||
* See LICENSE.txt for full license information.
|
||||
*/
|
||||
package com.hurlant.crypto.prng
|
||||
{
|
||||
import flash.utils.ByteArray;
|
||||
|
||||
public interface IPRNG {
|
||||
function getPoolSize():uint;
|
||||
function init(key:ByteArray):void;
|
||||
function next():uint;
|
||||
function dispose():void;
|
||||
function toString():String;
|
||||
}
|
||||
}
|
||||
@@ -1,119 +0,0 @@
|
||||
/**
|
||||
* Random
|
||||
*
|
||||
* An ActionScript 3 implementation of a Random Number Generator
|
||||
* Copyright (c) 2007 Henri Torgemane
|
||||
*
|
||||
* Derived from:
|
||||
* The jsbn library, Copyright (c) 2003-2005 Tom Wu
|
||||
*
|
||||
* See LICENSE.txt for full license information.
|
||||
*/
|
||||
package com.hurlant.crypto.prng
|
||||
{
|
||||
import flash.utils.ByteArray;
|
||||
import com.hurlant.util.Memory;
|
||||
import flash.system.System;
|
||||
import flash.system.Capabilities;
|
||||
import flash.accessibility.AccessibilityProperties;
|
||||
import flash.display.SWFVersion;
|
||||
import flash.display.Stage;
|
||||
import flash.utils.getTimer;
|
||||
import flash.text.Font;
|
||||
|
||||
public class Random
|
||||
{
|
||||
private var state:IPRNG;
|
||||
private var ready:Boolean = false;
|
||||
private var pool:ByteArray;
|
||||
private var psize:int;
|
||||
private var pptr:int;
|
||||
private var seeded:Boolean = false;
|
||||
|
||||
public function Random(prng:Class = null) {
|
||||
if (prng==null) prng = ARC4;
|
||||
state = new prng as IPRNG;
|
||||
psize= state.getPoolSize();
|
||||
pool = new ByteArray;
|
||||
pptr = 0;
|
||||
while (pptr <psize) {
|
||||
var t:uint = 65536*Math.random();
|
||||
pool[pptr++] = t >>> 8;
|
||||
pool[pptr++] = t&255;
|
||||
}
|
||||
pptr=0;
|
||||
seed();
|
||||
}
|
||||
|
||||
public function seed(x:int = 0):void {
|
||||
if (x==0) {
|
||||
x = new Date().getTime();
|
||||
}
|
||||
pool[pptr++] ^= x & 255;
|
||||
pool[pptr++] ^= (x>>8)&255;
|
||||
pool[pptr++] ^= (x>>16)&255;
|
||||
pool[pptr++] ^= (x>>24)&255;
|
||||
pptr %= psize;
|
||||
seeded = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gather anything we have that isn't entirely predictable:
|
||||
* - memory used
|
||||
* - system capabilities
|
||||
* - timing stuff
|
||||
* - installed fonts
|
||||
*/
|
||||
public function autoSeed():void {
|
||||
var b:ByteArray = new ByteArray;
|
||||
b.writeUnsignedInt(System.totalMemory);
|
||||
b.writeUTF(Capabilities.serverString);
|
||||
b.writeUnsignedInt(getTimer());
|
||||
b.writeUnsignedInt((new Date).getTime());
|
||||
var a:Array = Font.enumerateFonts(true);
|
||||
for each (var f:Font in a) {
|
||||
b.writeUTF(f.fontName);
|
||||
b.writeUTF(f.fontStyle);
|
||||
b.writeUTF(f.fontType);
|
||||
}
|
||||
b.position=0;
|
||||
while (b.bytesAvailable>=4) {
|
||||
seed(b.readUnsignedInt());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public function nextBytes(buffer:ByteArray, length:int):void {
|
||||
while (length--) {
|
||||
buffer.writeByte(nextByte());
|
||||
}
|
||||
}
|
||||
public function nextByte():int {
|
||||
if (!ready) {
|
||||
if (!seeded) {
|
||||
autoSeed();
|
||||
}
|
||||
state.init(pool);
|
||||
pool.length = 0;
|
||||
pptr = 0;
|
||||
ready = true;
|
||||
}
|
||||
return state.next();
|
||||
}
|
||||
public function dispose():void {
|
||||
for (var i:uint=0;i<pool.length;i++) {
|
||||
pool[i] = Math.random()*256;
|
||||
}
|
||||
pool.length=0;
|
||||
pool = null;
|
||||
state.dispose();
|
||||
state = null;
|
||||
psize = 0;
|
||||
pptr = 0;
|
||||
Memory.gc();
|
||||
}
|
||||
public function toString():String {
|
||||
return "random-"+state.toString();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,142 +0,0 @@
|
||||
/**
|
||||
* TLSPRF
|
||||
*
|
||||
* An ActionScript 3 implementation of a pseudo-random generator
|
||||
* that follows the TLS specification
|
||||
* Copyright (c) 2007 Henri Torgemane
|
||||
*
|
||||
* See LICENSE.txt for full license information.
|
||||
*/
|
||||
package com.hurlant.crypto.prng
|
||||
{
|
||||
import flash.utils.ByteArray;
|
||||
import com.hurlant.crypto.hash.HMAC;
|
||||
import com.hurlant.crypto.hash.MD5;
|
||||
import com.hurlant.crypto.hash.SHA1;
|
||||
import com.hurlant.util.Memory;
|
||||
import com.hurlant.util.Hex;
|
||||
import flash.utils.IDataOutput;
|
||||
|
||||
/**
|
||||
* There's "Random", and then there's TLS Random.
|
||||
* .
|
||||
* Still Pseudo-random, though.
|
||||
*/
|
||||
public class TLSPRF
|
||||
{
|
||||
// XXX WAY TOO MANY STRUCTURES HERE
|
||||
|
||||
// seed
|
||||
private var seed:ByteArray;
|
||||
// P_MD5's secret
|
||||
private var s1:ByteArray;
|
||||
// P_SHA-1's secret
|
||||
private var s2:ByteArray;
|
||||
// HMAC_MD5's A
|
||||
private var a1:ByteArray;
|
||||
// HMAC_SHA1's A
|
||||
private var a2:ByteArray;
|
||||
// Pool for P_MD5
|
||||
private var p1:ByteArray;
|
||||
// Pool for P_SHA1
|
||||
private var p2:ByteArray;
|
||||
// Data for HMAC_MD5
|
||||
private var d1:ByteArray;
|
||||
// Data for HMAC_SHA1
|
||||
private var d2:ByteArray;
|
||||
|
||||
|
||||
private var hmac_md5:HMAC;
|
||||
private var hmac_sha1:HMAC;
|
||||
|
||||
public function TLSPRF(secret:ByteArray, label:String, seed:ByteArray) {
|
||||
var l:int = Math.ceil(secret.length/2);
|
||||
var s1:ByteArray = new ByteArray;
|
||||
var s2:ByteArray = new ByteArray;
|
||||
s1.writeBytes(secret, 0, l);
|
||||
s2.writeBytes(secret, secret.length-l, l);
|
||||
var s:ByteArray = new ByteArray;
|
||||
s.writeUTFBytes(label);
|
||||
s.writeBytes(seed);
|
||||
this.seed = s;
|
||||
this.s1 = s1;
|
||||
this.s2 = s2;
|
||||
hmac_md5 = new HMAC(new MD5);
|
||||
hmac_sha1 = new HMAC(new SHA1);
|
||||
|
||||
this.a1 = hmac_md5.compute(s1, this.seed);
|
||||
this.a2 = hmac_sha1.compute(s2, this.seed);
|
||||
|
||||
p1 = new ByteArray;
|
||||
p2 = new ByteArray;
|
||||
|
||||
d1 = new ByteArray;
|
||||
d2 = new ByteArray;
|
||||
d1.position = MD5.HASH_SIZE;
|
||||
d1.writeBytes(this.seed);
|
||||
d2.position = SHA1.HASH_SIZE;
|
||||
d2.writeBytes(this.seed);
|
||||
}
|
||||
|
||||
// XXX HORRIBLY SLOW. REWRITE.
|
||||
public function nextBytes(buffer:IDataOutput, length:int):void {
|
||||
while (length--) {
|
||||
buffer.writeByte(nextByte());
|
||||
}
|
||||
}
|
||||
public function nextByte():int {
|
||||
if (p1.bytesAvailable==0) {
|
||||
more_md5();
|
||||
}
|
||||
if (p2.bytesAvailable==0) {
|
||||
more_sha1();
|
||||
}
|
||||
return p1.readUnsignedByte()^p2.readUnsignedByte();
|
||||
}
|
||||
public function dispose():void {
|
||||
seed = dba(seed);
|
||||
s1 = dba(s1);
|
||||
s2 = dba(s2);
|
||||
a1 = dba(a1);
|
||||
a2 = dba(a2);
|
||||
p1 = dba(p1);
|
||||
p2 = dba(p2);
|
||||
d1 = dba(d1);
|
||||
d2 = dba(d2);
|
||||
hmac_md5.dispose();
|
||||
hmac_md5 = null;
|
||||
hmac_sha1.dispose();
|
||||
hmac_sha1 = null;
|
||||
Memory.gc();
|
||||
}
|
||||
public function toString():String {
|
||||
return "tls-prf";
|
||||
}
|
||||
private function dba(ba:ByteArray):ByteArray {
|
||||
for (var i:uint=0;i<ba.length;i++) {
|
||||
ba[i]=0;
|
||||
}
|
||||
ba.length=0;
|
||||
return null;
|
||||
}
|
||||
private function more_md5():void {
|
||||
d1.position=0;
|
||||
d1.writeBytes(a1);
|
||||
var p:int = p1.position;
|
||||
var more:ByteArray = hmac_md5.compute(s1, d1);
|
||||
a1 = hmac_md5.compute(s1, a1);
|
||||
p1.writeBytes(more);
|
||||
p1.position=p;
|
||||
}
|
||||
private function more_sha1():void {
|
||||
d2.position=0;
|
||||
d2.writeBytes(a2);
|
||||
var p:int = p2.position;
|
||||
var more:ByteArray = hmac_sha1.compute(s2, d2);
|
||||
a2 = hmac_sha1.compute(s2, a2);
|
||||
p2.writeBytes(more);
|
||||
p2.position=p;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,339 +0,0 @@
|
||||
/**
|
||||
* RSAKey
|
||||
*
|
||||
* An ActionScript 3 implementation of RSA + PKCS#1 (light version)
|
||||
* Copyright (c) 2007 Henri Torgemane
|
||||
*
|
||||
* Derived from:
|
||||
* The jsbn library, Copyright (c) 2003-2005 Tom Wu
|
||||
*
|
||||
* See LICENSE.txt for full license information.
|
||||
*/
|
||||
package com.hurlant.crypto.rsa
|
||||
{
|
||||
import com.hurlant.crypto.prng.Random;
|
||||
import com.hurlant.math.BigInteger;
|
||||
import com.hurlant.util.Memory;
|
||||
|
||||
import flash.utils.ByteArray;
|
||||
import com.hurlant.crypto.hash.IHash;
|
||||
import com.hurlant.util.Hex;
|
||||
import com.hurlant.util.der.DER;
|
||||
import com.hurlant.util.der.OID;
|
||||
import com.hurlant.util.ArrayUtil;
|
||||
import com.hurlant.util.der.Type;
|
||||
import com.hurlant.util.der.Sequence;
|
||||
import com.hurlant.util.der.ObjectIdentifier;
|
||||
import com.hurlant.util.der.ByteString;
|
||||
import com.hurlant.crypto.tls.TLSError;
|
||||
|
||||
/**
|
||||
* Current limitations:
|
||||
* exponent must be smaller than 2^31.
|
||||
*/
|
||||
public class RSAKey
|
||||
{
|
||||
// public key
|
||||
public var e:int; // public exponent. must be <2^31
|
||||
public var n:BigInteger; // modulus
|
||||
// private key
|
||||
public var d:BigInteger;
|
||||
// extended private key
|
||||
public var p:BigInteger;
|
||||
public var q:BigInteger;
|
||||
public var dmp1:BigInteger
|
||||
public var dmq1:BigInteger;
|
||||
public var coeff:BigInteger;
|
||||
// flags. flags are cool.
|
||||
protected var canDecrypt:Boolean;
|
||||
protected var canEncrypt:Boolean;
|
||||
|
||||
public function RSAKey(N:BigInteger, E:int,
|
||||
D:BigInteger=null,
|
||||
P:BigInteger = null, Q:BigInteger=null,
|
||||
DP:BigInteger=null, DQ:BigInteger=null,
|
||||
C:BigInteger=null) {
|
||||
|
||||
this.n = N;
|
||||
this.e = E;
|
||||
this.d = D;
|
||||
this.p = P;
|
||||
this.q = Q;
|
||||
this.dmp1 = DP;
|
||||
this.dmq1 = DQ;
|
||||
this.coeff = C;
|
||||
|
||||
// adjust a few flags.
|
||||
canEncrypt = (n!=null&&e!=0);
|
||||
canDecrypt = (canEncrypt&&d!=null);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
public static function parsePublicKey(N:String, E:String):RSAKey {
|
||||
return new RSAKey(new BigInteger(N, 16, true), parseInt(E,16));
|
||||
}
|
||||
public static function parsePrivateKey(N:String, E:String, D:String,
|
||||
P:String=null,Q:String=null, DMP1:String=null, DMQ1:String=null, IQMP:String=null):RSAKey {
|
||||
if (P==null) {
|
||||
return new RSAKey(new BigInteger(N,16, true), parseInt(E,16), new BigInteger(D,16, true));
|
||||
} else {
|
||||
return new RSAKey(new BigInteger(N,16, true), parseInt(E,16), new BigInteger(D,16, true),
|
||||
new BigInteger(P,16, true), new BigInteger(Q,16, true),
|
||||
new BigInteger(DMP1,16, true), new BigInteger(DMQ1, 16, true),
|
||||
new BigInteger(IQMP, 16, true));
|
||||
}
|
||||
}
|
||||
|
||||
public function getBlockSize():uint {
|
||||
return (n.bitLength()+7)/8;
|
||||
}
|
||||
public function dispose():void {
|
||||
e = 0;
|
||||
n.dispose();
|
||||
n = null;
|
||||
Memory.gc();
|
||||
}
|
||||
|
||||
|
||||
public function encrypt(src:ByteArray, dst:ByteArray, length:uint, pad:Function=null):void {
|
||||
_encrypt(doPublic, src, dst, length, pad, 0x02);
|
||||
}
|
||||
public function decrypt(src:ByteArray, dst:ByteArray, length:uint, pad:Function=null):void {
|
||||
_decrypt(doPrivate2, src, dst, length, pad, 0x02);
|
||||
}
|
||||
|
||||
|
||||
public function sign(src:ByteArray, dst:ByteArray, length:uint, pad:Function = null):void {
|
||||
_encrypt(doPrivate2, src, dst, length, pad, 0x01);
|
||||
}
|
||||
public function verify(src:ByteArray, dst:ByteArray, length:uint, pad:Function = null):void {
|
||||
_decrypt(doPublic, src, dst, length, pad, 0x01);
|
||||
}
|
||||
|
||||
|
||||
|
||||
private function _encrypt(op:Function, src:ByteArray, dst:ByteArray, length:uint, pad:Function, padType:int):void {
|
||||
// adjust pad if needed
|
||||
if (pad==null) pad = pkcs1pad;
|
||||
// convert src to BigInteger
|
||||
if (src.position >= src.length) {
|
||||
src.position = 0;
|
||||
}
|
||||
var bl:uint = getBlockSize();
|
||||
var end:int = src.position + length;
|
||||
while (src.position<end) {
|
||||
var block:BigInteger = new BigInteger(pad(src, end, bl, padType), bl, true);
|
||||
var chunk:BigInteger = op(block);
|
||||
chunk.toArray(dst);
|
||||
}
|
||||
}
|
||||
private function _decrypt(op:Function, src:ByteArray, dst:ByteArray, length:uint, pad:Function, padType:int):void {
|
||||
// adjust pad if needed
|
||||
if (pad==null) pad = pkcs1unpad;
|
||||
|
||||
// convert src to BigInteger
|
||||
if (src.position >= src.length) {
|
||||
src.position = 0;
|
||||
}
|
||||
var bl:uint = getBlockSize();
|
||||
var end:int = src.position + length;
|
||||
while (src.position<end) {
|
||||
var block:BigInteger = new BigInteger(src, bl, true);
|
||||
var chunk:BigInteger = op(block);
|
||||
var b:ByteArray = pad(chunk, bl, padType);
|
||||
if (b == null)
|
||||
throw new TLSError( "Decrypt error - padding function returned null!", TLSError.decode_error );
|
||||
// if (b != null)
|
||||
dst.writeBytes(b);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* PKCS#1 pad. type 1 (0xff) or 2, random.
|
||||
* puts as much data from src into it, leaves what doesn't fit alone.
|
||||
*/
|
||||
private function pkcs1pad(src:ByteArray, end:int, n:uint, type:uint = 0x02):ByteArray {
|
||||
var out:ByteArray = new ByteArray;
|
||||
var p:uint = src.position;
|
||||
end = Math.min(end, src.length, p+n-11);
|
||||
src.position = end;
|
||||
var i:int = end-1;
|
||||
while (i>=p && n>11) {
|
||||
out[--n] = src[i--];
|
||||
}
|
||||
out[--n] = 0;
|
||||
if (type==0x02) { // type 2
|
||||
var rng:Random = new Random;
|
||||
var x:int = 0;
|
||||
while (n>2) {
|
||||
do {
|
||||
x = rng.nextByte();
|
||||
} while (x==0);
|
||||
out[--n] = x;
|
||||
}
|
||||
} else { // type 1
|
||||
while (n>2) {
|
||||
out[--n] = 0xFF;
|
||||
}
|
||||
}
|
||||
out[--n] = type;
|
||||
out[--n] = 0;
|
||||
return out;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param src
|
||||
* @param n
|
||||
* @param type Not used.
|
||||
* @return
|
||||
*
|
||||
*/
|
||||
private function pkcs1unpad(src:BigInteger, n:uint, type:uint = 0x02):ByteArray {
|
||||
var b:ByteArray = src.toByteArray();
|
||||
var out:ByteArray = new ByteArray;
|
||||
|
||||
b.position = 0;
|
||||
var i:int = 0;
|
||||
while (i<b.length && b[i]==0) ++i;
|
||||
if (b.length-i != n-1 || b[i]!=type) {
|
||||
trace("PKCS#1 unpad: i="+i+", expected b[i]=="+type+", got b[i]="+b[i].toString(16));
|
||||
return null;
|
||||
}
|
||||
++i;
|
||||
while (b[i]!=0) {
|
||||
if (++i>=b.length) {
|
||||
trace("PKCS#1 unpad: i="+i+", b[i-1]!=0 (="+b[i-1].toString(16)+")");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
while (++i < b.length) {
|
||||
out.writeByte(b[i]);
|
||||
}
|
||||
out.position = 0;
|
||||
return out;
|
||||
}
|
||||
/**
|
||||
* Raw pad.
|
||||
*/
|
||||
public function rawpad(src:ByteArray, end:int, n:uint, type:uint = 0):ByteArray {
|
||||
return src;
|
||||
}
|
||||
public function rawunpad(src:BigInteger, n:uint, type:uint = 0):ByteArray {
|
||||
return src.toByteArray();
|
||||
}
|
||||
|
||||
public function toString():String {
|
||||
return "rsa";
|
||||
}
|
||||
|
||||
public function dump():String {
|
||||
var s:String= "N="+n.toString(16)+"\n"+
|
||||
"E="+e.toString(16)+"\n";
|
||||
if (canDecrypt) {
|
||||
s+="D="+d.toString(16)+"\n";
|
||||
if (p!=null && q!=null) {
|
||||
s+="P="+p.toString(16)+"\n";
|
||||
s+="Q="+q.toString(16)+"\n";
|
||||
s+="DMP1="+dmp1.toString(16)+"\n";
|
||||
s+="DMQ1="+dmq1.toString(16)+"\n";
|
||||
s+="IQMP="+coeff.toString(16)+"\n";
|
||||
}
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* note: We should have a "nice" variant of this function that takes a callback,
|
||||
* and perform the computation is small fragments, to keep the web browser
|
||||
* usable.
|
||||
*
|
||||
* @param B
|
||||
* @param E
|
||||
* @return a new random private key B bits long, using public expt E
|
||||
*
|
||||
*/
|
||||
public static function generate(B:uint, E:String):RSAKey {
|
||||
var rng:Random = new Random;
|
||||
var qs:uint = B>>1;
|
||||
var key:RSAKey = new RSAKey(null,0,null);
|
||||
key.e = parseInt(E, 16);
|
||||
var ee:BigInteger = new BigInteger(E,16, true);
|
||||
for (;;) {
|
||||
for (;;) {
|
||||
key.p = bigRandom(B-qs, rng);
|
||||
if (key.p.subtract(BigInteger.ONE).gcd(ee).compareTo(BigInteger.ONE)==0 &&
|
||||
key.p.isProbablePrime(10)) break;
|
||||
}
|
||||
for (;;) {
|
||||
key.q = bigRandom(qs, rng);
|
||||
if (key.q.subtract(BigInteger.ONE).gcd(ee).compareTo(BigInteger.ONE)==0 &&
|
||||
key.q.isProbablePrime(10)) break;
|
||||
}
|
||||
if (key.p.compareTo(key.q)<=0) {
|
||||
var t:BigInteger = key.p;
|
||||
key.p = key.q;
|
||||
key.q = t;
|
||||
}
|
||||
var p1:BigInteger = key.p.subtract(BigInteger.ONE);
|
||||
var q1:BigInteger = key.q.subtract(BigInteger.ONE);
|
||||
var phi:BigInteger = p1.multiply(q1);
|
||||
if (phi.gcd(ee).compareTo(BigInteger.ONE)==0) {
|
||||
key.n = key.p.multiply(key.q);
|
||||
key.d = ee.modInverse(phi);
|
||||
key.dmp1 = key.d.mod(p1);
|
||||
key.dmq1 = key.d.mod(q1);
|
||||
key.coeff = key.q.modInverse(key.p);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return key;
|
||||
}
|
||||
|
||||
protected static function bigRandom(bits:int, rnd:Random):BigInteger {
|
||||
if (bits<2) return BigInteger.nbv(1);
|
||||
var x:ByteArray = new ByteArray;
|
||||
rnd.nextBytes(x, (bits>>3));
|
||||
x.position = 0;
|
||||
var b:BigInteger = new BigInteger(x,0,true);
|
||||
b.primify(bits, 1);
|
||||
return b;
|
||||
}
|
||||
|
||||
protected function doPublic(x:BigInteger):BigInteger {
|
||||
return x.modPowInt(e, n);
|
||||
}
|
||||
|
||||
protected function doPrivate2(x:BigInteger):BigInteger {
|
||||
if (p==null && q==null) {
|
||||
return x.modPow(d,n);
|
||||
}
|
||||
|
||||
var xp:BigInteger = x.mod(p).modPow(dmp1, p);
|
||||
var xq:BigInteger = x.mod(q).modPow(dmq1, q);
|
||||
|
||||
while (xp.compareTo(xq)<0) {
|
||||
xp = xp.add(p);
|
||||
}
|
||||
var r:BigInteger = xp.subtract(xq).multiply(coeff).mod(p).multiply(q).add(xq);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
protected function doPrivate(x:BigInteger):BigInteger {
|
||||
if (p==null || q==null) {
|
||||
return x.modPow(d, n);
|
||||
}
|
||||
// TODO: re-calculate any missing CRT params
|
||||
var xp:BigInteger = x.mod(p).modPow(dmp1, p);
|
||||
var xq:BigInteger = x.mod(q).modPow(dmq1, q);
|
||||
|
||||
while (xp.compareTo(xq)<0) {
|
||||
xp = xp.add(p);
|
||||
}
|
||||
return xp.subtract(xq).multiply(coeff).mod(p).multiply(q).add(xq);
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,375 +0,0 @@
|
||||
/**
|
||||
* BlowFishKey
|
||||
*
|
||||
* An Actionscript 3 implementation of the BlowFish encryption algorithm,
|
||||
* as documented at http://www.schneier.com/blowfish.html
|
||||
* Copyright (c) 2007 Henri Torgemane
|
||||
*
|
||||
* Derived from:
|
||||
* The Bouncy Castle Crypto package,
|
||||
* Copyright (c) 2000-2004 The Legion Of The Bouncy Castle
|
||||
* (http://www.bouncycastle.org)
|
||||
*
|
||||
* See LICENSE.txt for full license information.
|
||||
*/
|
||||
package com.hurlant.crypto.symmetric
|
||||
{
|
||||
import flash.utils.ByteArray;
|
||||
import com.hurlant.util.Memory;
|
||||
|
||||
public class BlowFishKey implements ISymmetricKey
|
||||
{
|
||||
|
||||
private static const KP:Array = [ 0x243F6A88, 0x85A308D3, 0x13198A2E, 0x03707344, 0xA4093822, 0x299F31D0,
|
||||
0x082EFA98, 0xEC4E6C89, 0x452821E6, 0x38D01377, 0xBE5466CF, 0x34E90C6C, 0xC0AC29B7, 0xC97C50DD, 0x3F84D5B5,
|
||||
0xB5470917, 0x9216D5D9, 0x8979FB1B ];
|
||||
|
||||
private static const KS0:Array = [ 0xD1310BA6, 0x98DFB5AC, 0x2FFD72DB, 0xD01ADFB7, 0xB8E1AFED, 0x6A267E96, 0xBA7C9045, 0xF12C7F99, 0x24A19947,
|
||||
0xB3916CF7, 0x0801F2E2, 0x858EFC16, 0x636920D8, 0x71574E69, 0xA458FEA3, 0xF4933D7E, 0x0D95748F, 0x728EB658,
|
||||
0x718BCD58, 0x82154AEE, 0x7B54A41D, 0xC25A59B5, 0x9C30D539, 0x2AF26013, 0xC5D1B023, 0x286085F0, 0xCA417918,
|
||||
0xB8DB38EF, 0x8E79DCB0, 0x603A180E, 0x6C9E0E8B, 0xB01E8A3E, 0xD71577C1, 0xBD314B27, 0x78AF2FDA, 0x55605C60,
|
||||
0xE65525F3, 0xAA55AB94, 0x57489862, 0x63E81440, 0x55CA396A, 0x2AAB10B6, 0xB4CC5C34, 0x1141E8CE, 0xA15486AF,
|
||||
0x7C72E993, 0xB3EE1411, 0x636FBC2A, 0x2BA9C55D, 0x741831F6, 0xCE5C3E16, 0x9B87931E, 0xAFD6BA33, 0x6C24CF5C,
|
||||
0x7A325381, 0x28958677, 0x3B8F4898, 0x6B4BB9AF, 0xC4BFE81B, 0x66282193, 0x61D809CC, 0xFB21A991, 0x487CAC60,
|
||||
0x5DEC8032, 0xEF845D5D, 0xE98575B1, 0xDC262302, 0xEB651B88, 0x23893E81, 0xD396ACC5, 0x0F6D6FF3, 0x83F44239,
|
||||
0x2E0B4482, 0xA4842004, 0x69C8F04A, 0x9E1F9B5E, 0x21C66842, 0xF6E96C9A, 0x670C9C61, 0xABD388F0, 0x6A51A0D2,
|
||||
0xD8542F68, 0x960FA728, 0xAB5133A3, 0x6EEF0B6C, 0x137A3BE4, 0xBA3BF050, 0x7EFB2A98, 0xA1F1651D, 0x39AF0176,
|
||||
0x66CA593E, 0x82430E88, 0x8CEE8619, 0x456F9FB4, 0x7D84A5C3, 0x3B8B5EBE, 0xE06F75D8, 0x85C12073, 0x401A449F,
|
||||
0x56C16AA6, 0x4ED3AA62, 0x363F7706, 0x1BFEDF72, 0x429B023D, 0x37D0D724, 0xD00A1248, 0xDB0FEAD3, 0x49F1C09B,
|
||||
0x075372C9, 0x80991B7B, 0x25D479D8, 0xF6E8DEF7, 0xE3FE501A, 0xB6794C3B, 0x976CE0BD, 0x04C006BA, 0xC1A94FB6,
|
||||
0x409F60C4, 0x5E5C9EC2, 0x196A2463, 0x68FB6FAF, 0x3E6C53B5, 0x1339B2EB, 0x3B52EC6F, 0x6DFC511F, 0x9B30952C,
|
||||
0xCC814544, 0xAF5EBD09, 0xBEE3D004, 0xDE334AFD, 0x660F2807, 0x192E4BB3, 0xC0CBA857, 0x45C8740F, 0xD20B5F39,
|
||||
0xB9D3FBDB, 0x5579C0BD, 0x1A60320A, 0xD6A100C6, 0x402C7279, 0x679F25FE, 0xFB1FA3CC, 0x8EA5E9F8, 0xDB3222F8,
|
||||
0x3C7516DF, 0xFD616B15, 0x2F501EC8, 0xAD0552AB, 0x323DB5FA, 0xFD238760, 0x53317B48, 0x3E00DF82, 0x9E5C57BB,
|
||||
0xCA6F8CA0, 0x1A87562E, 0xDF1769DB, 0xD542A8F6, 0x287EFFC3, 0xAC6732C6, 0x8C4F5573, 0x695B27B0, 0xBBCA58C8,
|
||||
0xE1FFA35D, 0xB8F011A0, 0x10FA3D98, 0xFD2183B8, 0x4AFCB56C, 0x2DD1D35B, 0x9A53E479, 0xB6F84565, 0xD28E49BC,
|
||||
0x4BFB9790, 0xE1DDF2DA, 0xA4CB7E33, 0x62FB1341, 0xCEE4C6E8, 0xEF20CADA, 0x36774C01, 0xD07E9EFE, 0x2BF11FB4,
|
||||
0x95DBDA4D, 0xAE909198, 0xEAAD8E71, 0x6B93D5A0, 0xD08ED1D0, 0xAFC725E0, 0x8E3C5B2F, 0x8E7594B7, 0x8FF6E2FB,
|
||||
0xF2122B64, 0x8888B812, 0x900DF01C, 0x4FAD5EA0, 0x688FC31C, 0xD1CFF191, 0xB3A8C1AD, 0x2F2F2218, 0xBE0E1777,
|
||||
0xEA752DFE, 0x8B021FA1, 0xE5A0CC0F, 0xB56F74E8, 0x18ACF3D6, 0xCE89E299, 0xB4A84FE0, 0xFD13E0B7, 0x7CC43B81,
|
||||
0xD2ADA8D9, 0x165FA266, 0x80957705, 0x93CC7314, 0x211A1477, 0xE6AD2065, 0x77B5FA86, 0xC75442F5, 0xFB9D35CF,
|
||||
0xEBCDAF0C, 0x7B3E89A0, 0xD6411BD3, 0xAE1E7E49, 0x00250E2D, 0x2071B35E, 0x226800BB, 0x57B8E0AF, 0x2464369B,
|
||||
0xF009B91E, 0x5563911D, 0x59DFA6AA, 0x78C14389, 0xD95A537F, 0x207D5BA2, 0x02E5B9C5, 0x83260376, 0x6295CFA9,
|
||||
0x11C81968, 0x4E734A41, 0xB3472DCA, 0x7B14A94A, 0x1B510052, 0x9A532915, 0xD60F573F, 0xBC9BC6E4, 0x2B60A476,
|
||||
0x81E67400, 0x08BA6FB5, 0x571BE91F, 0xF296EC6B, 0x2A0DD915, 0xB6636521, 0xE7B9F9B6, 0xFF34052E, 0xC5855664,
|
||||
0x53B02D5D, 0xA99F8FA1, 0x08BA4799, 0x6E85076A ];
|
||||
|
||||
private static const KS1:Array = [ 0x4B7A70E9, 0xB5B32944, 0xDB75092E, 0xC4192623, 0xAD6EA6B0, 0x49A7DF7D, 0x9CEE60B8, 0x8FEDB266, 0xECAA8C71,
|
||||
0x699A17FF, 0x5664526C, 0xC2B19EE1, 0x193602A5, 0x75094C29, 0xA0591340, 0xE4183A3E, 0x3F54989A, 0x5B429D65,
|
||||
0x6B8FE4D6, 0x99F73FD6, 0xA1D29C07, 0xEFE830F5, 0x4D2D38E6, 0xF0255DC1, 0x4CDD2086, 0x8470EB26, 0x6382E9C6,
|
||||
0x021ECC5E, 0x09686B3F, 0x3EBAEFC9, 0x3C971814, 0x6B6A70A1, 0x687F3584, 0x52A0E286, 0xB79C5305, 0xAA500737,
|
||||
0x3E07841C, 0x7FDEAE5C, 0x8E7D44EC, 0x5716F2B8, 0xB03ADA37, 0xF0500C0D, 0xF01C1F04, 0x0200B3FF, 0xAE0CF51A,
|
||||
0x3CB574B2, 0x25837A58, 0xDC0921BD, 0xD19113F9, 0x7CA92FF6, 0x94324773, 0x22F54701, 0x3AE5E581, 0x37C2DADC,
|
||||
0xC8B57634, 0x9AF3DDA7, 0xA9446146, 0x0FD0030E, 0xECC8C73E, 0xA4751E41, 0xE238CD99, 0x3BEA0E2F, 0x3280BBA1,
|
||||
0x183EB331, 0x4E548B38, 0x4F6DB908, 0x6F420D03, 0xF60A04BF, 0x2CB81290, 0x24977C79, 0x5679B072, 0xBCAF89AF,
|
||||
0xDE9A771F, 0xD9930810, 0xB38BAE12, 0xDCCF3F2E, 0x5512721F, 0x2E6B7124, 0x501ADDE6, 0x9F84CD87, 0x7A584718,
|
||||
0x7408DA17, 0xBC9F9ABC, 0xE94B7D8C, 0xEC7AEC3A, 0xDB851DFA, 0x63094366, 0xC464C3D2, 0xEF1C1847, 0x3215D908,
|
||||
0xDD433B37, 0x24C2BA16, 0x12A14D43, 0x2A65C451, 0x50940002, 0x133AE4DD, 0x71DFF89E, 0x10314E55, 0x81AC77D6,
|
||||
0x5F11199B, 0x043556F1, 0xD7A3C76B, 0x3C11183B, 0x5924A509, 0xF28FE6ED, 0x97F1FBFA, 0x9EBABF2C, 0x1E153C6E,
|
||||
0x86E34570, 0xEAE96FB1, 0x860E5E0A, 0x5A3E2AB3, 0x771FE71C, 0x4E3D06FA, 0x2965DCB9, 0x99E71D0F, 0x803E89D6,
|
||||
0x5266C825, 0x2E4CC978, 0x9C10B36A, 0xC6150EBA, 0x94E2EA78, 0xA5FC3C53, 0x1E0A2DF4, 0xF2F74EA7, 0x361D2B3D,
|
||||
0x1939260F, 0x19C27960, 0x5223A708, 0xF71312B6, 0xEBADFE6E, 0xEAC31F66, 0xE3BC4595, 0xA67BC883, 0xB17F37D1,
|
||||
0x018CFF28, 0xC332DDEF, 0xBE6C5AA5, 0x65582185, 0x68AB9802, 0xEECEA50F, 0xDB2F953B, 0x2AEF7DAD, 0x5B6E2F84,
|
||||
0x1521B628, 0x29076170, 0xECDD4775, 0x619F1510, 0x13CCA830, 0xEB61BD96, 0x0334FE1E, 0xAA0363CF, 0xB5735C90,
|
||||
0x4C70A239, 0xD59E9E0B, 0xCBAADE14, 0xEECC86BC, 0x60622CA7, 0x9CAB5CAB, 0xB2F3846E, 0x648B1EAF, 0x19BDF0CA,
|
||||
0xA02369B9, 0x655ABB50, 0x40685A32, 0x3C2AB4B3, 0x319EE9D5, 0xC021B8F7, 0x9B540B19, 0x875FA099, 0x95F7997E,
|
||||
0x623D7DA8, 0xF837889A, 0x97E32D77, 0x11ED935F, 0x16681281, 0x0E358829, 0xC7E61FD6, 0x96DEDFA1, 0x7858BA99,
|
||||
0x57F584A5, 0x1B227263, 0x9B83C3FF, 0x1AC24696, 0xCDB30AEB, 0x532E3054, 0x8FD948E4, 0x6DBC3128, 0x58EBF2EF,
|
||||
0x34C6FFEA, 0xFE28ED61, 0xEE7C3C73, 0x5D4A14D9, 0xE864B7E3, 0x42105D14, 0x203E13E0, 0x45EEE2B6, 0xA3AAABEA,
|
||||
0xDB6C4F15, 0xFACB4FD0, 0xC742F442, 0xEF6ABBB5, 0x654F3B1D, 0x41CD2105, 0xD81E799E, 0x86854DC7, 0xE44B476A,
|
||||
0x3D816250, 0xCF62A1F2, 0x5B8D2646, 0xFC8883A0, 0xC1C7B6A3, 0x7F1524C3, 0x69CB7492, 0x47848A0B, 0x5692B285,
|
||||
0x095BBF00, 0xAD19489D, 0x1462B174, 0x23820E00, 0x58428D2A, 0x0C55F5EA, 0x1DADF43E, 0x233F7061, 0x3372F092,
|
||||
0x8D937E41, 0xD65FECF1, 0x6C223BDB, 0x7CDE3759, 0xCBEE7460, 0x4085F2A7, 0xCE77326E, 0xA6078084, 0x19F8509E,
|
||||
0xE8EFD855, 0x61D99735, 0xA969A7AA, 0xC50C06C2, 0x5A04ABFC, 0x800BCADC, 0x9E447A2E, 0xC3453484, 0xFDD56705,
|
||||
0x0E1E9EC9, 0xDB73DBD3, 0x105588CD, 0x675FDA79, 0xE3674340, 0xC5C43465, 0x713E38D8, 0x3D28F89E, 0xF16DFF20,
|
||||
0x153E21E7, 0x8FB03D4A, 0xE6E39F2B, 0xDB83ADF7 ];
|
||||
|
||||
private static const KS2:Array = [ 0xE93D5A68, 0x948140F7, 0xF64C261C, 0x94692934, 0x411520F7, 0x7602D4F7, 0xBCF46B2E, 0xD4A20068, 0xD4082471,
|
||||
0x3320F46A, 0x43B7D4B7, 0x500061AF, 0x1E39F62E, 0x97244546, 0x14214F74, 0xBF8B8840, 0x4D95FC1D, 0x96B591AF,
|
||||
0x70F4DDD3, 0x66A02F45, 0xBFBC09EC, 0x03BD9785, 0x7FAC6DD0, 0x31CB8504, 0x96EB27B3, 0x55FD3941, 0xDA2547E6,
|
||||
0xABCA0A9A, 0x28507825, 0x530429F4, 0x0A2C86DA, 0xE9B66DFB, 0x68DC1462, 0xD7486900, 0x680EC0A4, 0x27A18DEE,
|
||||
0x4F3FFEA2, 0xE887AD8C, 0xB58CE006, 0x7AF4D6B6, 0xAACE1E7C, 0xD3375FEC, 0xCE78A399, 0x406B2A42, 0x20FE9E35,
|
||||
0xD9F385B9, 0xEE39D7AB, 0x3B124E8B, 0x1DC9FAF7, 0x4B6D1856, 0x26A36631, 0xEAE397B2, 0x3A6EFA74, 0xDD5B4332,
|
||||
0x6841E7F7, 0xCA7820FB, 0xFB0AF54E, 0xD8FEB397, 0x454056AC, 0xBA489527, 0x55533A3A, 0x20838D87, 0xFE6BA9B7,
|
||||
0xD096954B, 0x55A867BC, 0xA1159A58, 0xCCA92963, 0x99E1DB33, 0xA62A4A56, 0x3F3125F9, 0x5EF47E1C, 0x9029317C,
|
||||
0xFDF8E802, 0x04272F70, 0x80BB155C, 0x05282CE3, 0x95C11548, 0xE4C66D22, 0x48C1133F, 0xC70F86DC, 0x07F9C9EE,
|
||||
0x41041F0F, 0x404779A4, 0x5D886E17, 0x325F51EB, 0xD59BC0D1, 0xF2BCC18F, 0x41113564, 0x257B7834, 0x602A9C60,
|
||||
0xDFF8E8A3, 0x1F636C1B, 0x0E12B4C2, 0x02E1329E, 0xAF664FD1, 0xCAD18115, 0x6B2395E0, 0x333E92E1, 0x3B240B62,
|
||||
0xEEBEB922, 0x85B2A20E, 0xE6BA0D99, 0xDE720C8C, 0x2DA2F728, 0xD0127845, 0x95B794FD, 0x647D0862, 0xE7CCF5F0,
|
||||
0x5449A36F, 0x877D48FA, 0xC39DFD27, 0xF33E8D1E, 0x0A476341, 0x992EFF74, 0x3A6F6EAB, 0xF4F8FD37, 0xA812DC60,
|
||||
0xA1EBDDF8, 0x991BE14C, 0xDB6E6B0D, 0xC67B5510, 0x6D672C37, 0x2765D43B, 0xDCD0E804, 0xF1290DC7, 0xCC00FFA3,
|
||||
0xB5390F92, 0x690FED0B, 0x667B9FFB, 0xCEDB7D9C, 0xA091CF0B, 0xD9155EA3, 0xBB132F88, 0x515BAD24, 0x7B9479BF,
|
||||
0x763BD6EB, 0x37392EB3, 0xCC115979, 0x8026E297, 0xF42E312D, 0x6842ADA7, 0xC66A2B3B, 0x12754CCC, 0x782EF11C,
|
||||
0x6A124237, 0xB79251E7, 0x06A1BBE6, 0x4BFB6350, 0x1A6B1018, 0x11CAEDFA, 0x3D25BDD8, 0xE2E1C3C9, 0x44421659,
|
||||
0x0A121386, 0xD90CEC6E, 0xD5ABEA2A, 0x64AF674E, 0xDA86A85F, 0xBEBFE988, 0x64E4C3FE, 0x9DBC8057, 0xF0F7C086,
|
||||
0x60787BF8, 0x6003604D, 0xD1FD8346, 0xF6381FB0, 0x7745AE04, 0xD736FCCC, 0x83426B33, 0xF01EAB71, 0xB0804187,
|
||||
0x3C005E5F, 0x77A057BE, 0xBDE8AE24, 0x55464299, 0xBF582E61, 0x4E58F48F, 0xF2DDFDA2, 0xF474EF38, 0x8789BDC2,
|
||||
0x5366F9C3, 0xC8B38E74, 0xB475F255, 0x46FCD9B9, 0x7AEB2661, 0x8B1DDF84, 0x846A0E79, 0x915F95E2, 0x466E598E,
|
||||
0x20B45770, 0x8CD55591, 0xC902DE4C, 0xB90BACE1, 0xBB8205D0, 0x11A86248, 0x7574A99E, 0xB77F19B6, 0xE0A9DC09,
|
||||
0x662D09A1, 0xC4324633, 0xE85A1F02, 0x09F0BE8C, 0x4A99A025, 0x1D6EFE10, 0x1AB93D1D, 0x0BA5A4DF, 0xA186F20F,
|
||||
0x2868F169, 0xDCB7DA83, 0x573906FE, 0xA1E2CE9B, 0x4FCD7F52, 0x50115E01, 0xA70683FA, 0xA002B5C4, 0x0DE6D027,
|
||||
0x9AF88C27, 0x773F8641, 0xC3604C06, 0x61A806B5, 0xF0177A28, 0xC0F586E0, 0x006058AA, 0x30DC7D62, 0x11E69ED7,
|
||||
0x2338EA63, 0x53C2DD94, 0xC2C21634, 0xBBCBEE56, 0x90BCB6DE, 0xEBFC7DA1, 0xCE591D76, 0x6F05E409, 0x4B7C0188,
|
||||
0x39720A3D, 0x7C927C24, 0x86E3725F, 0x724D9DB9, 0x1AC15BB4, 0xD39EB8FC, 0xED545578, 0x08FCA5B5, 0xD83D7CD3,
|
||||
0x4DAD0FC4, 0x1E50EF5E, 0xB161E6F8, 0xA28514D9, 0x6C51133C, 0x6FD5C7E7, 0x56E14EC4, 0x362ABFCE, 0xDDC6C837,
|
||||
0xD79A3234, 0x92638212, 0x670EFA8E, 0x406000E0 ];
|
||||
|
||||
private static const KS3:Array = [ 0x3A39CE37, 0xD3FAF5CF, 0xABC27737, 0x5AC52D1B, 0x5CB0679E, 0x4FA33742, 0xD3822740, 0x99BC9BBE, 0xD5118E9D,
|
||||
0xBF0F7315, 0xD62D1C7E, 0xC700C47B, 0xB78C1B6B, 0x21A19045, 0xB26EB1BE, 0x6A366EB4, 0x5748AB2F, 0xBC946E79,
|
||||
0xC6A376D2, 0x6549C2C8, 0x530FF8EE, 0x468DDE7D, 0xD5730A1D, 0x4CD04DC6, 0x2939BBDB, 0xA9BA4650, 0xAC9526E8,
|
||||
0xBE5EE304, 0xA1FAD5F0, 0x6A2D519A, 0x63EF8CE2, 0x9A86EE22, 0xC089C2B8, 0x43242EF6, 0xA51E03AA, 0x9CF2D0A4,
|
||||
0x83C061BA, 0x9BE96A4D, 0x8FE51550, 0xBA645BD6, 0x2826A2F9, 0xA73A3AE1, 0x4BA99586, 0xEF5562E9, 0xC72FEFD3,
|
||||
0xF752F7DA, 0x3F046F69, 0x77FA0A59, 0x80E4A915, 0x87B08601, 0x9B09E6AD, 0x3B3EE593, 0xE990FD5A, 0x9E34D797,
|
||||
0x2CF0B7D9, 0x022B8B51, 0x96D5AC3A, 0x017DA67D, 0xD1CF3ED6, 0x7C7D2D28, 0x1F9F25CF, 0xADF2B89B, 0x5AD6B472,
|
||||
0x5A88F54C, 0xE029AC71, 0xE019A5E6, 0x47B0ACFD, 0xED93FA9B, 0xE8D3C48D, 0x283B57CC, 0xF8D56629, 0x79132E28,
|
||||
0x785F0191, 0xED756055, 0xF7960E44, 0xE3D35E8C, 0x15056DD4, 0x88F46DBA, 0x03A16125, 0x0564F0BD, 0xC3EB9E15,
|
||||
0x3C9057A2, 0x97271AEC, 0xA93A072A, 0x1B3F6D9B, 0x1E6321F5, 0xF59C66FB, 0x26DCF319, 0x7533D928, 0xB155FDF5,
|
||||
0x03563482, 0x8ABA3CBB, 0x28517711, 0xC20AD9F8, 0xABCC5167, 0xCCAD925F, 0x4DE81751, 0x3830DC8E, 0x379D5862,
|
||||
0x9320F991, 0xEA7A90C2, 0xFB3E7BCE, 0x5121CE64, 0x774FBE32, 0xA8B6E37E, 0xC3293D46, 0x48DE5369, 0x6413E680,
|
||||
0xA2AE0810, 0xDD6DB224, 0x69852DFD, 0x09072166, 0xB39A460A, 0x6445C0DD, 0x586CDECF, 0x1C20C8AE, 0x5BBEF7DD,
|
||||
0x1B588D40, 0xCCD2017F, 0x6BB4E3BB, 0xDDA26A7E, 0x3A59FF45, 0x3E350A44, 0xBCB4CDD5, 0x72EACEA8, 0xFA6484BB,
|
||||
0x8D6612AE, 0xBF3C6F47, 0xD29BE463, 0x542F5D9E, 0xAEC2771B, 0xF64E6370, 0x740E0D8D, 0xE75B1357, 0xF8721671,
|
||||
0xAF537D5D, 0x4040CB08, 0x4EB4E2CC, 0x34D2466A, 0x0115AF84, 0xE1B00428, 0x95983A1D, 0x06B89FB4, 0xCE6EA048,
|
||||
0x6F3F3B82, 0x3520AB82, 0x011A1D4B, 0x277227F8, 0x611560B1, 0xE7933FDC, 0xBB3A792B, 0x344525BD, 0xA08839E1,
|
||||
0x51CE794B, 0x2F32C9B7, 0xA01FBAC9, 0xE01CC87E, 0xBCC7D1F6, 0xCF0111C3, 0xA1E8AAC7, 0x1A908749, 0xD44FBD9A,
|
||||
0xD0DADECB, 0xD50ADA38, 0x0339C32A, 0xC6913667, 0x8DF9317C, 0xE0B12B4F, 0xF79E59B7, 0x43F5BB3A, 0xF2D519FF,
|
||||
0x27D9459C, 0xBF97222C, 0x15E6FC2A, 0x0F91FC71, 0x9B941525, 0xFAE59361, 0xCEB69CEB, 0xC2A86459, 0x12BAA8D1,
|
||||
0xB6C1075E, 0xE3056A0C, 0x10D25065, 0xCB03A442, 0xE0EC6E0E, 0x1698DB3B, 0x4C98A0BE, 0x3278E964, 0x9F1F9532,
|
||||
0xE0D392DF, 0xD3A0342B, 0x8971F21E, 0x1B0A7441, 0x4BA3348C, 0xC5BE7120, 0xC37632D8, 0xDF359F8D, 0x9B992F2E,
|
||||
0xE60B6F47, 0x0FE3F11D, 0xE54CDA54, 0x1EDAD891, 0xCE6279CF, 0xCD3E7E6F, 0x1618B166, 0xFD2C1D05, 0x848FD2C5,
|
||||
0xF6FB2299, 0xF523F357, 0xA6327623, 0x93A83531, 0x56CCCD02, 0xACF08162, 0x5A75EBB5, 0x6E163697, 0x88D273CC,
|
||||
0xDE966292, 0x81B949D0, 0x4C50901B, 0x71C65614, 0xE6C6C7BD, 0x327A140A, 0x45E1D006, 0xC3F27B9A, 0xC9AA53FD,
|
||||
0x62A80F00, 0xBB25BFE2, 0x35BDD2F6, 0x71126905, 0xB2040222, 0xB6CBCF7C, 0xCD769C2B, 0x53113EC0, 0x1640E3D3,
|
||||
0x38ABBD60, 0x2547ADF0, 0xBA38209C, 0xF746CE76, 0x77AFA1C5, 0x20756060, 0x85CBFE4E, 0x8AE88DD8, 0x7AAAF9B0,
|
||||
0x4CF9AA7E, 0x1948C25C, 0x02FB8A8C, 0x01C36AE4, 0xD6EBE1F9, 0x90D4F869, 0xA65CDEA0, 0x3F09252D, 0xC208E69F,
|
||||
0xB74E6132, 0xCE77E25B, 0x578FDFE3, 0x3AC372E6 ];
|
||||
|
||||
// ====================================
|
||||
// Useful constants
|
||||
// ====================================
|
||||
|
||||
private static const ROUNDS:uint = 16;
|
||||
private static const BLOCK_SIZE:uint = 8; // bytes = 64 bits
|
||||
private static const SBOX_SK:uint = 256;
|
||||
private static const P_SZ:uint = ROUNDS + 2;
|
||||
|
||||
private var S0:Array;
|
||||
private var S1:Array;
|
||||
private var S2:Array;
|
||||
private var S3:Array; // the s-boxes
|
||||
private var P:Array; // the p-array
|
||||
|
||||
private var key:ByteArray = null;
|
||||
|
||||
public function BlowFishKey(key:ByteArray) {
|
||||
this.key = key;
|
||||
setKey(key);
|
||||
}
|
||||
|
||||
public function getBlockSize():uint
|
||||
{
|
||||
return BLOCK_SIZE;
|
||||
}
|
||||
|
||||
public function decrypt(block:ByteArray, index:uint=0):void
|
||||
{
|
||||
decryptBlock(block, index, block, index);
|
||||
}
|
||||
|
||||
public function dispose():void
|
||||
{
|
||||
var i:uint=0;
|
||||
for (i=0;i<S0.length;i++) { S0[i]=0; }
|
||||
for (i=0;i<S1.length;i++) { S1[i]=0; }
|
||||
for (i=0;i<S2.length;i++) { S2[i]=0; }
|
||||
for (i=0;i<S3.length;i++) { S3[i]=0; }
|
||||
for (i=0;i<P.length;i++) { P[i]=0; }
|
||||
S0 = null;
|
||||
S1 = null;
|
||||
S2 = null;
|
||||
S3 = null;
|
||||
P = null;
|
||||
for (i=0;i<key.length;i++) {
|
||||
key[i]=0;
|
||||
}
|
||||
key.length = 0;
|
||||
key = null;
|
||||
Memory.gc();
|
||||
}
|
||||
|
||||
public function encrypt(block:ByteArray, index:uint=0):void
|
||||
{
|
||||
encryptBlock(block, index, block, index);
|
||||
}
|
||||
|
||||
// ==================================
|
||||
// Private Implementation
|
||||
// ==================================
|
||||
|
||||
private function F(x:uint):uint
|
||||
{
|
||||
return (((S0[(x >>> 24)] + S1[(x >>> 16) & 0xff]) ^ S2[(x >>> 8) & 0xff]) + S3[x & 0xff]);
|
||||
}
|
||||
|
||||
/**
|
||||
* apply the encryption cycle to each value pair in the table.
|
||||
*/
|
||||
private function processTable(xl:uint, xr:uint, table:Array):void
|
||||
{
|
||||
var size:uint = table.length;
|
||||
|
||||
for (var s:uint = 0; s < size; s += 2)
|
||||
{
|
||||
xl ^= P[0];
|
||||
|
||||
for (var i:uint = 1; i < ROUNDS; i += 2)
|
||||
{
|
||||
xr ^= F(xl) ^ P[i];
|
||||
xl ^= F(xr) ^ P[i + 1];
|
||||
}
|
||||
|
||||
xr ^= P[ROUNDS + 1];
|
||||
|
||||
table[s] = xr;
|
||||
table[s + 1] = xl;
|
||||
|
||||
xr = xl; // end of cycle swap
|
||||
xl = table[s];
|
||||
}
|
||||
}
|
||||
|
||||
private function setKey(key:ByteArray):void
|
||||
{
|
||||
/*
|
||||
* - comments are from _Applied Crypto_, Schneier, p338 please be
|
||||
* careful comparing the two, AC numbers the arrays from 1, the enclosed
|
||||
* code from 0.
|
||||
*
|
||||
* (1) Initialise the S-boxes and the P-array, with a fixed string This
|
||||
* string contains the hexadecimal digits of pi (3.141...)
|
||||
*/
|
||||
S0 = KS0.concat();
|
||||
S1 = KS1.concat();
|
||||
S2 = KS2.concat();
|
||||
S3 = KS3.concat();
|
||||
P = KP.concat();
|
||||
|
||||
/*
|
||||
* (2) Now, XOR P[0] with the first 32 bits of the key, XOR P[1] with
|
||||
* the second 32-bits of the key, and so on for all bits of the key (up
|
||||
* to P[17]). Repeatedly cycle through the key bits until the entire
|
||||
* P-array has been XOR-ed with the key bits
|
||||
*/
|
||||
var keyLength:uint= key.length;
|
||||
var keyIndex:uint = 0;
|
||||
|
||||
for (var i:uint = 0; i < P_SZ; i++)
|
||||
{
|
||||
// get the 32 bits of the key, in 4 * 8 bit chunks
|
||||
var data:uint = 0x0000000;
|
||||
for (var j:uint = 0; j < 4; j++)
|
||||
{
|
||||
// create a 32 bit block
|
||||
data = (data << 8) | (key[keyIndex++] & 0xff);
|
||||
|
||||
// wrap when we get to the end of the key
|
||||
if (keyIndex >= keyLength)
|
||||
{
|
||||
keyIndex = 0;
|
||||
}
|
||||
}
|
||||
// XOR the newly created 32 bit chunk onto the P-array
|
||||
P[i] ^= data;
|
||||
}
|
||||
|
||||
/*
|
||||
* (3) Encrypt the all-zero string with the Blowfish algorithm, using
|
||||
* the subkeys described in (1) and (2)
|
||||
*
|
||||
* (4) Replace P1 and P2 with the output of step (3)
|
||||
*
|
||||
* (5) Encrypt the output of step(3) using the Blowfish algorithm, with
|
||||
* the modified subkeys.
|
||||
*
|
||||
* (6) Replace P3 and P4 with the output of step (5)
|
||||
*
|
||||
* (7) Continue the process, replacing all elements of the P-array and
|
||||
* then all four S-boxes in order, with the output of the continuously
|
||||
* changing Blowfish algorithm
|
||||
*/
|
||||
|
||||
processTable(0, 0, P);
|
||||
processTable(P[P_SZ - 2], P[P_SZ - 1], S0);
|
||||
processTable(S0[SBOX_SK - 2], S0[SBOX_SK - 1], S1);
|
||||
processTable(S1[SBOX_SK - 2], S1[SBOX_SK - 1], S2);
|
||||
processTable(S2[SBOX_SK - 2], S2[SBOX_SK - 1], S3);
|
||||
}
|
||||
|
||||
/**
|
||||
* Encrypt the given input starting at the given offset and place the result
|
||||
* in the provided buffer starting at the given offset. The input will be an
|
||||
* exact multiple of our blocksize.
|
||||
*/
|
||||
private function encryptBlock(src:ByteArray, srcIndex:uint, dst:ByteArray, dstIndex:uint):void
|
||||
{
|
||||
var xl:uint = BytesTo32bits(src, srcIndex);
|
||||
var xr:uint = BytesTo32bits(src, srcIndex + 4);
|
||||
|
||||
xl ^= P[0];
|
||||
|
||||
for (var i:uint = 1; i < ROUNDS; i += 2)
|
||||
{
|
||||
xr ^= F(xl) ^ P[i];
|
||||
xl ^= F(xr) ^ P[i + 1];
|
||||
}
|
||||
|
||||
xr ^= P[ROUNDS + 1];
|
||||
|
||||
Bits32ToBytes(xr, dst, dstIndex);
|
||||
Bits32ToBytes(xl, dst, dstIndex + 4);
|
||||
}
|
||||
|
||||
/**
|
||||
* Decrypt the given input starting at the given offset and place the result
|
||||
* in the provided buffer starting at the given offset. The input will be an
|
||||
* exact multiple of our blocksize.
|
||||
*/
|
||||
private function decryptBlock(src:ByteArray, srcIndex:uint, dst:ByteArray, dstIndex:uint):void
|
||||
{
|
||||
var xl:uint = BytesTo32bits(src, srcIndex);
|
||||
var xr:uint = BytesTo32bits(src, srcIndex + 4);
|
||||
|
||||
xl ^= P[ROUNDS + 1];
|
||||
|
||||
for (var i:uint = ROUNDS; i > 0; i -= 2)
|
||||
{
|
||||
xr ^= F(xl) ^ P[i];
|
||||
xl ^= F(xr) ^ P[i - 1];
|
||||
}
|
||||
|
||||
xr ^= P[0];
|
||||
|
||||
Bits32ToBytes(xr, dst, dstIndex);
|
||||
Bits32ToBytes(xl, dst, dstIndex + 4);
|
||||
}
|
||||
|
||||
private function BytesTo32bits(b:ByteArray, i:uint):uint
|
||||
{
|
||||
return ((b[i] & 0xff) << 24) | ((b[i + 1] & 0xff) << 16) | ((b[i + 2] & 0xff) << 8) | ((b[i + 3] & 0xff));
|
||||
}
|
||||
|
||||
private function Bits32ToBytes(i:uint, b:ByteArray, offset:uint):void
|
||||
{
|
||||
b[offset + 3] = i;
|
||||
b[offset + 2] = (i >> 8);
|
||||
b[offset + 1] = (i >> 16);
|
||||
b[offset] = (i >> 24);
|
||||
}
|
||||
|
||||
public function toString():String {
|
||||
return "blowfish";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,55 +0,0 @@
|
||||
/**
|
||||
* CBCMode
|
||||
*
|
||||
* An ActionScript 3 implementation of the CBC confidentiality mode
|
||||
* Copyright (c) 2007 Henri Torgemane
|
||||
*
|
||||
* See LICENSE.txt for full license information.
|
||||
*/
|
||||
package com.hurlant.crypto.symmetric
|
||||
{
|
||||
import flash.utils.ByteArray;
|
||||
|
||||
/**
|
||||
* CBC confidentiality mode. why not.
|
||||
*/
|
||||
public class CBCMode extends IVMode implements IMode
|
||||
{
|
||||
|
||||
public function CBCMode(key:ISymmetricKey, padding:IPad = null) {
|
||||
super(key, padding);
|
||||
}
|
||||
|
||||
public function encrypt(src:ByteArray):void {
|
||||
padding.pad(src);
|
||||
var vector:ByteArray = getIV4e();
|
||||
for (var i:uint=0;i<src.length;i+=blockSize) {
|
||||
for (var j:uint=0;j<blockSize;j++) {
|
||||
src[i+j] ^= vector[j];
|
||||
}
|
||||
key.encrypt(src, i);
|
||||
vector.position=0;
|
||||
vector.writeBytes(src, i, blockSize);
|
||||
}
|
||||
}
|
||||
public function decrypt(src:ByteArray):void {
|
||||
var vector:ByteArray = getIV4d();
|
||||
var tmp:ByteArray = new ByteArray;
|
||||
for (var i:uint=0;i<src.length;i+=blockSize) {
|
||||
tmp.position=0;
|
||||
tmp.writeBytes(src, i, blockSize);
|
||||
key.decrypt(src, i);
|
||||
for (var j:uint=0;j<blockSize;j++) {
|
||||
src[i+j] ^= vector[j];
|
||||
}
|
||||
vector.position=0;
|
||||
vector.writeBytes(tmp, 0, blockSize);
|
||||
}
|
||||
padding.unpad(src);
|
||||
}
|
||||
|
||||
public function toString():String {
|
||||
return key.toString()+"-cbc";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,61 +0,0 @@
|
||||
/**
|
||||
* CFB8Mode
|
||||
*
|
||||
* An ActionScript 3 implementation of the CFB-8 confidentiality mode
|
||||
* Copyright (c) 2007 Henri Torgemane
|
||||
*
|
||||
* See LICENSE.txt for full license information.
|
||||
*/
|
||||
package com.hurlant.crypto.symmetric
|
||||
{
|
||||
import com.hurlant.crypto.tests.TestCase;
|
||||
import flash.utils.ByteArray;
|
||||
|
||||
/**
|
||||
*
|
||||
* Note: The constructor accepts an optional padding argument, but ignores it otherwise.
|
||||
*/
|
||||
public class CFB8Mode extends IVMode implements IMode
|
||||
{
|
||||
public function CFB8Mode(key:ISymmetricKey, padding:IPad = null) {
|
||||
super(key, null);
|
||||
}
|
||||
|
||||
public function encrypt(src:ByteArray):void {
|
||||
var vector:ByteArray = getIV4e();
|
||||
var tmp:ByteArray = new ByteArray;
|
||||
for (var i:uint=0;i<src.length;i++) {
|
||||
tmp.position = 0;
|
||||
tmp.writeBytes(vector);
|
||||
key.encrypt(vector);
|
||||
src[i] ^= vector[0];
|
||||
// rotate
|
||||
for (var j:uint=0;j<blockSize-1;j++) {
|
||||
vector[j] = tmp[j+1];
|
||||
}
|
||||
vector[blockSize-1] = src[i];
|
||||
}
|
||||
}
|
||||
|
||||
public function decrypt(src:ByteArray):void {
|
||||
var vector:ByteArray = getIV4d();
|
||||
var tmp:ByteArray = new ByteArray;
|
||||
for (var i:uint=0;i<src.length;i++) {
|
||||
var c:uint = src[i];
|
||||
tmp.position = 0;
|
||||
tmp.writeBytes(vector); // I <- tmp
|
||||
key.encrypt(vector); // O <- vector
|
||||
src[i] ^= vector[0];
|
||||
// rotate
|
||||
for (var j:uint=0;j<blockSize-1;j++) {
|
||||
vector[j] = tmp[j+1];
|
||||
}
|
||||
vector[blockSize-1] = c;
|
||||
}
|
||||
|
||||
}
|
||||
public function toString():String {
|
||||
return key.toString()+"-cfb8";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,64 +0,0 @@
|
||||
/**
|
||||
* CFBMode
|
||||
*
|
||||
* An ActionScript 3 implementation of the CFB confidentiality mode
|
||||
* Copyright (c) 2007 Henri Torgemane
|
||||
*
|
||||
* See LICENSE.txt for full license information.
|
||||
*/
|
||||
package com.hurlant.crypto.symmetric
|
||||
{
|
||||
import flash.utils.ByteArray;
|
||||
|
||||
/**
|
||||
* This is the "full" CFB.
|
||||
* CFB1 and CFB8 are hiding somewhere else.
|
||||
*
|
||||
* Note: The constructor accepts an optional padding argument, but ignores it otherwise.
|
||||
*/
|
||||
public class CFBMode extends IVMode implements IMode
|
||||
{
|
||||
|
||||
public function CFBMode(key:ISymmetricKey, padding:IPad = null) {
|
||||
super(key,null);
|
||||
}
|
||||
|
||||
public function encrypt(src:ByteArray):void
|
||||
{
|
||||
var l:uint = src.length;
|
||||
var vector:ByteArray = getIV4e();
|
||||
for (var i:uint=0;i<src.length;i+=blockSize) {
|
||||
key.encrypt(vector);
|
||||
var chunk:uint = (i+blockSize<l)?blockSize:l-i;
|
||||
for (var j:uint=0;j<chunk;j++) {
|
||||
src[i+j] ^= vector[j];
|
||||
}
|
||||
vector.position=0;
|
||||
vector.writeBytes(src, i, chunk);
|
||||
}
|
||||
}
|
||||
|
||||
public function decrypt(src:ByteArray):void
|
||||
{
|
||||
var l:uint = src.length;
|
||||
var vector:ByteArray = getIV4d();
|
||||
var tmp:ByteArray = new ByteArray;
|
||||
for (var i:uint=0;i<src.length;i+=blockSize) {
|
||||
key.encrypt(vector);
|
||||
var chunk:uint = (i+blockSize<l)?blockSize:l-i;
|
||||
tmp.position=0;
|
||||
tmp.writeBytes(src, i, chunk);
|
||||
for (var j:uint=0;j<chunk;j++) {
|
||||
src[i+j] ^= vector[j];
|
||||
}
|
||||
vector.position=0;
|
||||
vector.writeBytes(tmp);
|
||||
}
|
||||
}
|
||||
|
||||
public function toString():String {
|
||||
return key.toString()+"-cfb";
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,58 +0,0 @@
|
||||
/**
|
||||
* CTRMode
|
||||
*
|
||||
* An ActionScript 3 implementation of the counter confidentiality mode
|
||||
* Copyright (c) 2007 Henri Torgemane
|
||||
*
|
||||
* See LICENSE.txt for full license information.
|
||||
*/
|
||||
package com.hurlant.crypto.symmetric
|
||||
{
|
||||
import flash.utils.ByteArray;
|
||||
|
||||
public class CTRMode extends IVMode implements IMode
|
||||
{
|
||||
|
||||
public function CTRMode(key:ISymmetricKey, padding:IPad = null) {
|
||||
super(key, padding);
|
||||
}
|
||||
|
||||
public function encrypt(src:ByteArray):void
|
||||
{
|
||||
padding.pad(src);
|
||||
var vector:ByteArray = getIV4e();
|
||||
core(src, vector);
|
||||
}
|
||||
|
||||
public function decrypt(src:ByteArray):void
|
||||
{
|
||||
var vector:ByteArray = getIV4d();
|
||||
core(src, vector);
|
||||
padding.unpad(src);
|
||||
}
|
||||
|
||||
private function core(src:ByteArray, iv:ByteArray):void {
|
||||
var X:ByteArray = new ByteArray;
|
||||
var Xenc:ByteArray = new ByteArray;
|
||||
X.writeBytes(iv);
|
||||
for (var i:uint=0;i<src.length;i+=blockSize) {
|
||||
Xenc.position=0;
|
||||
Xenc.writeBytes(X);
|
||||
key.encrypt(Xenc);
|
||||
for (var j:uint=0;j<blockSize;j++) {
|
||||
src[i+j] ^= Xenc[j];
|
||||
}
|
||||
|
||||
for (j=blockSize-1;j>=0;--j) {
|
||||
X[j]++;
|
||||
if (X[j]!=0)
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
public function toString():String {
|
||||
return key.toString()+"-ctr";
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,365 +0,0 @@
|
||||
/**
|
||||
* DESKey
|
||||
*
|
||||
* An Actionscript 3 implementation of the Data Encryption Standard (DES)
|
||||
* Copyright (c) 2007 Henri Torgemane
|
||||
*
|
||||
* Derived from:
|
||||
* The Bouncy Castle Crypto package,
|
||||
* Copyright (c) 2000-2004 The Legion Of The Bouncy Castle
|
||||
* (http://www.bouncycastle.org)
|
||||
*
|
||||
* See LICENSE.txt for full license information.
|
||||
*/
|
||||
package com.hurlant.crypto.symmetric
|
||||
{
|
||||
import flash.utils.ByteArray;
|
||||
import com.hurlant.util.Hex;
|
||||
import com.hurlant.util.Memory;
|
||||
|
||||
public class DESKey implements ISymmetricKey
|
||||
{
|
||||
/**
|
||||
* what follows is mainly taken from "Applied Cryptography", by Bruce
|
||||
* Schneier, however it also bears great resemblance to Richard
|
||||
* Outerbridge's D3DES...
|
||||
*/
|
||||
|
||||
private static const Df_Key:Array = [ 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32,
|
||||
0x10, 0x89, 0xab, 0xcd, 0xef, 0x01, 0x23, 0x45, 0x67 ];
|
||||
|
||||
private static const bytebit:Array = [ 128, 64, 32, 16, 8, 4, 2, 1 ];
|
||||
|
||||
private static const bigbyte:Array = [ 0x800000, 0x400000, 0x200000, 0x100000, 0x80000, 0x40000, 0x20000, 0x10000, 0x8000,
|
||||
0x4000, 0x2000, 0x1000, 0x800, 0x400, 0x200, 0x100, 0x80, 0x40, 0x20, 0x10, 0x8, 0x4, 0x2, 0x1 ];
|
||||
|
||||
/*
|
||||
* Use the key schedule specified in the Standard (ANSI X3.92-1981).
|
||||
*/
|
||||
|
||||
private static const pc1:Array = [ 56, 48, 40, 32, 24, 16, 8, 0, 57, 49, 41, 33, 25, 17, 9, 1, 58, 50, 42, 34, 26, 18, 10, 2,
|
||||
59, 51, 43, 35, 62, 54, 46, 38, 30, 22, 14, 6, 61, 53, 45, 37, 29, 21, 13, 5, 60, 52, 44, 36, 28, 20, 12,
|
||||
4, 27, 19, 11, 3 ];
|
||||
|
||||
private static const totrot:Array = [ 1, 2, 4, 6, 8, 10, 12, 14, 15, 17, 19, 21, 23, 25, 27, 28 ];
|
||||
|
||||
private static const pc2:Array = [ 13, 16, 10, 23, 0, 4, 2, 27, 14, 5, 20, 9, 22, 18, 11, 3, 25, 7, 15, 6, 26, 19, 12, 1, 40,
|
||||
51, 30, 36, 46, 54, 29, 39, 50, 44, 32, 47, 43, 48, 38, 55, 33, 52, 45, 41, 49, 35, 28, 31 ];
|
||||
|
||||
private static const SP1:Array = [ 0x01010400, 0x00000000, 0x00010000, 0x01010404, 0x01010004, 0x00010404, 0x00000004,
|
||||
0x00010000, 0x00000400, 0x01010400, 0x01010404, 0x00000400, 0x01000404, 0x01010004, 0x01000000, 0x00000004,
|
||||
0x00000404, 0x01000400, 0x01000400, 0x00010400, 0x00010400, 0x01010000, 0x01010000, 0x01000404, 0x00010004,
|
||||
0x01000004, 0x01000004, 0x00010004, 0x00000000, 0x00000404, 0x00010404, 0x01000000, 0x00010000, 0x01010404,
|
||||
0x00000004, 0x01010000, 0x01010400, 0x01000000, 0x01000000, 0x00000400, 0x01010004, 0x00010000, 0x00010400,
|
||||
0x01000004, 0x00000400, 0x00000004, 0x01000404, 0x00010404, 0x01010404, 0x00010004, 0x01010000, 0x01000404,
|
||||
0x01000004, 0x00000404, 0x00010404, 0x01010400, 0x00000404, 0x01000400, 0x01000400, 0x00000000, 0x00010004,
|
||||
0x00010400, 0x00000000, 0x01010004 ];
|
||||
|
||||
private static const SP2:Array = [ 0x80108020, 0x80008000, 0x00008000, 0x00108020, 0x00100000, 0x00000020, 0x80100020,
|
||||
0x80008020, 0x80000020, 0x80108020, 0x80108000, 0x80000000, 0x80008000, 0x00100000, 0x00000020, 0x80100020,
|
||||
0x00108000, 0x00100020, 0x80008020, 0x00000000, 0x80000000, 0x00008000, 0x00108020, 0x80100000, 0x00100020,
|
||||
0x80000020, 0x00000000, 0x00108000, 0x00008020, 0x80108000, 0x80100000, 0x00008020, 0x00000000, 0x00108020,
|
||||
0x80100020, 0x00100000, 0x80008020, 0x80100000, 0x80108000, 0x00008000, 0x80100000, 0x80008000, 0x00000020,
|
||||
0x80108020, 0x00108020, 0x00000020, 0x00008000, 0x80000000, 0x00008020, 0x80108000, 0x00100000, 0x80000020,
|
||||
0x00100020, 0x80008020, 0x80000020, 0x00100020, 0x00108000, 0x00000000, 0x80008000, 0x00008020, 0x80000000,
|
||||
0x80100020, 0x80108020, 0x00108000 ];
|
||||
|
||||
private static const SP3:Array = [ 0x00000208, 0x08020200, 0x00000000, 0x08020008, 0x08000200, 0x00000000, 0x00020208,
|
||||
0x08000200, 0x00020008, 0x08000008, 0x08000008, 0x00020000, 0x08020208, 0x00020008, 0x08020000, 0x00000208,
|
||||
0x08000000, 0x00000008, 0x08020200, 0x00000200, 0x00020200, 0x08020000, 0x08020008, 0x00020208, 0x08000208,
|
||||
0x00020200, 0x00020000, 0x08000208, 0x00000008, 0x08020208, 0x00000200, 0x08000000, 0x08020200, 0x08000000,
|
||||
0x00020008, 0x00000208, 0x00020000, 0x08020200, 0x08000200, 0x00000000, 0x00000200, 0x00020008, 0x08020208,
|
||||
0x08000200, 0x08000008, 0x00000200, 0x00000000, 0x08020008, 0x08000208, 0x00020000, 0x08000000, 0x08020208,
|
||||
0x00000008, 0x00020208, 0x00020200, 0x08000008, 0x08020000, 0x08000208, 0x00000208, 0x08020000, 0x00020208,
|
||||
0x00000008, 0x08020008, 0x00020200 ];
|
||||
|
||||
private static const SP4:Array = [ 0x00802001, 0x00002081, 0x00002081, 0x00000080, 0x00802080, 0x00800081, 0x00800001,
|
||||
0x00002001, 0x00000000, 0x00802000, 0x00802000, 0x00802081, 0x00000081, 0x00000000, 0x00800080, 0x00800001,
|
||||
0x00000001, 0x00002000, 0x00800000, 0x00802001, 0x00000080, 0x00800000, 0x00002001, 0x00002080, 0x00800081,
|
||||
0x00000001, 0x00002080, 0x00800080, 0x00002000, 0x00802080, 0x00802081, 0x00000081, 0x00800080, 0x00800001,
|
||||
0x00802000, 0x00802081, 0x00000081, 0x00000000, 0x00000000, 0x00802000, 0x00002080, 0x00800080, 0x00800081,
|
||||
0x00000001, 0x00802001, 0x00002081, 0x00002081, 0x00000080, 0x00802081, 0x00000081, 0x00000001, 0x00002000,
|
||||
0x00800001, 0x00002001, 0x00802080, 0x00800081, 0x00002001, 0x00002080, 0x00800000, 0x00802001, 0x00000080,
|
||||
0x00800000, 0x00002000, 0x00802080 ];
|
||||
|
||||
private static const SP5:Array = [ 0x00000100, 0x02080100, 0x02080000, 0x42000100, 0x00080000, 0x00000100, 0x40000000,
|
||||
0x02080000, 0x40080100, 0x00080000, 0x02000100, 0x40080100, 0x42000100, 0x42080000, 0x00080100, 0x40000000,
|
||||
0x02000000, 0x40080000, 0x40080000, 0x00000000, 0x40000100, 0x42080100, 0x42080100, 0x02000100, 0x42080000,
|
||||
0x40000100, 0x00000000, 0x42000000, 0x02080100, 0x02000000, 0x42000000, 0x00080100, 0x00080000, 0x42000100,
|
||||
0x00000100, 0x02000000, 0x40000000, 0x02080000, 0x42000100, 0x40080100, 0x02000100, 0x40000000, 0x42080000,
|
||||
0x02080100, 0x40080100, 0x00000100, 0x02000000, 0x42080000, 0x42080100, 0x00080100, 0x42000000, 0x42080100,
|
||||
0x02080000, 0x00000000, 0x40080000, 0x42000000, 0x00080100, 0x02000100, 0x40000100, 0x00080000, 0x00000000,
|
||||
0x40080000, 0x02080100, 0x40000100 ];
|
||||
|
||||
private static const SP6:Array = [ 0x20000010, 0x20400000, 0x00004000, 0x20404010, 0x20400000, 0x00000010, 0x20404010,
|
||||
0x00400000, 0x20004000, 0x00404010, 0x00400000, 0x20000010, 0x00400010, 0x20004000, 0x20000000, 0x00004010,
|
||||
0x00000000, 0x00400010, 0x20004010, 0x00004000, 0x00404000, 0x20004010, 0x00000010, 0x20400010, 0x20400010,
|
||||
0x00000000, 0x00404010, 0x20404000, 0x00004010, 0x00404000, 0x20404000, 0x20000000, 0x20004000, 0x00000010,
|
||||
0x20400010, 0x00404000, 0x20404010, 0x00400000, 0x00004010, 0x20000010, 0x00400000, 0x20004000, 0x20000000,
|
||||
0x00004010, 0x20000010, 0x20404010, 0x00404000, 0x20400000, 0x00404010, 0x20404000, 0x00000000, 0x20400010,
|
||||
0x00000010, 0x00004000, 0x20400000, 0x00404010, 0x00004000, 0x00400010, 0x20004010, 0x00000000, 0x20404000,
|
||||
0x20000000, 0x00400010, 0x20004010 ];
|
||||
|
||||
private static const SP7:Array = [ 0x00200000, 0x04200002, 0x04000802, 0x00000000, 0x00000800, 0x04000802, 0x00200802,
|
||||
0x04200800, 0x04200802, 0x00200000, 0x00000000, 0x04000002, 0x00000002, 0x04000000, 0x04200002, 0x00000802,
|
||||
0x04000800, 0x00200802, 0x00200002, 0x04000800, 0x04000002, 0x04200000, 0x04200800, 0x00200002, 0x04200000,
|
||||
0x00000800, 0x00000802, 0x04200802, 0x00200800, 0x00000002, 0x04000000, 0x00200800, 0x04000000, 0x00200800,
|
||||
0x00200000, 0x04000802, 0x04000802, 0x04200002, 0x04200002, 0x00000002, 0x00200002, 0x04000000, 0x04000800,
|
||||
0x00200000, 0x04200800, 0x00000802, 0x00200802, 0x04200800, 0x00000802, 0x04000002, 0x04200802, 0x04200000,
|
||||
0x00200800, 0x00000000, 0x00000002, 0x04200802, 0x00000000, 0x00200802, 0x04200000, 0x00000800, 0x04000002,
|
||||
0x04000800, 0x00000800, 0x00200002 ];
|
||||
|
||||
private static const SP8:Array = [ 0x10001040, 0x00001000, 0x00040000, 0x10041040, 0x10000000, 0x10001040, 0x00000040,
|
||||
0x10000000, 0x00040040, 0x10040000, 0x10041040, 0x00041000, 0x10041000, 0x00041040, 0x00001000, 0x00000040,
|
||||
0x10040000, 0x10000040, 0x10001000, 0x00001040, 0x00041000, 0x00040040, 0x10040040, 0x10041000, 0x00001040,
|
||||
0x00000000, 0x00000000, 0x10040040, 0x10000040, 0x10001000, 0x00041040, 0x00040000, 0x00041040, 0x00040000,
|
||||
0x10041000, 0x00001000, 0x00000040, 0x10040040, 0x00001000, 0x00041040, 0x10001000, 0x00000040, 0x10000040,
|
||||
0x10040000, 0x10040040, 0x10000000, 0x00040000, 0x10001040, 0x00000000, 0x10041040, 0x00040040, 0x10000040,
|
||||
0x10040000, 0x10001000, 0x10001040, 0x00000000, 0x10041040, 0x00041000, 0x00041000, 0x00001040, 0x00001040,
|
||||
0x00040040, 0x10000000, 0x10041000 ];
|
||||
|
||||
|
||||
protected var key:ByteArray;
|
||||
protected var encKey:Array;
|
||||
protected var decKey:Array;
|
||||
|
||||
|
||||
public function DESKey(key:ByteArray) {
|
||||
this.key = key;
|
||||
this.encKey = generateWorkingKey(true, key, 0);
|
||||
this.decKey = generateWorkingKey(false, key, 0);
|
||||
}
|
||||
|
||||
public function getBlockSize():uint
|
||||
{
|
||||
return 8;
|
||||
}
|
||||
|
||||
public function decrypt(block:ByteArray, index:uint=0):void
|
||||
{
|
||||
desFunc(decKey, block, index, block, index);
|
||||
}
|
||||
|
||||
public function dispose():void
|
||||
{
|
||||
var i:uint=0;
|
||||
for (i=0;i<encKey.length;i++) { encKey[i]=0; }
|
||||
for (i=0;i<decKey.length;i++) { decKey[i]=0; }
|
||||
encKey=null;
|
||||
decKey=null;
|
||||
for (i=0;i<key.length;i++) { key[i]=0; }
|
||||
key.length = 0;
|
||||
key = null;
|
||||
Memory.gc();
|
||||
}
|
||||
|
||||
public function encrypt(block:ByteArray, index:uint=0):void
|
||||
{
|
||||
desFunc(encKey, block, index, block, index);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* generate an integer based working key based on our secret key and what we
|
||||
* processing we are planning to do.
|
||||
*
|
||||
* Acknowledgements for this routine go to James Gillogly & Phil Karn.
|
||||
*/
|
||||
protected function generateWorkingKey(encrypting:Boolean, key:ByteArray, off:uint):Array
|
||||
{
|
||||
//int[] newKey = new int[32];
|
||||
var newKey:Array = [];
|
||||
//boolean[] pc1m = new boolean[56], pcr = new boolean[56];
|
||||
var pc1m:ByteArray = new ByteArray;
|
||||
var pcr:ByteArray = new ByteArray;
|
||||
|
||||
var l:uint;
|
||||
|
||||
for (var j:uint = 0; j < 56; j++)
|
||||
{
|
||||
l = pc1[j];
|
||||
|
||||
pc1m[j] = ((key[off + (l >>> 3)] & bytebit[l & 07]) != 0);
|
||||
}
|
||||
|
||||
for (var i:uint = 0; i < 16; i++)
|
||||
{
|
||||
var m:uint;
|
||||
var n:uint;
|
||||
|
||||
if (encrypting)
|
||||
{
|
||||
m = i << 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
m = (15 - i) << 1;
|
||||
}
|
||||
|
||||
n = m + 1;
|
||||
newKey[m] = newKey[n] = 0;
|
||||
|
||||
for (j = 0; j < 28; j++)
|
||||
{
|
||||
l = j + totrot[i];
|
||||
if (l < 28)
|
||||
{
|
||||
pcr[j] = pc1m[l];
|
||||
}
|
||||
else
|
||||
{
|
||||
pcr[j] = pc1m[l - 28];
|
||||
}
|
||||
}
|
||||
|
||||
for (j = 28; j < 56; j++)
|
||||
{
|
||||
l = j + totrot[i];
|
||||
if (l < 56)
|
||||
{
|
||||
pcr[j] = pc1m[l];
|
||||
}
|
||||
else
|
||||
{
|
||||
pcr[j] = pc1m[l - 28];
|
||||
}
|
||||
}
|
||||
|
||||
for (j = 0; j < 24; j++)
|
||||
{
|
||||
if (pcr[pc2[j]])
|
||||
{
|
||||
newKey[m] |= bigbyte[j];
|
||||
}
|
||||
|
||||
if (pcr[pc2[j + 24]])
|
||||
{
|
||||
newKey[n] |= bigbyte[j];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// store the processed key
|
||||
//
|
||||
for (i = 0; i != 32; i += 2)
|
||||
{
|
||||
var i1:uint;
|
||||
var i2:uint;
|
||||
|
||||
i1 = newKey[i];
|
||||
i2 = newKey[i + 1];
|
||||
|
||||
newKey[i] = ((i1 & 0x00fc0000) << 6) | ((i1 & 0x00000fc0) << 10) | ((i2 & 0x00fc0000) >>> 10)
|
||||
| ((i2 & 0x00000fc0) >>> 6);
|
||||
|
||||
newKey[i + 1] = ((i1 & 0x0003f000) << 12) | ((i1 & 0x0000003f) << 16) | ((i2 & 0x0003f000) >>> 4)
|
||||
| (i2 & 0x0000003f);
|
||||
}
|
||||
return newKey;
|
||||
}
|
||||
|
||||
/**
|
||||
* the DES engine.
|
||||
*/
|
||||
protected function desFunc(wKey:Array, inp:ByteArray, inOff:uint, out:ByteArray, outOff:uint):void
|
||||
{
|
||||
var work:uint;
|
||||
var right:uint;
|
||||
var left:uint;
|
||||
|
||||
left = (inp[inOff + 0] & 0xff) << 24;
|
||||
left |= (inp[inOff + 1] & 0xff) << 16;
|
||||
left |= (inp[inOff + 2] & 0xff) << 8;
|
||||
left |= (inp[inOff + 3] & 0xff);
|
||||
|
||||
right = (inp[inOff + 4] & 0xff) << 24;
|
||||
right |= (inp[inOff + 5] & 0xff) << 16;
|
||||
right |= (inp[inOff + 6] & 0xff) << 8;
|
||||
right |= (inp[inOff + 7] & 0xff);
|
||||
|
||||
work = ((left >>> 4) ^ right) & 0x0f0f0f0f;
|
||||
right ^= work;
|
||||
left ^= (work << 4);
|
||||
work = ((left >>> 16) ^ right) & 0x0000ffff;
|
||||
right ^= work;
|
||||
left ^= (work << 16);
|
||||
work = ((right >>> 2) ^ left) & 0x33333333;
|
||||
left ^= work;
|
||||
right ^= (work << 2);
|
||||
work = ((right >>> 8) ^ left) & 0x00ff00ff;
|
||||
left ^= work;
|
||||
right ^= (work << 8);
|
||||
right = ((right << 1) | ((right >>> 31) & 1)) & 0xffffffff;
|
||||
work = (left ^ right) & 0xaaaaaaaa;
|
||||
left ^= work;
|
||||
right ^= work;
|
||||
left = ((left << 1) | ((left >>> 31) & 1)) & 0xffffffff;
|
||||
|
||||
for (var round:uint = 0; round < 8; round++)
|
||||
{
|
||||
var fval:uint;
|
||||
|
||||
work = (right << 28) | (right >>> 4);
|
||||
work ^= wKey[round * 4 + 0];
|
||||
fval = SP7[work & 0x3f];
|
||||
fval |= SP5[(work >>> 8) & 0x3f];
|
||||
fval |= SP3[(work >>> 16) & 0x3f];
|
||||
fval |= SP1[(work >>> 24) & 0x3f];
|
||||
work = right ^ wKey[round * 4 + 1];
|
||||
fval |= SP8[work & 0x3f];
|
||||
fval |= SP6[(work >>> 8) & 0x3f];
|
||||
fval |= SP4[(work >>> 16) & 0x3f];
|
||||
fval |= SP2[(work >>> 24) & 0x3f];
|
||||
left ^= fval;
|
||||
work = (left << 28) | (left >>> 4);
|
||||
work ^= wKey[round * 4 + 2];
|
||||
fval = SP7[work & 0x3f];
|
||||
fval |= SP5[(work >>> 8) & 0x3f];
|
||||
fval |= SP3[(work >>> 16) & 0x3f];
|
||||
fval |= SP1[(work >>> 24) & 0x3f];
|
||||
work = left ^ wKey[round * 4 + 3];
|
||||
fval |= SP8[work & 0x3f];
|
||||
fval |= SP6[(work >>> 8) & 0x3f];
|
||||
fval |= SP4[(work >>> 16) & 0x3f];
|
||||
fval |= SP2[(work >>> 24) & 0x3f];
|
||||
right ^= fval;
|
||||
}
|
||||
|
||||
right = (right << 31) | (right >>> 1);
|
||||
work = (left ^ right) & 0xaaaaaaaa;
|
||||
left ^= work;
|
||||
right ^= work;
|
||||
left = (left << 31) | (left >>> 1);
|
||||
work = ((left >>> 8) ^ right) & 0x00ff00ff;
|
||||
right ^= work;
|
||||
left ^= (work << 8);
|
||||
work = ((left >>> 2) ^ right) & 0x33333333;
|
||||
right ^= work;
|
||||
left ^= (work << 2);
|
||||
work = ((right >>> 16) ^ left) & 0x0000ffff;
|
||||
left ^= work;
|
||||
right ^= (work << 16);
|
||||
work = ((right >>> 4) ^ left) & 0x0f0f0f0f;
|
||||
left ^= work;
|
||||
right ^= (work << 4);
|
||||
|
||||
out[outOff + 0] = ((right >>> 24) & 0xff);
|
||||
out[outOff + 1] = ((right >>> 16) & 0xff);
|
||||
out[outOff + 2] = ((right >>> 8) & 0xff);
|
||||
out[outOff + 3] = (right & 0xff);
|
||||
out[outOff + 4] = ((left >>> 24) & 0xff);
|
||||
out[outOff + 5] = ((left >>> 16) & 0xff);
|
||||
out[outOff + 6] = ((left >>> 8) & 0xff);
|
||||
out[outOff + 7] = (left & 0xff);
|
||||
}
|
||||
|
||||
|
||||
public function toString():String {
|
||||
return "des";
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,86 +0,0 @@
|
||||
/**
|
||||
* ECBMode
|
||||
*
|
||||
* An ActionScript 3 implementation of the ECB confidentiality mode
|
||||
* Copyright (c) 2007 Henri Torgemane
|
||||
*
|
||||
* See LICENSE.txt for full license information.
|
||||
*/
|
||||
package com.hurlant.crypto.symmetric
|
||||
{
|
||||
import flash.utils.ByteArray;
|
||||
import com.hurlant.util.Memory;
|
||||
import com.hurlant.util.Hex;
|
||||
|
||||
/**
|
||||
* ECB mode.
|
||||
* This uses a padding and a symmetric key.
|
||||
* If no padding is given, PKCS#5 is used.
|
||||
*/
|
||||
public class ECBMode implements IMode, ICipher
|
||||
{
|
||||
private var key:ISymmetricKey;
|
||||
private var padding:IPad;
|
||||
|
||||
public function ECBMode(key:ISymmetricKey, padding:IPad = null) {
|
||||
this.key = key;
|
||||
if (padding == null) {
|
||||
padding = new PKCS5(key.getBlockSize());
|
||||
} else {
|
||||
padding.setBlockSize(key.getBlockSize());
|
||||
}
|
||||
this.padding = padding;
|
||||
}
|
||||
|
||||
public function getBlockSize():uint {
|
||||
return key.getBlockSize();
|
||||
}
|
||||
|
||||
public function encrypt(src:ByteArray):void {
|
||||
padding.pad(src);
|
||||
src.position = 0;
|
||||
var blockSize:uint = key.getBlockSize();
|
||||
var tmp:ByteArray = new ByteArray;
|
||||
var dst:ByteArray = new ByteArray;
|
||||
for (var i:uint=0;i<src.length;i+=blockSize) {
|
||||
tmp.length=0;
|
||||
src.readBytes(tmp, 0, blockSize);
|
||||
key.encrypt(tmp);
|
||||
dst.writeBytes(tmp);
|
||||
}
|
||||
src.length=0;
|
||||
src.writeBytes(dst);
|
||||
}
|
||||
public function decrypt(src:ByteArray):void {
|
||||
src.position = 0;
|
||||
var blockSize:uint = key.getBlockSize();
|
||||
|
||||
// sanity check.
|
||||
if (src.length%blockSize!=0) {
|
||||
throw new Error("ECB mode cipher length must be a multiple of blocksize "+blockSize);
|
||||
}
|
||||
|
||||
var tmp:ByteArray = new ByteArray;
|
||||
var dst:ByteArray = new ByteArray;
|
||||
for (var i:uint=0;i<src.length;i+=blockSize) {
|
||||
tmp.length=0;
|
||||
src.readBytes(tmp, 0, blockSize);
|
||||
|
||||
key.decrypt(tmp);
|
||||
dst.writeBytes(tmp);
|
||||
}
|
||||
padding.unpad(dst);
|
||||
src.length=0;
|
||||
src.writeBytes(dst);
|
||||
}
|
||||
public function dispose():void {
|
||||
key.dispose();
|
||||
key = null;
|
||||
padding = null;
|
||||
Memory.gc();
|
||||
}
|
||||
public function toString():String {
|
||||
return key.toString()+"-ecb";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
/**
|
||||
* ICipher
|
||||
*
|
||||
* A generic interface to use symmetric ciphers
|
||||
* Copyright (c) 2007 Henri Torgemane
|
||||
*
|
||||
* See LICENSE.txt for full license information.
|
||||
*/
|
||||
package com.hurlant.crypto.symmetric
|
||||
{
|
||||
import flash.utils.ByteArray;
|
||||
|
||||
public interface ICipher
|
||||
{
|
||||
function getBlockSize():uint;
|
||||
function encrypt(src:ByteArray):void;
|
||||
function decrypt(src:ByteArray):void;
|
||||
function dispose():void;
|
||||
function toString():String;
|
||||
}
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
/**
|
||||
* IMode
|
||||
*
|
||||
* An interface for confidentiality modes to implement
|
||||
* This could become deprecated at some point.
|
||||
* Copyright (c) 2007 Henri Torgemane
|
||||
*
|
||||
* See LICENSE.txt for full license information.
|
||||
*/
|
||||
package com.hurlant.crypto.symmetric
|
||||
{
|
||||
public interface IMode extends ICipher
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -1,32 +0,0 @@
|
||||
/**
|
||||
* IPad
|
||||
*
|
||||
* An interface for padding mechanisms to implement.
|
||||
* Copyright (c) 2007 Henri Torgemane
|
||||
*
|
||||
* See LICENSE.txt for full license information.
|
||||
*/
|
||||
package com.hurlant.crypto.symmetric
|
||||
{
|
||||
import flash.utils.ByteArray;
|
||||
|
||||
/**
|
||||
* Tiny interface that represents a padding mechanism.
|
||||
*/
|
||||
public interface IPad
|
||||
{
|
||||
/**
|
||||
* Add padding to the array
|
||||
*/
|
||||
function pad(a:ByteArray):void;
|
||||
/**
|
||||
* Remove padding from the array.
|
||||
* @throws Error if the padding is invalid.
|
||||
*/
|
||||
function unpad(a:ByteArray):void;
|
||||
/**
|
||||
* Set the blockSize to work on
|
||||
*/
|
||||
function setBlockSize(bs:uint):void;
|
||||
}
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
/**
|
||||
* IStreamCipher
|
||||
*
|
||||
* A "marker" interface for stream ciphers.
|
||||
* Copyright (c) 2007 Henri Torgemane
|
||||
*
|
||||
* See LICENSE.txt for full license information.
|
||||
*/
|
||||
package com.hurlant.crypto.symmetric {
|
||||
|
||||
/**
|
||||
* A marker to indicate how this cipher works.
|
||||
* A stream cipher:
|
||||
* - does not use initialization vector
|
||||
* - keeps some internal state between calls to encrypt() and decrypt()
|
||||
*
|
||||
*/
|
||||
public interface IStreamCipher extends ICipher {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,35 +0,0 @@
|
||||
/**
|
||||
* ISymmetricKey
|
||||
*
|
||||
* An interface for symmetric encryption keys to implement.
|
||||
* Copyright (c) 2007 Henri Torgemane
|
||||
*
|
||||
* See LICENSE.txt for full license information.
|
||||
*/
|
||||
package com.hurlant.crypto.symmetric
|
||||
{
|
||||
import flash.utils.ByteArray;
|
||||
|
||||
public interface ISymmetricKey
|
||||
{
|
||||
/**
|
||||
* Returns the block size used by this particular encryption algorithm
|
||||
*/
|
||||
function getBlockSize():uint;
|
||||
/**
|
||||
* Encrypt one block of data in "block", starting at "index", of length "getBlockSize()"
|
||||
*/
|
||||
function encrypt(block:ByteArray, index:uint=0):void;
|
||||
/**
|
||||
* Decrypt one block of data in "block", starting at "index", of length "getBlockSize()"
|
||||
*/
|
||||
function decrypt(block:ByteArray, index:uint=0):void;
|
||||
/**
|
||||
* Attempts to destroy sensitive information from memory, such as encryption keys.
|
||||
* Note: This is not guaranteed to work given the Flash sandbox model.
|
||||
*/
|
||||
function dispose():void;
|
||||
|
||||
function toString():String;
|
||||
}
|
||||
}
|
||||
@@ -1,110 +0,0 @@
|
||||
/**
|
||||
* IVMode
|
||||
*
|
||||
* An abstract class for confidentialy modes that rely on an initialization vector.
|
||||
* Copyright (c) 2007 Henri Torgemane
|
||||
*
|
||||
* See LICENSE.txt for full license information.
|
||||
*/
|
||||
package com.hurlant.crypto.symmetric
|
||||
{
|
||||
import com.hurlant.crypto.prng.Random;
|
||||
import com.hurlant.crypto.tests.TestCase;
|
||||
import com.hurlant.util.Memory;
|
||||
|
||||
import flash.utils.ByteArray;
|
||||
|
||||
/**
|
||||
* An "abtract" class to avoid redundant code in subclasses
|
||||
*/
|
||||
public class IVMode
|
||||
{
|
||||
protected var key:ISymmetricKey;
|
||||
protected var padding:IPad;
|
||||
// random generator used to generate IVs
|
||||
protected var prng:Random;
|
||||
// optional static IV. used for testing only.
|
||||
protected var iv:ByteArray;
|
||||
// generated IV is stored here.
|
||||
protected var lastIV:ByteArray;
|
||||
protected var blockSize:uint;
|
||||
|
||||
|
||||
public function IVMode(key:ISymmetricKey, padding:IPad = null) {
|
||||
this.key = key;
|
||||
blockSize = key.getBlockSize();
|
||||
if (padding == null) {
|
||||
padding = new PKCS5(blockSize);
|
||||
} else {
|
||||
padding.setBlockSize(blockSize);
|
||||
}
|
||||
this.padding = padding;
|
||||
|
||||
prng = new Random;
|
||||
iv = null;
|
||||
lastIV = new ByteArray;
|
||||
}
|
||||
|
||||
public function getBlockSize():uint {
|
||||
return key.getBlockSize();
|
||||
}
|
||||
public function dispose():void {
|
||||
var i:uint;
|
||||
if (iv != null) {
|
||||
for (i=0;i<iv.length;i++) {
|
||||
iv[i] = prng.nextByte();
|
||||
}
|
||||
iv.length=0;
|
||||
iv = null;
|
||||
}
|
||||
if (lastIV != null) {
|
||||
for (i=0;i<iv.length;i++) {
|
||||
lastIV[i] = prng.nextByte();
|
||||
}
|
||||
lastIV.length=0;
|
||||
lastIV=null;
|
||||
}
|
||||
key.dispose();
|
||||
key = null;
|
||||
padding = null;
|
||||
prng.dispose();
|
||||
prng = null;
|
||||
Memory.gc();
|
||||
}
|
||||
/**
|
||||
* Optional function to force the IV value.
|
||||
* Normally, an IV gets generated randomly at every encrypt() call.
|
||||
* Also, use this to set the IV before calling decrypt()
|
||||
* (if not set before decrypt(), the IV is read from the beginning of the stream.)
|
||||
*/
|
||||
public function set IV(value:ByteArray):void {
|
||||
iv = value;
|
||||
lastIV.length=0;
|
||||
lastIV.writeBytes(iv);
|
||||
}
|
||||
public function get IV():ByteArray {
|
||||
return lastIV;
|
||||
}
|
||||
|
||||
protected function getIV4e():ByteArray {
|
||||
var vec:ByteArray = new ByteArray;
|
||||
if (iv) {
|
||||
vec.writeBytes(iv);
|
||||
} else {
|
||||
prng.nextBytes(vec, blockSize);
|
||||
}
|
||||
lastIV.length=0;
|
||||
lastIV.writeBytes(vec);
|
||||
return vec;
|
||||
}
|
||||
protected function getIV4d():ByteArray {
|
||||
var vec:ByteArray = new ByteArray;
|
||||
if (iv) {
|
||||
vec.writeBytes(iv);
|
||||
} else {
|
||||
throw new Error("an IV must be set before calling decrypt()");
|
||||
}
|
||||
return vec;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,34 +0,0 @@
|
||||
/**
|
||||
* NullPad
|
||||
*
|
||||
* A padding class that doesn't pad.
|
||||
* Copyright (c) 2007 Henri Torgemane
|
||||
*
|
||||
* See LICENSE.txt for full license information.
|
||||
*/
|
||||
package com.hurlant.crypto.symmetric
|
||||
{
|
||||
import flash.utils.ByteArray;
|
||||
|
||||
/**
|
||||
* A pad that does nothing.
|
||||
* Useful when you don't want padding in your Mode.
|
||||
*/
|
||||
public class NullPad implements IPad
|
||||
{
|
||||
public function unpad(a:ByteArray):void
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
public function pad(a:ByteArray):void
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
public function setBlockSize(bs:uint):void {
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,52 +0,0 @@
|
||||
/**
|
||||
* OFBMode
|
||||
*
|
||||
* An ActionScript 3 implementation of the OFB confidentiality mode
|
||||
* Copyright (c) 2007 Henri Torgemane
|
||||
*
|
||||
* See LICENSE.txt for full license information.
|
||||
*/
|
||||
package com.hurlant.crypto.symmetric
|
||||
{
|
||||
import flash.utils.ByteArray;
|
||||
|
||||
public class OFBMode extends IVMode implements IMode
|
||||
{
|
||||
public function OFBMode(key:ISymmetricKey, padding:IPad=null)
|
||||
{
|
||||
super(key, null);
|
||||
}
|
||||
|
||||
public function encrypt(src:ByteArray):void
|
||||
{
|
||||
var vector:ByteArray = getIV4e();
|
||||
core(src, vector);
|
||||
}
|
||||
|
||||
public function decrypt(src:ByteArray):void
|
||||
{
|
||||
var vector:ByteArray = getIV4d();
|
||||
core(src, vector);
|
||||
}
|
||||
|
||||
private function core(src:ByteArray, iv:ByteArray):void {
|
||||
var l:uint = src.length;
|
||||
var tmp:ByteArray = new ByteArray;
|
||||
for (var i:uint=0;i<src.length;i+=blockSize) {
|
||||
key.encrypt(iv);
|
||||
tmp.position=0;
|
||||
tmp.writeBytes(iv);
|
||||
var chunk:uint = (i+blockSize<l)?blockSize:l-i;
|
||||
for (var j:uint=0;j<chunk;j++) {
|
||||
src[i+j] ^= iv[j];
|
||||
}
|
||||
iv.position=0;
|
||||
iv.writeBytes(tmp);
|
||||
}
|
||||
}
|
||||
public function toString():String {
|
||||
return key.toString()+"-ofb";
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,44 +0,0 @@
|
||||
/**
|
||||
* PKCS5
|
||||
*
|
||||
* A padding implementation of PKCS5.
|
||||
* Copyright (c) 2007 Henri Torgemane
|
||||
*
|
||||
* See LICENSE.txt for full license information.
|
||||
*/
|
||||
package com.hurlant.crypto.symmetric
|
||||
{
|
||||
import flash.utils.ByteArray;
|
||||
|
||||
public class PKCS5 implements IPad
|
||||
{
|
||||
private var blockSize:uint;
|
||||
|
||||
public function PKCS5(blockSize:uint=0) {
|
||||
this.blockSize = blockSize;
|
||||
}
|
||||
|
||||
public function pad(a:ByteArray):void {
|
||||
var c:uint = blockSize-a.length%blockSize;
|
||||
for (var i:uint=0;i<c;i++){
|
||||
a[a.length] = c;
|
||||
}
|
||||
}
|
||||
public function unpad(a:ByteArray):void {
|
||||
var c:uint = a.length%blockSize;
|
||||
if (c!=0) throw new Error("PKCS#5::unpad: ByteArray.length isn't a multiple of the blockSize");
|
||||
c = a[a.length-1];
|
||||
for (var i:uint=c;i>0;i--) {
|
||||
var v:uint = a[a.length-1];
|
||||
a.length--;
|
||||
if (c!=v) throw new Error("PKCS#5:unpad: Invalid padding value. expected ["+c+"], found ["+v+"]");
|
||||
}
|
||||
// that is all.
|
||||
}
|
||||
|
||||
public function setBlockSize(bs:uint):void {
|
||||
blockSize = bs;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,44 +0,0 @@
|
||||
/**
|
||||
* TLSPad
|
||||
*
|
||||
* A padding implementation used by TLS
|
||||
* Copyright (c) 2007 Henri Torgemane
|
||||
*
|
||||
* See LICENSE.txt for full license information.
|
||||
*/
|
||||
package com.hurlant.crypto.symmetric {
|
||||
import flash.utils.ByteArray;
|
||||
import com.hurlant.util.Hex;
|
||||
import com.hurlant.crypto.tls.TLSError;
|
||||
|
||||
public class SSLPad implements IPad {
|
||||
private var blockSize:uint;
|
||||
|
||||
public function SSLPad(blockSize:uint=0) {
|
||||
this.blockSize = blockSize;
|
||||
}
|
||||
public function pad(a:ByteArray):void {
|
||||
var c:uint = blockSize - (a.length+1)%blockSize;
|
||||
for (var i:uint=0;i<=c;i++) {
|
||||
a[a.length] = c;
|
||||
}
|
||||
|
||||
}
|
||||
public function unpad(a:ByteArray):void {
|
||||
var c:uint = a.length%blockSize;
|
||||
if (c!=0) throw new TLSError("SSLPad::unpad: ByteArray.length isn't a multiple of the blockSize", TLSError.bad_record_mac);
|
||||
c = a[a.length-1];
|
||||
for (var i:uint=c;i>0;i--) {
|
||||
var v:uint = a[a.length-1];
|
||||
a.length--;
|
||||
// But LOOK! SSL 3.0 doesn't care about this, bytes are arbitrary!
|
||||
// if (c!=v) throw new TLSError("SSLPad:unpad: Invalid padding value. expected ["+c+"], found ["+v+"]", TLSError.bad_record_mac);
|
||||
}
|
||||
a.length--;
|
||||
|
||||
}
|
||||
public function setBlockSize(bs:uint):void {
|
||||
blockSize = bs;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,60 +0,0 @@
|
||||
/**
|
||||
* SimpleIVMode
|
||||
*
|
||||
* A convenience class that automatically places the IV
|
||||
* at the beginning of the encrypted stream, so it doesn't have to
|
||||
* be handled explicitely.
|
||||
* Copyright (c) 2007 Henri Torgemane
|
||||
*
|
||||
* See LICENSE.txt for full license information.
|
||||
*/
|
||||
package com.hurlant.crypto.symmetric
|
||||
{
|
||||
import flash.utils.ByteArray;
|
||||
import com.hurlant.util.Memory;
|
||||
|
||||
public class SimpleIVMode implements IMode, ICipher
|
||||
{
|
||||
protected var mode:IVMode;
|
||||
protected var cipher:ICipher;
|
||||
|
||||
public function SimpleIVMode(mode:IVMode) {
|
||||
this.mode = mode;
|
||||
cipher = mode as ICipher;
|
||||
}
|
||||
|
||||
public function getBlockSize():uint {
|
||||
return mode.getBlockSize();
|
||||
}
|
||||
|
||||
public function dispose():void {
|
||||
mode.dispose();
|
||||
mode = null;
|
||||
cipher = null;
|
||||
Memory.gc();
|
||||
}
|
||||
|
||||
public function encrypt(src:ByteArray):void {
|
||||
cipher.encrypt(src);
|
||||
var tmp:ByteArray = new ByteArray;
|
||||
tmp.writeBytes(mode.IV);
|
||||
tmp.writeBytes(src);
|
||||
src.position=0;
|
||||
src.writeBytes(tmp);
|
||||
}
|
||||
|
||||
public function decrypt(src:ByteArray):void {
|
||||
var tmp:ByteArray = new ByteArray;
|
||||
tmp.writeBytes(src, 0, getBlockSize());
|
||||
mode.IV = tmp;
|
||||
tmp = new ByteArray;
|
||||
tmp.writeBytes(src, getBlockSize());
|
||||
cipher.decrypt(tmp);
|
||||
src.length=0;
|
||||
src.writeBytes(tmp);
|
||||
}
|
||||
public function toString():String {
|
||||
return "simple-"+cipher.toString();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,42 +0,0 @@
|
||||
/**
|
||||
* TLSPad
|
||||
*
|
||||
* A padding implementation used by TLS
|
||||
* Copyright (c) 2007 Henri Torgemane
|
||||
*
|
||||
* See LICENSE.txt for full license information.
|
||||
*/
|
||||
package com.hurlant.crypto.symmetric {
|
||||
import flash.utils.ByteArray;
|
||||
import com.hurlant.util.Hex;
|
||||
import com.hurlant.crypto.tls.TLSError;
|
||||
|
||||
public class TLSPad implements IPad {
|
||||
private var blockSize:uint;
|
||||
|
||||
public function TLSPad(blockSize:uint=0) {
|
||||
this.blockSize = blockSize;
|
||||
}
|
||||
public function pad(a:ByteArray):void {
|
||||
var c:uint = blockSize - (a.length+1)%blockSize;
|
||||
for (var i:uint=0;i<=c;i++) {
|
||||
a[a.length] = c;
|
||||
}
|
||||
}
|
||||
public function unpad(a:ByteArray):void {
|
||||
var c:uint = a.length%blockSize;
|
||||
if (c!=0) throw new TLSError("TLSPad::unpad: ByteArray.length isn't a multiple of the blockSize", TLSError.bad_record_mac);
|
||||
c = a[a.length-1];
|
||||
for (var i:uint=c;i>0;i--) {
|
||||
var v:uint = a[a.length-1];
|
||||
a.length--;
|
||||
if (c!=v) throw new TLSError("TLSPad:unpad: Invalid padding value. expected ["+c+"], found ["+v+"]", TLSError.bad_record_mac);
|
||||
}
|
||||
a.length--;
|
||||
// mostly ripped off from PKCS5.as, but with subtle differences
|
||||
}
|
||||
public function setBlockSize(bs:uint):void {
|
||||
blockSize = bs;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,88 +0,0 @@
|
||||
/**
|
||||
* TripleDESKey
|
||||
*
|
||||
* An Actionscript 3 implementation of Triple DES
|
||||
* Copyright (c) 2007 Henri Torgemane
|
||||
*
|
||||
* Derived from:
|
||||
* The Bouncy Castle Crypto package,
|
||||
* Copyright (c) 2000-2004 The Legion Of The Bouncy Castle
|
||||
* (http://www.bouncycastle.org)
|
||||
*
|
||||
* See LICENSE.txt for full license information.
|
||||
*/
|
||||
package com.hurlant.crypto.symmetric
|
||||
{
|
||||
import flash.utils.ByteArray;
|
||||
import com.hurlant.util.Memory;
|
||||
import com.hurlant.util.Hex;
|
||||
|
||||
public class TripleDESKey extends DESKey
|
||||
{
|
||||
protected var encKey2:Array;
|
||||
protected var encKey3:Array;
|
||||
protected var decKey2:Array;
|
||||
protected var decKey3:Array;
|
||||
|
||||
/**
|
||||
* This supports 2TDES and 3TDES.
|
||||
* If the key passed is 128 bits, 2TDES is used.
|
||||
* If the key has 192 bits, 3TDES is used.
|
||||
* Other key lengths give "undefined" results.
|
||||
*/
|
||||
public function TripleDESKey(key:ByteArray)
|
||||
{
|
||||
super(key);
|
||||
encKey2 = generateWorkingKey(false, key, 8);
|
||||
decKey2 = generateWorkingKey(true, key, 8);
|
||||
if (key.length>16) {
|
||||
encKey3 = generateWorkingKey(true, key, 16);
|
||||
decKey3 = generateWorkingKey(false, key, 16);
|
||||
} else {
|
||||
encKey3 = encKey;
|
||||
decKey3 = decKey;
|
||||
}
|
||||
}
|
||||
|
||||
public override function dispose():void
|
||||
{
|
||||
super.dispose();
|
||||
var i:uint = 0;
|
||||
if (encKey2!=null) {
|
||||
for (i=0;i<encKey2.length;i++) { encKey2[i]=0; }
|
||||
encKey2=null;
|
||||
}
|
||||
if (encKey3!=null) {
|
||||
for (i=0;i<encKey3.length;i++) { encKey3[i]=0; }
|
||||
encKey3=null;
|
||||
}
|
||||
if (decKey2!=null) {
|
||||
for (i=0;i<decKey2.length;i++) { decKey2[i]=0; }
|
||||
decKey2=null
|
||||
}
|
||||
if (decKey3!=null) {
|
||||
for (i=0;i<decKey3.length;i++) { decKey3[i]=0; }
|
||||
decKey3=null;
|
||||
}
|
||||
Memory.gc();
|
||||
}
|
||||
|
||||
public override function encrypt(block:ByteArray, index:uint=0):void
|
||||
{
|
||||
desFunc(encKey, block,index, block,index);
|
||||
desFunc(encKey2, block,index, block,index);
|
||||
desFunc(encKey3, block,index, block,index);
|
||||
}
|
||||
|
||||
public override function decrypt(block:ByteArray, index:uint=0):void
|
||||
{
|
||||
desFunc(decKey3, block, index, block, index);
|
||||
desFunc(decKey2, block, index, block, index);
|
||||
desFunc(decKey, block, index, block, index);
|
||||
}
|
||||
|
||||
public override function toString():String {
|
||||
return "3des";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,94 +0,0 @@
|
||||
/**
|
||||
* XTeaKey
|
||||
*
|
||||
* An ActionScript 3 implementation of the XTea algorithm
|
||||
* Copyright (c) 2007 Henri Torgemane
|
||||
*
|
||||
* See LICENSE.txt for full license information.
|
||||
*/
|
||||
package com.hurlant.crypto.symmetric
|
||||
{
|
||||
import com.hurlant.crypto.prng.Random;
|
||||
import com.hurlant.util.Memory;
|
||||
|
||||
import flash.utils.ByteArray;
|
||||
|
||||
|
||||
public class XTeaKey implements ISymmetricKey
|
||||
{
|
||||
public const NUM_ROUNDS:uint = 64;
|
||||
private var k:Array;
|
||||
|
||||
public function XTeaKey(a:ByteArray) {
|
||||
a.position=0;
|
||||
k = [a.readUnsignedInt(),a.readUnsignedInt(),a.readUnsignedInt(),a.readUnsignedInt()];
|
||||
}
|
||||
/**
|
||||
* K is an hex string with 32 digits.
|
||||
*/
|
||||
public static function parseKey(K:String):XTeaKey {
|
||||
var a:ByteArray = new ByteArray;
|
||||
a.writeUnsignedInt(parseInt(K.substr(0,8),16));
|
||||
a.writeUnsignedInt(parseInt(K.substr(8,8),16));
|
||||
a.writeUnsignedInt(parseInt(K.substr(16,8),16));
|
||||
a.writeUnsignedInt(parseInt(K.substr(24,8),16));
|
||||
a.position = 0;
|
||||
return new XTeaKey(a);
|
||||
}
|
||||
|
||||
public function getBlockSize():uint {
|
||||
return 8;
|
||||
}
|
||||
|
||||
public function encrypt(block:ByteArray, index:uint=0):void {
|
||||
block.position = index;
|
||||
var v0:uint = block.readUnsignedInt();
|
||||
var v1:uint = block.readUnsignedInt();
|
||||
var i:uint;
|
||||
var sum:uint =0;
|
||||
var delta:uint = 0x9E3779B9;
|
||||
for (i=0; i<NUM_ROUNDS; i++) {
|
||||
v0 += (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + k[sum & 3]);
|
||||
sum += delta;
|
||||
v1 += (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + k[(sum>>11) & 3]);
|
||||
}
|
||||
block.position-=8;
|
||||
block.writeUnsignedInt(v0);
|
||||
block.writeUnsignedInt(v1);
|
||||
}
|
||||
|
||||
public function decrypt(block:ByteArray, index:uint=0):void {
|
||||
block.position = index;
|
||||
var v0:uint = block.readUnsignedInt();
|
||||
var v1:uint = block.readUnsignedInt();
|
||||
var i:uint;
|
||||
var delta:uint = 0x9E3779B9;
|
||||
var sum:uint = delta*NUM_ROUNDS;
|
||||
for (i=0; i<NUM_ROUNDS; i++) {
|
||||
v1 -= (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + k[(sum>>11) & 3]);
|
||||
sum -= delta;
|
||||
v0 -= (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + k[sum & 3]);
|
||||
}
|
||||
block.position-=8;
|
||||
block.writeUnsignedInt(v0);
|
||||
block.writeUnsignedInt(v1);
|
||||
}
|
||||
|
||||
public function dispose():void {
|
||||
//private var k:Array;
|
||||
var r:Random = new Random;
|
||||
for (var i:uint=0;i<k.length;i++) {
|
||||
k[i] = r.nextByte();
|
||||
delete k[i];
|
||||
}
|
||||
k = null;
|
||||
Memory.gc();
|
||||
}
|
||||
|
||||
public function toString():String {
|
||||
return "xtea";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -1,29 +0,0 @@
|
||||
#!/usr/bin/perl
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
sub say {
|
||||
my $w = shift;
|
||||
print $w;
|
||||
print "\n";
|
||||
}
|
||||
|
||||
sub dump {
|
||||
my $i = shift;
|
||||
&say(sprintf("Sbox[%d] = _Sbox[%d]", $i, $i));
|
||||
&say(sprintf("InvSbox[%d] = _InvSbox[%d]", $i, $i));
|
||||
&say(sprintf("Xtime2Sbox[%d] = _Xtime2Sbox[%d]", $i, $i));
|
||||
&say(sprintf("Xtime3Sbox[%d] = _Xtime3Sbox[%d]", $i, $i));
|
||||
&say(sprintf("Xtime2[%d] = _Xtime2[%d]", $i, $i));
|
||||
&say(sprintf("Xtime9[%d] = _Xtime9[%d]", $i, $i));
|
||||
&say(sprintf("XtimeB[%d] = _XtimeB[%d]", $i, $i));
|
||||
&say(sprintf("XtimeD[%d] = _XtimeD[%d]", $i, $i));
|
||||
&say(sprintf("XtimeE[%d] = _XtimeE[%d]", $i, $i));
|
||||
}
|
||||
|
||||
for (my $i=0;$i<256;$i++) {
|
||||
&dump($i);
|
||||
}
|
||||
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user