422 Commits

Author SHA1 Message Date
Solly Ross cd4bc7590e Update to 0.6.1
This is a minor patch release which fixes the functionality of
the file_only parameter and prevents uninteded directory listings.
2015-05-11 10:35:55 -04:00
Solly Ross d626fed76a Restore functionaltiy to file_only
There was a bug in WebSocketServer that prevented the `file_only`
parameter from actually being set as an instance property, causing
directory listings to appear even with `file_only=True`.  This
commit fixes that.

See-Also: https://bugs.launchpad.net/nova/+bug/1447675

Conflicts:
	websockify/websocket.py
2015-05-11 10:30:49 -04:00
Solly Ross 739af6ecb4 Update to v0.6.0
*** NOTE ***

This version of websockify will break existing code which sub-classes
`WebsocketProxy` -- see pull requests #110 and #111
2014-02-18 17:03:09 -05:00
Joel Martin 56b740ef5c README: update with general contact info. 2014-02-03 09:26:03 -06:00
Solly Ross 18e70c52e1 Fix default log level in echo and load tests
Since we switched to using the `logging` module to log
in pull request #100, none of the messages on the 'INFO'
level were being shown from `tests/echo.py` and
`tests/load.py`, since the default log level is 'WARNING'.

Now, the log level is set to INFO in `tests/echo.py` and
`tests/load.py`, to match the log level in the main websockify
executable.

Fixes #109
2014-01-30 17:11:20 -05:00
Joel Martin cc3ccf0ddd README: fix wrap mode examples. 2014-01-13 13:25:13 -06:00
astrand 38db12c2b0 Merge pull request #111 from astrand/master
Refactor to use standard SocketServer RequestHandler design.
2013-12-19 01:31:14 -08:00
Peter Åstrand (astrand) a749611370 Merge remote branch 'upstream/master' 2013-12-19 10:28:37 +01:00
Peter Åstrand (astrand) b662d185ca Prepare for fixing https://github.com/kanaka/websockify/pull/111
Move around functions and methods, so that connection-related and
server-related stuff are close together.

This patch just moves things around - it does not change anything at
all. This can be verified with:

git diff | grep ^- | cut -c 2- | sort > removed
git diff | grep ^+ | cut -c 2- | sort > added
diff -u removed added
2013-12-19 10:24:36 +01:00
Peter Åstrand (astrand) 6de6933819 Minor whitespace and layout tweaks, to reduce diff against
upstream/master.
2013-12-17 14:20:14 +01:00
Peter Åstrand (astrand) f46db48399 Merge remote branch 'upstream/master'
Conflicts:
	websockify/websocket.py
2013-12-17 14:04:30 +01:00
Peter Åstrand (astrand) 8049ddfe26 Cherry-picked 4e3388964a from
astrand/websockify:

    Prepare for fixing https://github.com/kanaka/websockify/issues/71:
    Move around functions and methods, so that connection-related and
    server-related stuff are close together.

    This patch just moves things around - it does not change anything at
    all. This can be verified with:

    git diff websocket.py | grep ^- | cut -c 2- | sort > removed
    git diff websocket.py | grep ^+ | cut -c 2- | sort > added
    diff -u removed added
2013-12-17 13:56:20 +01:00
Peter Åstrand (astrand) f64e3dea51 Merge remote branch 'upstream/master', after #110 was merged. 2013-12-16 16:18:41 +01:00
astrand 17455afe4d Merge pull request #110 from astrand/rename-self-client
Rename self.client and new_client - prepare for #72 / #111
2013-12-16 05:45:03 -08:00
Peter Åstrand (astrand) 047ce47742 Rename new_client to new_websocket_client, in order to have a better
name in the SocketServer/HTTPServer request handler hierarchy. Prepare
for merge pull request #72. This work has been picked out of
7b3dd8a6f5 .
2013-11-28 13:33:28 +01:00
Peter Åstrand (astrand) 558402848e Rename self.client to self.request, in preparation for merging pull
request #72. The standard Python SocketServer/BaseRequestHandler
requires this name.
2013-11-28 13:23:50 +01:00
Peter Åstrand (astrand) db93395061 Follow up on 131f9ea645: Proper logging
in request handler class.
2013-11-28 12:37:57 +01:00
Peter Åstrand (astrand) e246e98b20 Merge commit '34a1b68d79a13c03aa63b5c4194796341c9383fe'
* commit '34a1b68d79a13c03aa63b5c4194796341c9383fe':
  Clarify ssl module build for old python versions.
2013-11-28 09:34:43 +01:00
Peter Åstrand (astrand) 7ecfa4f384 Merge commit 'a04edfe80f54b44df5a3579f71710560c6b7b4fc'
* commit 'a04edfe80f54b44df5a3579f71710560c6b7b4fc':
  Added temp dir for unit test data and cleanup
2013-11-28 09:34:33 +01:00
Peter Åstrand (astrand) bc216fb7d1 Merge commit 'a47be21f9fa69ddf8d888ff9e3c75cdfc9e31c00'
* commit 'a47be21f9fa69ddf8d888ff9e3c75cdfc9e31c00':
  Added unit tests for websocket and websocketproxy
2013-11-28 09:32:49 +01:00
Peter Åstrand (astrand) b92528aeba Merge commit 'c3acdc2e38f871e28ffda1847b4338c4b02296b8'
* commit 'c3acdc2e38f871e28ffda1847b4338c4b02296b8':
  Adds optional TCP_KEEPALIVE to WebSocketServer
2013-11-28 09:32:30 +01:00
Peter Åstrand (astrand) 81e2a53692 Merge commit '13c99bcf053f7f3af8ba84c0d963a9591e020f49'
* commit '13c99bcf053f7f3af8ba84c0d963a9591e020f49':
  Fix search path construction in tests.
2013-11-28 09:14:25 +01:00
Peter Åstrand (astrand) 602248425a Merge commit 'b4e0b534d5d04d57265045b4baf49dd81555064b'
* commit 'b4e0b534d5d04d57265045b4baf49dd81555064b':
  Fix crash when an import is missing
2013-11-28 09:09:03 +01:00
Peter Åstrand (astrand) 3b802c08b7 Merge commit '32b0567343aee7753b2b6be1bc1ee9a69657ba26'
* commit '32b0567343aee7753b2b6be1bc1ee9a69657ba26':
  Fix syntax errors in other/websockify.rb
2013-11-28 09:07:52 +01:00
Peter Åstrand (astrand) 972b30ddc2 Merge commit '0e5c3ecfda3b1506b41412052db75d84df2b4ae7'
* commit '0e5c3ecfda3b1506b41412052db75d84df2b4ae7':
  Handle SIGCHLD properly for multiprocessing
2013-11-28 09:07:41 +01:00
Peter Åstrand (astrand) f58b49fa08 Merge commit 'a61ae52610642ae58e914dda705df8bb9c8213ec'
* commit 'a61ae52610642ae58e914dda705df8bb9c8213ec':
  fixed 1.8 compatibility bug for OpenSSL::SSL::SSLSocket#read_nonblock vs #readpartial tested in 1.8 and 2.0
  adding SSL support and Ruby1.9 support
2013-11-28 09:07:30 +01:00
Peter Åstrand (astrand) 131f9ea645 Merge commit '477dce6cf86d61b20a394f3cbf3170e60d199658'
* commit '477dce6cf86d61b20a394f3cbf3170e60d199658':
  websocket: use python logging module
  websocket: fix exception statement introduced by comment 903e3f06ee557

Adapted to new standard SocketServer RequestHandler design. For
example, this means that self.i_am_client is not needed.
2013-11-28 09:05:24 +01:00
Peter Åstrand (astrand) cbf05f84fe Merge commit '4459824cc8196ad78fe9258b6c560ad46fe4cd52'
* commit '4459824cc8196ad78fe9258b6c560ad46fe4cd52':
  websocket: do not exit at the middle of process
  websocket: restore signals after processing
  websocket: support SIGTERM as exit signal
2013-11-27 14:49:54 +01:00
Peter Åstrand (astrand) 611da86353 Merge commit 'a7fa97f0e14926cc4433483fcb7581e0b3782140'
* commit 'a7fa97f0e14926cc4433483fcb7581e0b3782140':
  WebSocketProxy: support non path target_cfg
2013-11-27 13:41:00 +01:00
Peter Åstrand (astrand) fb4ac5ae51 Merge commit 'edde5cd0ff6059bddae10c9b9faf0b3e8f388a9e'
* commit 'edde5cd0ff6059bddae10c9b9faf0b3e8f388a9e':
  Fixed wiki reference
2013-11-27 13:38:03 +01:00
Peter Åstrand (astrand) 063c7de783 Merge commit 'bff3c373b32ebf707085e3c677bfad19b44fa054' 2013-11-27 13:34:17 +01:00
Peter Åstrand (astrand) 08d37e0deb Merge commit 'f30ad05c70ab2a43c9078e2f79da40f1dc0c60ec'
* commit 'f30ad05c70ab2a43c9078e2f79da40f1dc0c60ec':
  Fix #97: rebind.so not found when installed
2013-11-27 13:33:30 +01:00
Peter Åstrand (astrand) ff30e5461f Merge commit 'ab389d4e7114d7ddbfd085591d336ea5cc06c00d'
* commit 'ab389d4e7114d7ddbfd085591d336ea5cc06c00d':
  Collect zombie child processes within server loop
2013-11-27 13:30:30 +01:00
Peter Åstrand (astrand) 4071291fa9 Merge commit '264f8fdd7f12bd5b9f6813fb8de81c55b6328d9b'
* commit '264f8fdd7f12bd5b9f6813fb8de81c55b6328d9b':
  Update to version 0.5.1
2013-11-27 13:30:22 +01:00
Peter Åstrand (astrand) 611effd83b Merge commit '36cb8f4676c7b5ff34bd22ad729e00e77efb6f00'
* commit '36cb8f4676c7b5ff34bd22ad729e00e77efb6f00':
  Move javascript websockify files to other/js
2013-11-27 13:30:13 +01:00
Peter Åstrand (astrand) b63d197292 Merge commit '36fcd5784fa0825eedbf31d91bc42c970605ddb4'
* commit '36fcd5784fa0825eedbf31d91bc42c970605ddb4':
  Add package file for websockify.js
2013-11-27 13:30:05 +01:00
Peter Åstrand (astrand) cf901ddac5 Merge commit '46450577c2fb119fc5bf0ac09664f22651a080d0' 2013-11-27 13:29:54 +01:00
Peter Åstrand (astrand) 122985bd67 Merge commit 'd3ba23fa64d79eeb602ff1015ec31014fd8e9b35'
* commit 'd3ba23fa64d79eeb602ff1015ec31014fd8e9b35':
  Update to c0855c6cae of web-socket-js
2013-11-27 13:29:45 +01:00
Peter Åstrand (astrand) 19c8482236 Merge commit '6d27b5d321978586ea1601f757ead73dfba03da7'
* commit '6d27b5d321978586ea1601f757ead73dfba03da7':
  Add 2 arguments to websockify.WSRequestHandler

As of now, only implemented the first command; see #83 for details.
2013-11-27 13:27:38 +01:00
Peter Åstrand (astrand) 33a1bd2337 Merge commit 'b7f255ce0b21dc42189205b1f0e46b4f1d9854f9'
* commit 'b7f255ce0b21dc42189205b1f0e46b4f1d9854f9':
  Clarify messages when optional modules are not found.
2013-11-27 12:27:43 +01:00
Peter Åstrand (astrand) 5f8cb96bab Merge commit '477947ba96a00032ae35ac55fd02a4a5f485497e'
* commit '477947ba96a00032ae35ac55fd02a4a5f485497e':
  Remove wsproxy references. Sync launch.sh from noVNC.
2013-11-27 12:27:31 +01:00
Peter Åstrand (astrand) 6ddfaa86ae Merge commit '33e9a21ce4e38d52f43fe775fb154fc71c09c827'
* commit '33e9a21ce4e38d52f43fe775fb154fc71c09c827':
  Add gimite/web-socket-js submodule for DFSG compliance.
2013-11-27 12:26:53 +01:00
Peter Åstrand (astrand) 4dc7c0da7a Merge commit '2d078e8cd83735dad7d98fadcece652d93e2a037'
* commit '2d078e8cd83735dad7d98fadcece652d93e2a037':
  correctly include include directory in egg.
2013-11-27 11:36:47 +01:00
Joel Martin 34a1b68d79 Clarify ssl module build for old python versions. 2013-11-20 07:30:23 -06:00
Joel Martin a04edfe80f Merge pull request #105 from dosaboy/topic/unit-test-cleanup
Added temp dir for unit test data and cleanup
2013-11-20 05:21:18 -08:00
Edward Hope-Morley 32c1abd5d9 Added temp dir for unit test data and cleanup
Unit test data will now go to a temporary dir that will be deleted
once the test completes. The unit tests also setup a logger which
will persist so that it can be inspected once tests complete.

Also fixes a bug where instance var is missing from decode_hybi()

Co-authored-by: natsume.takashi@lab.ntt.co.jp
2013-11-14 12:38:03 +00:00
Joel Martin a47be21f9f Merge pull request #94 from dosaboy/topic/add-unit-tests
Added unit tests for websocket and websocketproxy
2013-10-29 09:44:48 -07:00
Edward Hope-Morley 5e0ff7d855 Added unit tests for websocket and websocketproxy
To run the unit tests just run tox from the top
level directory which will try to run unit tests
for most versions of python. Requires tox to be
installed. To run tox for a specifice env, run
tox -e<env> e.g. for python 2.7 run 'tox -epy27'.

Co-authored-by: natsume.takashi@lab.ntt.co.jp
2013-10-29 16:19:39 +00:00
Joel Martin c3acdc2e38 Merge pull request #93 from dosaboy/topic/set-keepalive-options
Adds optional TCP_KEEPALIVE to WebSocketServer
2013-10-29 08:18:53 -07:00
Joel Martin 13c99bcf05 Fix search path construction in tests.
This way the tests can be run directly from within the tests directory
and they might also have a chance of running on Windows (where the
path separator is different).
2013-10-29 09:41:26 -05:00
Samuel b4e0b534d5 Merge pull request #104 from stevschmid/patch-1
Fix crash when module is missing
2013-10-24 04:22:44 -07:00
Steven Schmid be4119f84f Fix crash when an import is missing
self.msg is not available when checking the imports.

I had the problem on a host where numpy is missing (python 2.7.3).
2013-10-24 11:42:49 +02:00
Solly 32b0567343 Merge pull request #103 from dellsystem/master
Fix syntax errors in other/websockify.rb
2013-10-21 18:29:45 -07:00
dellsystem 82fe329129 Fix syntax errors in other/websockify.rb 2013-10-21 20:59:16 -04:00
Solly 0e5c3ecfda Merge pull request #102 from DirectXMan12/master
Handle SIGCHLD properly for multiprocessing (fixes #101)
2013-10-21 17:16:09 -07:00
Solly Ross 53f1f1989e Handle SIGCHLD properly for multiprocessing
This commit should fix #101 by enabling a special SIGCHLD
handler for when multiprocessing is in use.  The handler
simply calls `multiprocessing.active_children()` (which in
turn calls `_cleanup()`) upon receiving a SIGCHLD.  Now,
the `fallback_SIGCHLD` is only called when `multiprocessing`
is not in use.  See also #95.
2013-10-21 16:52:42 -04:00
Edward Hope-Morley 081046b6cd Adds optional TCP_KEEPALIVE to WebSocketServer
TCP_KEEPALIVE is now enabled by default. Settings for
KEEPCNT, KEEPINTVL and KEEPIDLE can be supplied when
creating WebSocketServer and KEEPALIVE can also be
disabled if required.

Also adds new unit test for testing.

Co-authored-by: natsume.takashi@lab.ntt.co.jp
2013-10-16 11:24:21 +01:00
Joel Martin a61ae52610 Merge pull request #86 from chrislee35/master
OpenSSL Support for Ruby Module of Websockify
2013-10-15 10:32:57 -07:00
Joel Martin 477dce6cf8 Merge pull request #100 from alonbl/log
websocket: use python logging module
2013-10-15 09:41:35 -07:00
Alon Bar-Lev 8a0a47223d websocket: use python logging module
WebSocketServer is a library module, as such, it cannot assume it can
write output to process stdout.

Python logging module is designed in order to allow subscribers to
handle the output out of modules. It is simple and generic mechanism to
separate between data producer and data handling.

Python logging API also has the nature of log level, so the verbose
parameter can probably be obsoleted in favor of logging level. And of
course the logging API has built in support for exception tracebacks, no
need for manual format.

Per upstream request a wrapper is created around python logging to
enable shorter statements and optional replacement.

Add --traffic parameter for traffic specific debug, this is required as
it uses direct unformatted stdout output.

Signed-off-by: Alon Bar-Lev <alon.barlev@gmail.com>
2013-10-15 19:18:17 +03:00
Alon Bar-Lev 1f798214de websocket: fix exception statement introduced by comment 903e3f06ee557
Signed-off-by: Alon Bar-Lev <alon.barlev@gmail.com>
2013-10-15 19:18:17 +03:00
Joel Martin 4459824cc8 Merge pull request #98 from alonbl/apicleanup
Minor API cleanups
2013-10-14 13:12:40 -07:00
Alon Bar-Lev c2a40d6900 websocket: do not exit at the middle of process
WebSocketServer is a library module, as such it should not exit process
but return from a method, allowing the caller to execute process show
down.

Signed-off-by: Alon Bar-Lev <alon.barlev@gmail.com>
2013-10-14 22:17:19 +03:00
Joel Martin a7fa97f0e1 Merge pull request #99 from alonbl/targetconfig
WebSocketProxy: support non path target_cfg
2013-10-14 11:38:05 -07:00
Alon Bar-Lev 1190fe1204 websocket: restore signals after processing
WebSocketServer is a library module, as such it should try to restore state
after processing, to allow caller to resume normal operation.

Signed-off-by: Alon Bar-Lev <alon.barlev@gmail.com>
2013-10-14 21:13:11 +03:00
Alon Bar-Lev 7026e26d68 websocket: support SIGTERM as exit signal
Similar to SIGINT that is already supported, support SIGTERM in daemon
and non daemon modes.

Signed-off-by: Alon Bar-Lev <alon.barlev@gmail.com>
2013-10-14 21:01:44 +03:00
Alon Bar-Lev 37e40a78f2 WebSocketProxy: support non path target_cfg
The WebSocketProxy class is usable for creating derived applications
with different logic, especially for the target validation.

Current code assumes that target is a path while in other implementation
it can be object that is loaded at initialization.

This change moves the conversion to absolute path into main function, so
that the WebSocketProxy class will not make that assumption.

Signed-off-by: Alon Bar-Lev <alon.barlev@gmail.com>
2013-10-14 20:31:24 +03:00
Samuel edde5cd0ff Merge pull request #91 from MartinF/master
Fixed wiki reference
2013-10-09 06:50:08 -07:00
Joel Martin bff3c373b3 Merge pull request #96 from DirectXMan12/master
Enable Process Reaping in All Conditions
2013-09-27 06:05:55 -07:00
Joel Martin f30ad05c70 Fix #97: rebind.so not found when installed
This should fix the upstream Debian bug:
http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=719889
2013-09-27 07:42:57 -05:00
directxman12 354dd6b0a2 Enable Process Reaping in All Conditions
Process reaping via the SIGCHLD handler is now enabled in all
circumstances, instead of just when os.fork is being used.

Fixes #95
2013-09-20 14:12:35 -04:00
Martin From e06de83295 Fixed wiki reference 2013-09-09 11:32:57 +02:00
Joel Martin ab389d4e71 Merge pull request #85 from dillaman/master
Collect zombie child processes within server loop
2013-07-02 10:55:53 -07:00
chrislee35 eee946d2cf fixed 1.8 compatibility bug for OpenSSL::SSL::SSLSocket#read_nonblock vs #readpartial
tested in 1.8 and 2.0
2013-07-02 22:16:01 +09:00
chrislee35 73af324a3a adding SSL support and Ruby1.9 support 2013-07-02 21:38:22 +09:00
Jason Dillaman 832118e61a Collect zombie child processes within server loop 2013-06-28 15:22:35 -04:00
Joel Martin 264f8fdd7f Update to version 0.5.1
*** NOTE ***

This version of websockify no longer supports the old Hixie protocol.
2013-06-27 16:35:54 -05:00
Joel Martin 36cb8f4676 Move javascript websockify files to other/js 2013-06-27 16:29:17 -05:00
Joel Martin 36fcd5784f Add package file for websockify.js 2013-06-27 16:29:17 -05:00
Joel Martin 46450577c2 Use upstream einaros/ws 0.4.27 with sub-protocol support.
Also, some connection error handling.
2013-06-27 16:29:17 -05:00
Joel Martin d3ba23fa64 Update to c0855c6cae of web-socket-js
Update both the submodule and the swf build. The submodule now
contains the unobfuscated source for swfobject.js which should make
websockify more DFSG compliant.
2013-06-27 16:29:17 -05:00
Joel Martin 6d27b5d321 Merge pull request #84 from nttdatainc-openstackers/master
Fix for issue #83
2013-06-27 14:01:07 -07:00
NTT Data OpenStackers 888e75a8fb Add 2 arguments to websockify.WSRequestHandler
This patch adds 2 arguments to websockify.WSRequestHandler for security:

* file_only: returns 404 response if non-file contents are requested.
             Required to disable directory listing.

* no_parent: returns 403 response if contents out of the web root are
             requested. Required to disable directory traversal.
2013-06-24 06:09:01 -07:00
Joel Martin b7f255ce0b Clarify messages when optional modules are not found. 2013-04-19 17:14:20 -05:00
Joel Martin 477947ba96 Remove wsproxy references. Sync launch.sh from noVNC. 2013-04-15 12:22:08 -05:00
Joel Martin 33e9a21ce4 Add gimite/web-socket-js submodule for DFSG compliance. 2013-04-12 08:24:07 -05:00
Joel Martin 2d078e8cd8 Merge pull request #76 from SlapOS/include
correctly include include directory in egg.
2013-04-03 09:44:37 -07:00
Cédric de Saint Martin d6d960dbe5 correctly include include directory in egg. 2013-04-03 12:12:37 +02:00
Peter Åstrand (astrand) ed109d7ec8 Fix Python3 compatibility when using --libserver. 2013-03-20 15:09:58 +01:00
Peter Åstrand (astrand) bc917863e0 Improved class documentation. 2013-03-20 13:30:16 +01:00
Peter Åstrand (astrand) e964c1edff Let our ProxyRequestHandler be default. This allows you to inherit
from WebSocketProxy without having to specify handler class.
2013-03-20 11:34:46 +01:00
Peter Åstrand (astrand) f5e42ff6f4 Move WebSocketProxy class so that it is defined after the
requesthandler. Removed comments about above/below which does not make
sense any longer. No functional changes.
2013-03-20 11:30:38 +01:00
Peter Åstrand (astrand) f594d70daf Removed unused import of SimpleHTTPRequestHandler. 2013-03-20 11:00:34 +01:00
Peter Åstrand (astrand) d0608a63b6 Make echo.py and load.py work again, after the refactoring of
websocket.py:

* With echo.py, which doesn't need any server configuration, we can
  just switch over our application class to inherit from
  WebSocketRequestHandler instead of WebSocketServer. Also, need to
  use the new method name new_websocket_client.

* With load.py, since we have the "delay" configuration, we need both
  a server class and a request handler.

Note that for both tests, I've removed the raising of
self.EClose(closed). This is incorrect. First of all, it's described
as "An exception before the WebSocket connection was established", so
not suitable for our case. Second, it will cause send_close to be
called twice. Finally, self.EClose is now in the WebSocketServer
class, and not a member of the request handler.
2013-03-20 10:03:04 +01:00
Peter Åstrand (astrand) 09f3ec7125 Rename self.client to self.request, ie adapt to:
>commit b9e1295f7a
>    Prepare for solving https://github.com/kanaka/websockify/issues/71:
>
>    Rename self.client to self.request, since this is what standard
>    SocketServer request handlers are using.
2013-03-20 09:03:18 +01:00
Peter Åstrand (astrand) 95593ac4bf Merge branch 'master' of github.com:astrand/websockify 2013-03-18 14:59:03 +01:00
Peter Åstrand (astrand) 1eecc7b17a Merge remote branch 'upstream/master' 2013-03-18 14:50:46 +01:00
Peter Åstrand (astrand) b05b773bd7 Corrected last commit. 2013-03-18 13:25:53 +01:00
Peter Åstrand (astrand) debc926612 Renamed CustomProxyServer to WebSocketProxy; this was the earlier name.
Also, call the server instance "server", not "httpd", even when using
LibProxyServer.
2013-03-18 13:22:48 +01:00
Peter Åstrand (astrand) 70eb75a3e6 Fix error with modern Python 2.X versions:
TypeError: exceptions must be old-style classes or derived from
BaseException, not str

Thus, we are not allowed to raise a string. Raise Exception instead.
2013-03-18 12:04:50 +01:00
Joel Martin 903198a724 tests: use new module path and remove Hixie code. 2013-03-14 12:24:58 -05:00
Peter Åstrand (astrand) 7b3dd8a6f5 Try to solve https://github.com/kanaka/websockify/issues/71 by
refactoring. Basically, we are dividing WebSocketServer into two
classes: One request handler following the SocketServer Requesthandler
API, and one optional server engine. The standard Python SocketServer
engine can also be used.

websocketproxy.py has been updated to match the API change. I've also
added a new option --libserver in order to use the Python built in
server instead.

I've done a lot of testing with the new code. This includes: verbose,
daemon, run-once, timeout, idle-timeout, ssl, web, libserver. I've
tested both Python 2 and 3. I've also tested websocket.py in another
external service.

Code details follows:

* The new request handler class is called WebSocketRequestHandler,
  inheriting SimpleHTTPRequestHandler.

* The service engine is called WebSocketServer, just like before.

* do_websocket_handshake: Using send_header() etc, instead of manually
  sending HTTP response.

* A new method called handle_websocket() upgrades the connection to
  WebSocket, if requested. Otherwise, it returns False. A typical
  application use is:

    def do_GET(self):
        if not self.handle_websocket():
	   # handle normal requests

* new_client has been renamed to new_websocket_client, in order to
  have a better name in the SocketServer/HTTPServer request handler
  hierarchy.

* Note that in the request handler, configuration variables must be
  provided by the "server" object, ie self.server.target_host.
2013-03-14 16:07:40 +01:00
Peter Åstrand (astrand) 208f83b9a2 Prepare for fixing https://github.com/kanaka/websockify/issues/71:
* Move traffic_legend.

* Since websocket.WebSocketServer.socket is static, don't call it with
  self.socket.
2013-03-14 16:00:11 +01:00
Peter Åstrand (astrand) 4e3388964a Prepare for fixing https://github.com/kanaka/websockify/issues/71:
Move around functions and methods, so that connection-related and
server-related stuff are close together.

This patch just moves things around - it does not change anything at
all. This can be verified with:

git diff websocket.py | grep ^- | cut -c 2- | sort > removed
git diff websocket.py | grep ^+ | cut -c 2- | sort > added
diff -u removed added
2013-03-14 15:50:49 +01:00
Peter Åstrand (astrand) b9e1295f7a Prepare for solving https://github.com/kanaka/websockify/issues/71:
Rename self.client to self.request, since this is what standard
SocketServer request handlers are using.
2013-03-14 15:23:44 +01:00
Joel Martin d3865688c8 README: no longer supporting Hixie.
NOTE: Hixie support is in version 0.4.X. If necessary, I will branch
and apply critical fixes release a new 0.4.X tagged version.
2013-03-12 13:54:11 -05:00
Joel Martin 5a726c2e4d Merge pull request #70 from astrand/master
Remove support for old Hixie protocols
2013-03-12 11:52:30 -07:00
Joel Martin db6a7e3e28 Update to version 0.4.1
*** IMPORTANT NOTE ***

0.4.X is the last minor version to support the Hixie protocol. 0.5.0
will drop the Hixie protocol support. The latest released version of
all major browsers (and web-socket-js) support the IETF 6455 protocol.

- Other changes: add 'include/' sub-dir to source distribution and to
  installed packaged.
2013-03-12 13:46:45 -05:00
Joel Martin d9aedfe7d3 Update to version 0.4.0
*** IMPORTANT NOTE ***

This is the last minor version to support the Hixie protocol. I may do
bug fixes (e.g. 0.4.1) but 0.5.0 will drop the Hixie protocol support.
The latest released version of all major browsers (and web-socket-js)
support the IETF 6455 protocol.

- Other changes: updating TODO and release process notes.
2013-03-12 13:10:53 -05:00
Peter Åstrand (astrand) b2fe57c950 Remove support for old Hixie protocols.
Hybi protocols 7 and 8 are still supported, in addition to
protocol 13 -  RFC 6455.
2013-03-04 09:38:29 +01:00
Joel Martin 805026360e Use Buffer base64 support instead of pkrumins/node-base64 2013-02-19 13:12:10 -06:00
Joel Martin 3d37d21b5f Update to version 0.3.0 and upload to pypi.
Update to 0.3.0 and document uploading to pypi.python.org.

Install thus:
    sudo pip install websockify
2013-01-15 11:49:08 -06:00
Joel Martin c33f0b52e7 In Opera 12.10, set binaryType earlier.
Otherwise, the first message received may be blob depending on timing.
2012-11-14 12:24:08 -05:00
Joel Martin 1d795c0643 Pull include/util.js from noVNC.
Pull version 51562999c7 load_scripts fixes.
2012-11-01 11:07:26 -05:00
Joel Martin c00c0eed1a websocket.py: close lsock on stop.
If WebSocketServer is used as a library with run_once or timeout, then
cleanup the socket listener socket so that when start_server returns
(due to run_once or timeout) then port is freed up.
2012-10-31 12:04:16 -05:00
Joel Martin 47fb367486 websocketproxy.py: fix for python2.4
Thanks to https://github.com/WhiteRavenTechnology for catching this.
2012-10-30 08:34:47 -05:00
Joel Martin 5e16b38524 websocketproxy.py: put client socket handling first.
Should at least mostly address this issue:
https://github.com/kanaka/websockify/issues/63

The problem is that the target in the test case often immediately
closed the target after sending the data. In this case the last data
received from the target is never sent to the client because the
client is not in the list of sockets being selected against (because
it is only added if their is pending data). By moving the client
conditionals first, we give the client socket a chance to be sent data
before the target is detected as close and we terminate the loop.
2012-10-29 18:12:54 -05:00
Joel Martin c728f43c63 README.md: clarify binary vs base64 negotiation. 2012-10-29 17:17:56 -05:00
Joel Martin d1458d0063 websocketproxy.py: better missing token exception. 2012-10-29 17:05:23 -05:00
Joel Martin 66d772a6bc Ignore other/node_modules directory (node.js modules). 2012-10-29 17:04:39 -05:00
Joel Martin a670af376e websockify.js: add encrypted HTTPS/WSS support.
This works a bit differently than python websockify implementation
since the server either runs in HTTP or in HTTPS and both web and
websocket servers only support the same mode. Specifying the --cert
parameter activates encrypted HTTPS/WSS mode.
2012-10-29 16:59:46 -05:00
Joel Martin 16691395e0 websock.js: use iteration to receive binary data
Instead of using apply with the Uint8Array to push the data onto the
receive queue, iterate through the binary data and push it an element
at a time. Apparently, doing an apply with a very large binary array
can blow the stack. Performance-wise this seems equivalent in Chrome
22 and Firefox 16.
2012-10-26 18:01:35 -05:00
Joel Martin 3018cf8c1a websockify.js: executable, fix usage statement. 2012-10-26 18:01:05 -05:00
Joel Martin 6a126405bd websockify.js: binary data, better logs and err handling.
This version requires a patched version of einaros/ws that can be
found here: https://github.com/kanaka/ws You can use the patched
version like this:

    cd websockify/other
    git clone https://github.com/kanaka/ws
    npm link ./ws

Once the upstream 'ws' module supports subprotocol negotiation then
this will no longer be necessary.

Changes:
- Adds support for binary data and subprotocol negotiation of 'base64'
  vs 'binary' with 'binary' preferred if the client offers it.
- Add client address to log messages.
- Close the target when the client closes.
- Catch errors when we try and send to a client that is no longer
  connected.
2012-10-26 16:08:47 -05:00
Joel Martin ee2f269c06 websocket.py: fix recording and refactor unmask.
Fix recording so that it records the actual payload bytes sent to the
client.  This means that if the client and server and using base64
encoding then the captured data will still be base64 encoded. However,
data received from the client is unmasked when recorded. Note that
this is not done efficiently; when recording, client data is unmasked
twice (once for sending on to the target and once for recording). This
could be made more efficient but that would require a refactor of how
frame reception and unmasking works and recording is not considered
a performance sensitive mode.
2012-10-17 11:59:03 -05:00
Joel Martin 780cb8a9e6 util.js, websock.js: sync with noVNC - dynamic script loading.
Sync with noVNC ad29479ca90f9. Use new dynamic script loading
mechanism in util.js.

window.onscriptsload is called when dynamic scripts have loaded
(window.onload fires too early in IE 9).
2012-10-17 11:59:03 -05:00
Joel Martin 388d9573fd Merge pull request #65 from lovelysystems/master
updated version in setup.py
2012-10-15 14:04:27 -07:00
Joel Martin 578dba1987 include/*util.js: update to versions from noVNC. 2012-10-15 16:02:38 -05:00
Joel Martin 124c9a7d88 Change include/websock.js (and deps) to MPL 2.0 license.
The MPL 2.0 license is a "file-level" copyleft license vs the
"project-level" nature of the L/GPL. The intention of the websock.js
file has always been that it should be easy to incorporate into
existing projects and sites whether free/open or
proprietary/commercial. The MPL 2.0 is designed for this sort of
combination project but still requires that any distributed
modifications to noVNC source files must also be published under the
same license.

In addition, the MPL 2.0 allows the code to be used in L/GPL projects
(the secondary license clause). This means that any projects that are
already incorporating noVNC should not be impacted by this change and
in fact it should clarify the licensing situation (the exact
application of the L/GPL to web applications and interpreted code is
somewhat ambiguous).

The dependencies on include/websock.js are also updated to MPL 2.0
including util.js and webutil.js. The base64.js has been updated to
the MPL 2.0 licensed version from Mozilla.

The websockify python code (and other implementations) remain under
a LGPLv3 license.
2012-10-15 16:02:38 -05:00
Jodok Batlogg e53fa10397 updated version 2012-10-15 22:06:50 +02:00
Joel Martin 1295668abb Merge pull request #64 from vishvananda/fix-import
In websockify/__init__.py import everything from websocketproxy and websocket
2012-09-26 07:35:05 -07:00
Vishvananda Ishaya 880257a431 Import everything in websocketproxy and websocket
Old users of the websockify library used websockify.WebSocketProxy
The refactor into a module unneccessarily broke this import. The
current imports in __init__.py don't actually do anything so this
patch changes the import to import everything so that the old import
still works. This appears to be the original intention of the existing
import statements.
2012-09-25 22:24:10 -07:00
Joel Martin 8b3125bcf3 other/websockify.js: arg cleanup, remove deprecated call.
Change deprecated path.exists call to fs.exists.

Confirmed that this runs with node v0.8.9
2012-09-21 08:19:40 -05:00
Joel Martin 471b504799 Merge branch 'master' of github.com:kanaka/websockify 2012-09-21 07:32:54 -05:00
Joel Martin b713acbeff Merge pull request #59 from dosht/master
--unix-target option breaks argument sanity check
2012-09-21 05:31:47 -07:00
Joel Martin ff736e9ad3 Fix issue #60: not all arguments converted
https://github.com/kanaka/websockify/issues/60

String formatting issue with wrapped cmds.
2012-09-21 07:28:08 -05:00
Joel Martin 384c2772fb Merge pull request #61 from vishvananda/fix-popen
Reset SIGPIPE handler when calling Popen

References:

http://www.chiark.greenend.org.uk/ucgi/~cjwatson/blosxom/2009-07-02-python-sigpipe.html

http://bugs.python.org/issue1615376

http://bugs.python.org/issue1652
2012-09-21 05:24:50 -07:00
Joel Martin e6d8d8f242 Gracefully handle errors when popping kwargs.
https://github.com/kanaka/websockify/pull/53
2012-09-21 07:10:34 -05:00
Vishvananda Ishaya ca8efbf657 Reset SIGPIPE handler when calling Popen
Python ignores SIGPIPE on startup, because it prefers to check every
write and raise an IOError exception rather than taking the signal. Most
Unix subprocesses don't expect to work this way. This patch (adapted
from Colin Watson's post at http://tinyurl.com/2a7mzh5) sets SIGPIPE
back to the default action.
2012-09-20 07:46:04 -07:00
mostafa sameh eb6d4e183b Fix --unix-target option 2012-09-18 09:20:39 +02:00
Joel Martin 6d9deda9c5 Pull upstream web-socket-js with IETF 6455 support.
Pull in web-socket-js 7677e7a954.

The biggest change of note is that this updates web-socket-js to IETF
6455 rather than the previous Hixie protocol.
2012-09-17 16:50:46 -05:00
Joel Martin 96890fab97 include/websock.js: cleanup and fix protocol list check.
If a protocol list is specified and we don't support binary WebSockets
then strip binary from the list and check the list to make sure there
is still an option left.
2012-09-17 16:49:36 -05:00
Joel Martin c0d23e27e4 Refactor into python modules: websocket, websocketproxy
Make websockify subdirectory and move websocket.py ->
websockify/websocket.py and websockify ->
websockify/websocketproxy.py. Create a ./run script that launches
websockify as before (unfortunately can't have a websockify script at
the same level since this is now a directory). Make websockify.py
a symlink to ./run. Once the package is installed, the main launch
script will be /usr/bin/websockify.

This makes it easier to package up websockify as a python module.
setup.py should now properly install websockify as a module.

Note that to include the base websocket module/class you will now do:

    import websockify.websocket
    #OR
    from websockify.websocket import WebSocketServer

To import the full websocket proxy functionality:

    import websockify.websocketproxy
    #OR
    from websockify.websocket import WebSocketProxy

This will also help with startup speed slightly because the code in
websocketproxy will now be byte compiled since it is no longer in the
main invocation script.
2012-09-17 14:06:51 -05:00
Joel Martin 2d2798954e websockify version 0.2.0 2012-09-17 12:56:34 -05:00
Joel Martin 44e5fa0b82 Merge pull request #56 from AricStewart/master
Implement --idle-timeout for issue #55
2012-09-06 20:02:04 -07:00
Aric Stewart 82cb31f3b6 change --idle-timeout to reset the idle timeout when active 2012-08-31 10:55:24 -05:00
Aric Stewart 9348dd5208 Implement option --idle-timeout
server exits after TIMEOUT seconds if there are no active connections
2012-08-31 09:24:09 -05:00
Joel Martin 17175afd73 websock.js: make protocols parameter of open().
If no protocols are selected then defaults to ['binary', 'base64'] (or
just 'base64' if there is not full binary type support.

Checks to make sure binary types are fully supported and throws an
exception if they are requested but not supported.
2012-08-16 13:28:28 -05:00
Joel Martin 53b074e8e7 websock.js: simplify rQshiftStr with apply(). 2012-08-16 13:27:50 -05:00
Joel Martin 068065e465 Simpler (but working) binary support.
Instead of trying to handle the receive queue as a typed array, just
replace the base64 encode/decode with conversion from/to typed arrays
and handle the receive and send queue as before (plain Javascript
arrays).

There is a lot of opportunity here for optimization of course, but for
now it's more important that it work properly.
2012-08-16 12:21:21 -05:00
Joel Martin 376872d993 Use WebSocket binary data (no base64 enc/dec) if available.
If typed arrays (arraybuffers) are available and the WebSocket
implementation supports them, then send and receive direct binary
frames and skip base64 encode/decode. Otherwise we just fallback to
the current method of sending base64 encoded strings (with a couple of
extra checks for mode in the send/receive path).

The check for binaryType support in WebSocket is a collosal hack right
now due to the fact that the 'binaryType' property doesn't exist on
the WebSocket prototype. So we have to create a connection to
a localhost port in order to test.

A potentionally big performance boost could probably be achieved by
re-using a larger typed array for storing the data instead of creating
a typed array every time we receive a message.
2012-08-14 15:19:38 -05:00
Joel Martin f55362ff07 websock.js: jslint comments, debug comments, copyright date 2012-08-14 15:18:14 -05:00
Joel Martin 36bdb09630 More verbosity about who closed the connection. 2012-08-14 15:14:00 -05:00
Joel Martin d575e571fd Fix split out handshake parsing for Hixie.
Need the scheme to be accessible when constructing the response for
Hixie clients.
2012-08-14 15:12:48 -05:00
Joel Martin 00e9d3bf29 websockify.rb: correct comment, no SSL support yet. 2012-07-24 09:31:26 -05:00
Joel Martin 26e8095244 websockify: rename config opt, fix config dir reading 2012-07-13 13:17:56 -05:00
Joel Martin e4b9d510f1 websocket.py: split out handshake parsing.
This makes it easier to use the websocket code in a WSGI script in the
future.
2012-07-13 13:09:32 -05:00
Joel Martin 65e96176cb websockify: change cfg file syntax and clean up parsing.
Config file syntax is now like this:

----------------------
    # Comments and blank lines are allow
    token1: host1:port1

    token2: host2:port2
----------------------
2012-07-12 19:34:27 -05:00
Joel Martin 52beba8695 Move target-list processing to websockify.
websocket.py has no concept of target/proxy so any target processing
should happen in websockify itself.

Also:

- remove URL parsing imports from websocket.py since they are not
  needed with SimpleHTTPRequestHandler doing the parsing.

- read the absolute path of the target_list file on startup since the
  --web option will change directories if set.
2012-07-12 19:10:12 -05:00
Hector Sanjuan e17e1158d8 Enable multiple targets in websockify by passing a target-list configuration file.
The --target-list option is used to pass a configuration file on websockify start.

This file contains entries in the form host:port:token, one per line.

When a new connection is open (from noVNC for example), the url should look like:

ws://websockify_host:websockify_port/?token=ABCD

The token is then extracted and checked against the entries in the configuration file.

When the token matches, the connection is proxied to the host:port indicated in the file.

If the configuration file is a folder, then all the entries from files in it are read.
2012-07-11 16:00:13 +02:00
Joel Martin 2a8df6327e Merge pull request #49 from libricoleur/master
Better support of IPv6
2012-06-26 07:40:38 -07:00
Alexandre Sicard 67d4c17516 Allow preference of IPv6 for source_addr
Add the option "-6, --prefer-ipv6". When set, the 'prefer_ipv6' flag in
websocket.py is used so that 'source_addr' is resolved to IPv6 if
available. If 'source_addr' is not set, binds to [::].
2012-06-26 13:57:50 +02:00
Alexandre Sicard 1f5b492e10 Support IPv6 brackets notation
Parse square brackets-enclosed IPv6 for 'source_addr' and 'target_addr'
parameters.
2012-06-26 13:55:19 +02:00
Joel Martin cb925eb486 doc/websockify.1: add man page for websockify command.
Mostly it is based on the project README.md but with some tweaks and
extra content removed.

Thanks for Adam Young <ayoung@redhat.com> for the original version of
this.

Also a decent man format reference is here:
http://www.fnal.gov/docs/products/ups/ReferenceManual/html/manpages.html
2012-06-22 18:40:11 -05:00
Joel Martin e295098330 Fix wrap mode when used with --web option.
- The --web option changes directory so the wrap mode needs to get an
  absolute path to the rebinder.
- Also, use long instead of int in rebind.c so avoid compile warnings.
2012-05-31 09:20:01 -05:00
Joel Martin cddc1613ff Fixup bugs from merge (pull #46).
- Rename unix socket option to '--unix-target' to be consistent with
  '--ssl-target' which is an analogous switch.
- Fix normal socket target mode which was broken after merge.
- Normalize/fix output for SSL, unix socket and wrap command modes.
2012-05-31 09:17:51 -05:00
Joel Martin 233b622e47 Merge pull request #46 from cloud9ers/master
Adding support for unix sockets as target socket.
2012-05-30 07:22:29 -07:00
Karim Allah Ahmed c7ba8c7826 Merge with kanaka's mainstream master branch 2012-05-28 13:09:07 +02:00
Joel Martin 89d2c92474 Move SSL target support into websocket.py.
This is cleanup related to:
https://github.com/kanaka/websockify/pull/45
2012-05-23 09:20:08 -05:00
Joel Martin d24f474362 Merge pull request #45 from d4nshields/master
feature from issue #8: Support connecting to SSL/TLS target socket
2012-05-23 06:47:14 -07:00
Karim Allah Ahmed f3054df53a Adding TCP_NODELAY to the source sockets 2012-05-22 16:49:00 +02:00
Karim Allah Ahmed c8018f29c9 Adding support for proxying from a unix socket 2012-05-22 16:09:07 +02:00
Daniel Shields 763d2d7c1c Feature: target_host is wrapped in SSL using --ssl-target option 2012-05-20 13:58:45 -04:00
Joel Martin e1c206b315 Release version 0.1.0 2012-05-11 12:12:50 -05:00
Joel Martin 63600bf422 Fix return code when client closes. 2012-05-10 22:00:27 -05:00
Joel Martin 19a9730744 Make CClose exception work in python 2.4.
Fixes https://github.com/kanaka/websockify/issues/41
2012-05-10 08:04:30 -05:00
Joel Martin 7a4dbad3e8 Fix latency test.
For echo/latency tests default to current host:port or URL.
2012-04-25 13:44:37 -05:00
Joel Martin 9a88f1800c Better close code/reason handling. 2012-04-25 13:44:01 -05:00
Joel Martin 37c0c80a93 C websockify: add --run-once option. 2012-04-13 10:36:16 -05:00
Joel Martin aef7ab3a57 Clean socket shutdown in C version too.
Related to https://github.com/kanaka/noVNC/issues/58 (supporting Apple
Remote Desktop).
2012-03-23 12:17:50 -05:00
Joel Martin 27c3da1908 Fix feature matrix link and clarify paragraph. 2012-02-23 17:45:27 -06:00
Joel Martin 9fcd92c39a Remove copy of kumina implementation.
The canonical location is https://github.com/kumina/wsproxy

There are now several external implementations of Websockify that
I link to from
https://github.com/kanaka/websockify/wiki/Feature_Matrix
2012-02-23 17:18:10 -06:00
Joel Martin 7ea468b5d7 Node impl to use einaros/ws and support HyBi.
Also adds web serving functionality and Flash policy service.
2012-02-23 17:06:35 -06:00
Joel Martin 9decfe1c95 Don't swallow SSL EOF errors. 2012-02-20 16:34:30 -06:00
Joel Martin cb839e85c4 Pull base64.js from noVNC.
Better illegal character debug output.
2012-02-20 15:49:18 -06:00
Joel Martin 31716a7265 Merge pull request #31 from SlapOS/master
Eggify websockify
2012-02-18 12:53:04 -08:00
Cédric de Saint Martin 301f3ae580 Eggify websockify 2012-02-18 09:43:12 +01:00
Joel Martin db17151941 Sync include/webutil.js with noVNC. 2012-02-14 17:37:01 -06:00
Joel Martin 7d44853da7 Pull include/util.js from noVNC. Add map to arrays for IE9.
IE9 still doesn't support [].map() so add it to the prototype in
include/util.js.
2012-02-14 07:51:44 -06:00
Joel Martin b405cdae7b Rename client.html to simple.html 2012-02-09 17:47:22 -06:00
Joel Martin e02b698015 Add simple client: tests/client.html. 2012-02-09 17:46:47 -06:00
Joel Martin bea32aebed Handle partial HyBi client frames. Cleanup buffer names.
Significant refactor of decode_hybi() and use of it in do_proxy().
2012-02-03 11:55:03 -06:00
Joel Martin bc1ea59867 Fix response to empty close frame. 2012-02-02 11:06:19 -06:00
Joel Martin b76c357f3f Fix --ssl-only option. 2012-02-02 08:11:06 -06:00
Joel Martin 8e95f18f99 Add openssl cert generation procedure to README. 2012-02-02 07:05:55 -06:00
Joel Martin 27ec5cff89 Remove more wswrapper Makefile references. 2012-02-02 06:51:39 -06:00
Joel Martin e2497313f5 Remove pointless md5_test.c file. 2012-02-01 19:17:56 -06:00
Joel Martin 04b3b2057c HyBi/IETF 6455 support to C websockify.
It's probably broken and it's definitely still messy in several ways,
but basic tests work with Chrome.

Several other C websockify cleanups:

- Remove most of the non-thread safe global variable usage (still
  a little bit that could be fixed so that threading would be easier).

- Remove wswrapper. It is unmaintained, out of date, and never worked
  well anyways (since it really needed a way to do asynchronous queued
  work but it was running in another process context making that
  hard).

- Use md5 routines from openssl.

- Remove md5.c and md5.h since no longer needed.

Thanks to https://github.com/dew111 for spurring me on to get this
done by writing code. I didn't end up using much his forked code, but
having something there goaded me enough to just get it working.
2012-02-01 19:10:39 -06:00
Joel Martin b2940c035f Show SSL error string. 2012-01-31 15:20:57 -06:00
Joel Martin 9ed4a17d70 Move alternate implementation data to wiki. 2012-01-30 15:00:58 -06:00
Joel Martin 6549c04fae Ignore clojure/lein artifacts. 2012-01-30 13:40:55 -06:00
Joel Martin 2c053f349c Clojure websockify: -main and command line args.
Can now be launched like so:

lein run websockify --web ../../noVNC/ 6080 localhost:5901
2012-01-30 13:38:18 -06:00
Joel Martin f2f838f7e2 Split generic websocket code out from websockify.
Generic TCP client and Websocket server code is now split out from the
websockify specific code.
2012-01-27 16:01:17 -06:00
Joel Martin 3278905ead Better error handling in Clojure Websockify.
Also, disable verbose debug.
2012-01-27 15:37:35 -06:00
Joel Martin a5d4fe1d18 Working vesrion Clojure Websockify.
Still needs some cleanup related to cleaning up client and target
connections.
2012-01-27 15:14:45 -06:00
Joel Martin 297a818066 Working Clojure Netty client code. 2012-01-27 13:11:38 -06:00
Joel Martin 9aa2844856 Switch to Jetty for Clojure WebSocket support.
This current code accepts WebSocket connections and can send data back
and forth.
2012-01-26 15:36:58 -06:00
Joel Martin 0664584843 Clojure Websockify using Aleph - broken. 2012-01-26 15:31:21 -06:00
Joel Martin 3aedd64765 Add websockify.py symlink for Windows support. 2012-01-05 12:00:22 -06:00
Joel Martin 7e6550806f Switch tests/echo.html to use websock.js. 2012-01-03 07:41:54 -07:00
Joel Martin e02c62932b README: websockify.rb support HyBi. 2011-12-23 10:59:56 -07:00
Joel Martin d5c94db054 Support python 3 with SSL/TLS connections.
Need to detect leading TLS/SSL character by number too for python 3.
2011-12-15 15:35:11 -06:00
Joel Martin 008a5118e7 Add commented out web-socket-js Flash debug var. 2011-12-15 15:10:09 -06:00
Joel Martin 7e2784bfcc Merge remote branch 'snorkeyg/master' 2011-11-04 10:16:17 -05:00
Joel Martin 669f77edb0 Merge commit 'e69a8d89c2354c146fa8969a142e0244be5b229a'
Pruned binary files.
2011-11-04 10:14:40 -05:00
Chris Gordon e80327ac2f Update Windows/Windows Service Readme.txt 2011-11-04 14:01:07 +10:00
Chris Gordon a487e2afa7 Update Windows/Windows Service Readme.txt 2011-11-04 14:00:54 +10:00
Chris Gordon e69a8d89c2 Windows websocket server service wrapper.
Signed-off-by: Chris Gordon <snorkeyg@gmail.com>
2011-11-04 13:52:18 +10:00
Joel Martin 545b6c80de Update kumina with HyBi-10+ support.
Pull 63aa9ce07 from https://github.com/kumina/wsproxy
2011-10-25 17:02:04 -05:00
Joel Martin 40868636da Link to API page. Default length for rQshift*
If no length parameter is given to rQshiftStr or rQshiftBytes, then
the all remaining data (the full length) will be shifted off.

Also, honor the window.WEB_SOCKET_FORCE_FLASH variable to force
web-socket-js to be used even if the browser has native WebSockets
support.
2011-10-06 16:55:10 -05:00
Joel Martin f69ac8e0a0 Clarify protocol/binary issues. 2011-10-06 10:56:36 -05:00
Joel Martin eac2c9fadd Use detection rather than python version checking.
Try importing from the newest location/name and then fallback if that
fails instead of using python version switches.

Still use version switch for the buffer/bytes to string wrapper
routines since python 2.6 has intermediate support for buffer/bytes
and I want to know if full support (ala python 3.0) is there.
2011-10-06 09:37:09 -05:00
Joel Martin 1658649d0c Merge pull request #12 from tomas-edwardsson/master
Python older than 2.5 fails, struct.unpack_from not available
2011-10-06 07:33:39 -07:00
Tomas Edwardsson 74fd12a7ae Added struct.unpack_from for python older that 2.5 2011-10-06 10:25:37 +00:00
Joel Martin acacb4527d HyBi and threading support to ruby websockify. 2011-10-05 17:53:36 -05:00
Joel Martin 6b9d6c39be Add ruby version of websockify.
Initial version is very basic but works: Hixie-76 only, no embedded
webserver, no SSL, etc.
2011-10-04 01:20:14 -05:00
Joel Martin 55e57c2048 Fix VNCAuthProxy reference. 2011-09-29 16:17:16 -05:00
Joel Martin 6748098152 Reference VNCAuthProxy in implementation list. 2011-09-29 16:15:15 -05:00
Joel Martin 724aa3aca0 HyBi fallback when no numpy. Python 3 close fix.
- Use array module for unmasking HyBi when no numpy module is
  available.

- Detect client close properly when using python 3.

- Print request URL path is specified.
2011-09-29 16:08:28 -05:00
Joel Martin 0f8b7580c6 Put include/util.js above include/websock.js.
websock.js uses Util so it needs to included first.
2011-09-23 12:09:16 -05:00
Joel Martin 636aba62ed Add --run-once and --timeout TIME parameters.
- --run-once will exit after handling a single WebSocket connection
  (but not ater flash policy or normal web requests).

- --timeout TIME will stop listening for new connections after exit
  after TIME seconds (the master process shuts down). Existing
  WebSocket connections will continue but once all connections are
  closed all processes will terminate.
2011-09-22 15:52:02 -05:00
Joel Martin 1c39c7f1f0 Fix python3 numpy buffer/string issue.
Simpler fix for this issue:
https://github.com/kanaka/websockify/pull/9

Use consistent string/byte type for HyBi decode with numpy.
2011-09-10 15:57:08 -05:00
Joel Martin 6e263063c2 Support HyBi 13.
Minor change to handshake (Sec-WebSocket-Origin renamed to Origin).

Reported version is 13 (bumped up from 8).
2011-08-31 18:05:03 -05:00
Joel Martin ada02f2c03 websocket.py: silence "Partial unmask" debug. 2011-08-31 15:36:36 -05:00
Joel Martin 0da91c7fdb Fix payload length off-by-one calculation. 2011-08-31 12:40:00 -05:00
Joel Martin 86af0b614d Fix HyBi support on 64-bit systems.
https://github.com/kanaka/noVNC/issues/76

- cleanup/update TODO.
- remove explicit check for ctypes module for HyBi.
2011-08-24 13:23:15 -05:00
Joel Martin 2e00f96431 Fix for python 2.4
Use rsplit(':', 1) instead of rpartition(':') in port argument
processing.

python2.4 may or may not work with HyBi which requires the numpy and
ctypes modules.
2011-08-10 17:48:33 -05:00
Joel Martin 4a84ab3777 More fighting with formating. 2011-08-04 11:13:28 -05:00
Joel Martin 1f7a87ecee Grr, links can't be in table fields apparently. 2011-08-04 11:12:57 -05:00
Joel Martin 7b496ce5bc Clarify that we support HyBi 07-10.
HyBi 07 reports version 7 in the handshake.
HyBi 08-10 report version 8 in the handshake.

Remove version 9 since that is not yet actually defined.
2011-08-04 11:09:12 -05:00
Joel Martin 475cfae4e5 Catch Mozilla prefixing of WebSocket.
In Firefox 7 Mozilla has added Websockets support but prefixed the
constructor with "Moz".
2011-08-02 07:59:37 -05:00
Joel Martin f1c8223a51 websocket.py: show web root, remove execute perm. 2011-07-14 15:55:26 -05:00
Joel Martin 80e1c38dd5 README: session recording no longer broken. 2011-07-14 12:32:06 -05:00
Joel Martin 6d5a137970 README: cleanup. 2011-07-14 12:30:07 -05:00
Joel Martin 6a7b56d56f READMEs: kumina features, clarifications. 2011-07-14 12:27:04 -05:00
Joel Martin 108b617eef Note kumina license, and link to kumina blog post.
Ed Schouten blog article:
http://blog.kumina.nl/2011/06/proxying-and-multiplexing-novnc-using-wsproxy/

Also, clarify external code licenses.
2011-07-13 13:01:03 -05:00
Joel Martin 9c2a41fe0e Merge commit 'kumina/master'
Conflicts:

	wsproxy.c

Conflicts:
	.gitignore
	Makefile
	README.md
2011-07-11 19:14:11 -05:00
Joel Martin 46e2fbee5f Replace addrinfo with socket() static method.
WebSocketServer.socket() is a static method takes a host and port and
an optional connect parameter. If connect is not set then it returns
a socket listening on host and port. If connect is set then
a connection will be made host and port and the socket returned. This
has IPv6 support like the addrinfo method it replaces.

Also, prefer IPv4 resolutions if they are in the list. This can be
overriden to prefer IPv6 resolutions for the same host using the
optional prefer_ipv6 parameter.
2011-07-09 13:34:53 -05:00
Joel Martin 7ae8711dc6 IPv6 and HyBi fixes.
- fix addrinfo to accept empty host as localhost

- use correct host variable in addrinfo error message

- accept HyBi 7, 8 and 9. No difference for now.

- send close buffer correctly.
2011-07-07 15:13:02 -05:00
Joel Martin 247b74950d Minor cleanup of IPv6 support code.
- Use self for static method call.

- Remove extraneous spaces.
2011-07-07 11:45:19 -05:00
Joel Martin e11012437a Merge pull request #5 from desaintmartin/master
Add support for IPv6
2011-07-07 09:19:46 -07:00
Ed Schouten d0e1fe6a3c Remove a faulty attribution from the Copyright.
The Copyright notice was copied from another source file, where I only
changed the Copyright line at the top.
2011-06-29 23:48:15 +02:00
Joel Martin 367ebb5597 Reformat feature table for readability/expansion. 2011-06-29 10:53:13 -05:00
Ed Schouten 8039dddced Add monitoring support to wsproxy. 2011-06-29 11:07:31 +02:00
Vivien Alger 78697b9663 Added static method addrinfo() 2011-06-29 10:19:52 +02:00
Joel Martin b590289de5 Remove extraneous question mark.
Part of https://github.com/kanaka/noVNC/issues/69
2011-06-28 16:28:42 -05:00
Joel Martin 9a2b50d80b Only append random string to swf path in IE.
Issue https://github.com/kanaka/noVNC/issues/69

Thanks https://github.com/EdSchouten for the catch.
2011-06-28 16:21:15 -05:00
Ed Schouten 306eab28da Add README. 2011-06-28 16:41:31 +02:00
Ed Schouten 7057e31fa0 Add support for Flash headers. This makes wsproxy work with Firefox. 2011-06-28 15:41:06 +02:00
Ed Schouten 631c5990f7 Remove all casting from the sockaddr code. 2011-06-28 12:20:21 +02:00
Ed Schouten d97d1b72d7 Add copy of strndup() for Lenny. 2011-06-28 12:11:35 +02:00
Ed Schouten c42612643a Add Debian package infrastructure and license. 2011-06-28 12:05:50 +02:00
Ed Schouten 52b07abe21 Prevent division by zero. 2011-06-28 11:46:59 +02:00
Ed Schouten 2aa2376e3a Add initial version of wsproxy source code. 2011-06-28 11:44:35 +02:00
Algervivien 30681a7018 Use of socket.getaddrinfo() to replace ipv6 attributes. Corrected error with ssl-only option 2011-06-27 18:49:01 +02:00
Algervivien 077279fe0f Refactoring of parsing 2011-06-27 17:07:29 +02:00
Algervivien eb62b2af6e Added data attributes and ipv6 condition for target 2011-06-27 11:01:01 +02:00
Algervivien a09d18b234 Added ipv6 related attributes 2011-06-27 10:21:20 +02:00
Algervivien 8d71c243b1 Modified parsing for ipv6 support 2011-06-27 09:45:49 +02:00
Joel Martin 7f487fdbd5 Fix recording, generic and part of websocket.py.
WebSocketServer(...,  record='FILE_PREFIX')

The reocrd parameter will turn on recording of all messages sent
to and from the client. The record parameter is a file prefix. The
full file-name will be the prefix with an extension '.HANDLER_ID'
based on the handler ID.

Recording required some restructing of the encode and decode function
to return more information so that the recording functions can record
just the payload data and ignore the WebSockets framing/headers.

Caveats:
- Not all messages recorded as sent to the client were necessarily
  received by the client. For example, if several messages are queued
  for the client, but the connection is shutdown before the messages
  are actually sent, these queued messages will still appear in the
  recording.
- If the server is also handling HTTP requests then the handler ID
  extensions for the recorded files will be monotonic but not
  contiguous because only WebSocket connections are recorded, not HTTP
  requests.
2011-06-26 13:55:52 -05:00
Joel Martin d91d89167f Do socket shutdown() of target before close(). 2011-06-26 13:26:59 -05:00
Algervivien 8ae73adbb7 Corrected wrong INET type in else condition 2011-06-24 19:01:47 +02:00
Cédric de Saint Martin d473f4b6d1 Use ipv6 socket when requested 2011-06-24 18:30:11 +02:00
Joel Martin c659bcb79e Refactor optional imports, make 'resource' optional.
Ticket #2: https://github.com/kanaka/websockify/issues/2 - win32
support. The 'resource' module is not available under Windows. We only
use it for daemonizing so make it optional and disable daemonizing
support on Windows for now.

Also, refactor how the optional imports to turn them into data instead
of code and iterate through them.

Add early warnings to indicate when modules are missing and
functionality is disabled.
2011-05-18 15:52:39 -05:00
Joel Martin c8587115bc Python 3.0 support. Use multiprocessing module.
Multiprocessing:
- Switch to using multiprocessing module for python >= 2.6. For python
  2.4 continue to use the os.fork() method.
- Move the new_client creation into top_new_client method to enable
  multiprocessing refactor.
- Only do SIGCHLD handling for os.fork/python 2.4. When doing our own
  SIGCHLD handling under python 3.0, we can run into a python futex
  hang when reloading a web page rapidly. Multiprocessing does it's
  own child reaping so we only need it with os.fork().

Python 3.0:
- Modify imports to reflect new locations: StringIO from io,
  SimpleHTTPRequestHandler from http.server, urlsplit from
  urllib.parse.
- Convert all print statements to print() calls. This also means no
  comma parameter idiom and only using string formatting.
- Define b2s (bytes-to-string) and s2b (string-to-bytes) which are
  no-ops on python versions prior to python 3. In python 3 these do
  the conversion between string and bytes.
- Use compatible try/except method. Exception variable must be
  extracted using sys.exc_info() rather than as part of the except
  statement.

Python 2.4:
- Now degrades more gracefully if ssl module is not found. It will
  still run, but will refuse SSL connections.
- Doesn't support HyBi-07 version due to numpy and struct.unpack_from
  requirement.
2011-05-18 11:09:10 -05:00
Joel Martin 85f84ef280 Refactor HTTP request/upgrade handling.
Instead of doing crazy things with file-descriptors in
SplitHTTPHandler, WSRequestHandler detects a WebSockets upgrade and
returns 101 as the 'last_code'. In addition to avoiding funkiness with
file-descriptors, this allows use of the already parsed headers and
removal of the parse_handshake routine.

This also makes it easier to explore adding python 3.X support
(https://github.com/kanaka/websockify/issues/1) since the
file-descriptor/string splitting is very difficult to integrate with
python 3.X.
2011-05-17 12:08:30 -05:00
Joel Martin 284ef3cc1a Send 'base64' sub-protocol. JSLint.
- Also report back sub-protocol that the server chooses.
2011-05-11 15:14:46 -05:00
Joel Martin 8c3fc55124 Extract close code and reason in decode_hybi.
Also, make it a bit more robust if no code and/or reason is given.
2011-05-02 16:50:17 -05:00
Joel Martin a339a4856a Stop sending empty frames. 2011-05-02 15:15:08 -05:00
Joel Martin c4b6e77127 README.md: formatting, note broken recording. 2011-05-01 22:30:26 -05:00
Joel Martin d82aeac93a README.md: note protocols supported by each variant. 2011-05-01 22:26:59 -05:00
Joel Martin 88b71ce171 Refactor and add IETF-07 protocol version support.
- Add initial IETF-07 (HyBi-07) protocol version support. This version
  still uses base64 encoding since the API for binary support is not
  yet finalized.

- Move socket send and recieve functions into the WebSocketServer
  class instead of having the sub-class do this. This simplifies
  sub-classes somewhat. The send_frame routine now returns the number
  of frames that were unable to be sent. If this value is non-zero
  then the sub-class should call again when the socket is ready until
  the pending frames count is 0.

- Do traffic reporting in the main class instead.

- When the client is HyBi style (i.e. IETF-07) then use the
  sub-protocol header to select whether to do base64 encoding or
  simply send the frame data raw (binary). Update include/websock.js
  to send a 'base64' protocol selector. Once the API support binary,
  then the client will need to detect this and set the protocol to
  'binary'.
2011-05-01 22:17:04 -05:00
Joel Martin ff470ad704 Make daemonize a real static method.
Add chdir option that defaults to '/' instead of passing self and
referencing self.web.
2011-04-30 16:34:56 -05:00
Joel Martin 65c1d8073c Update TODO. Add 'websockify' as protocol. 2011-04-26 09:16:03 -05:00
Joel Martin 2bb1252666 Save handshake headers and path.
Derived classes will almost certainly want to make use of the raw
info.
2011-04-19 09:36:42 -05:00
Joel Martin 7307be683f Fix chdir call to use string instead of character. 2011-04-12 22:46:32 -05:00
Joel Martin 7858c194ca Merge commit 'ccustine/master' 2011-04-12 22:46:03 -05:00
Joel Martin 76e25898bb Couple of misc utf8, base64 python tests. 2011-04-12 22:39:28 -05:00
Chris Custine 82d35c619c Include unistd.h to compile websockify on Mac OS X 2011-04-10 23:37:29 -06:00
Joel Martin 8765971e06 Use /usr/bin/env shebang to make more crossplatform.
Based on noVNC pull request from Decorum.
2011-03-26 15:27:08 -05:00
Joel Martin 7534574a2f Update web-socket-js to bb5797cad.
Primary change is removal of FABridge interface.

Seems to improve overall latency by perhaps 10%. Also, the slowdown
over time in Opera is about half as bad (but still there).
2011-03-16 10:22:31 -05:00
Joel Martin fe6b1f9e7f Pull JSLint'ing from noVNC. 2011-03-15 11:37:59 -05:00
Joel Martin 6954e4641d Better reaper, catch occasional bad WS header line.
Call waitpid in loop to catch SIGCHLD signals that happen while
handling the original SIGCHLD signal.
2011-02-01 10:46:28 -06:00
Joel Martin 0a2f850267 Reap websockify zombies. Add IE9 fix for websock.js.
Reap websockify zombies. Fixes:
https://github.com/kanaka/noVNC/issues#issue/47. Thanks NeilW.

Changes to get web-socket-js to work with IE9. Right now it's a hack to get
around: https://github.com/gimite/web-socket-js/issues#issue/41. The hack is to
disable caching of the flash objects by appending "?" + Math.random() to the
end of the flash object path (but only when using IE).
2011-01-31 10:34:42 -06:00
Joel Martin 58995c6f10 Typo. 2011-01-23 20:00:08 -06:00
Joel Martin 49b47baf13 Add some notes about the methodology of the test data. 2011-01-23 19:58:27 -06:00
Joel Martin cbc01b3f16 Re-order and fix sections. 2011-01-23 19:52:31 -06:00
Joel Martin 3d91fd3492 Use websock.js in latency test. Fixes for Opera.
Convert latency test to use include/websock.js instead of direct
WebSockets handling.

Add support for configuring the maximum bufferedAmount. This allows us
to configure it high enough to get around a bug in bufferedAmount
reporting in Opera.

Add some latency test results for Opera 11 with WebSockets turned on.
2011-01-23 19:30:51 -06:00
Joel Martin 307dda1ad0 Tolerate some bufferedAmount and send() return value.
- Only delay sending data if bufferedAmount is greater than 1000.

This seems to match the intention of the spec better. bufferedAmount
does not mean that we can't send, it's just an indication that the
network is becoming saturated. But Opera 11 native WebSockets seems to
have a bug that bufferedAmount isn't set back to zero correctly so

- websock.send returns true/false.

If all send data was flushed from the send queue then return true,
otherwise false. This doesn't mean the data won't be sent, just that
it wasn't sent this time and is queued.
2011-01-23 19:23:28 -06:00
Joel Martin d8c90aea88 Fix web-socket-js commit hash. 2011-01-19 15:35:21 -06:00
Joel Martin 70cef27dbe Add latency test and browser latency test results. 2011-01-19 15:25:44 -06:00
Joel Martin 4a09e6655e Fix firefox 4 strict complaint. 2011-01-19 15:13:36 -06:00
Joel Martin 3fa7b532b8 Update to gimite/web-socket-js 20f837425d4.
20f837425d4 changes to a single event stream handler fixing the
recursive call errors in firefox and Opera.

Also, pull web-socket-js fix from noVNC

    Related to this issue:
    https://github.com/gimite/web-socket-js/issues/#issue/50

    This prevents the "Uncaught exception: TypeError:
    'this.__handleEvents' is not a function" everytime the timer fires.
2011-01-19 15:10:55 -06:00
Joel Martin 6ff5dfa02d Strip "ws" from test names. Update TODO.
Also, rename wstest to load.
2011-01-19 13:19:47 -06:00
Joel Martin 9c4cf4ada2 Do not hang on non-ready client connection.
Wait 3 seconds for the client to send something. If no data is
available within 3 seconds then close the connection. It's probably
a non-WebSockets client that is waiting for the server to say
something first.
2011-01-13 12:22:22 -06:00
Joel Martin 046e22ea00 Only disable local echo if server is doing echo.
This makes the client usable for other plain text services that telnet
clients can normally communicate with (IRC, SMTP, etc).
2011-01-13 12:19:47 -06:00
Joel Martin 77e12cd586 Make wstelnet.html more prominent earlier. 2011-01-13 00:53:08 -06:00
Joel Martin bc96026fbf Convert wstelnet to use Websock. 2011-01-13 00:28:22 -06:00
Joel Martin 124f28c63a include/websock.js: client library for websockify.
The Websock object from websock.js 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.
2011-01-13 00:17:01 -06:00
Joel Martin 6d1e216115 fork noVNC, rename to websockify, cleanup.
Split of wsproxy from noVNC and rename it websockify.
2011-01-12 18:09:54 -06:00
Joel Martin 932e7318b9 Minor correct to wstelnet.js header comment. 2011-01-12 16:55:31 -06:00
Joel Martin f2538f337d wsproxy, wstelnet: wrap command, WS telnet client.
wswrapper:

    Getting the wswrapper.c LD_PRELOAD model working has turned out to
    involve too many dark corners of the glibc/POSIX file descriptor
    space. I realized that 95% of what I want can be accomplished by
    adding a "wrap command" mode to wsproxy.

    The code is still there for now, but consider it experimental at
    best. Minor fix to dup2 and add dup and dup3 logging.

wsproxy Wrap Command:

    In wsproxy wrap command mode, a command line is specified instead
    of a target address and port. wsproxy then uses a much simpler
    LD_PRELOAD library, rebind.so, to move intercept any bind() system
    calls made by the program. If the bind() call is for the wsproxy
    listen port number then the real bind() system call is issued for
    an alternate (free high) port on loopback/localhost.  wsproxy then
    forwards from the listen address/port to the moved port.

    The --wrap-mode argument takes three options that determine the
    behavior of wsproxy when the wrapped command returns an exit code
    (exit or daemonizing): ignore, exit, respawn.

    For example, this runs vncserver on turns port 5901 into
    a WebSockets port (rebind.so must be built first):

        ./utils/wsproxy.py --wrap-mode=ignore 5901 -- vncserver :1

    The vncserver command backgrounds itself so the wrap mode is set
    to "ignore" so that wsproxy keeps running even after it receives
    an exit code from vncserver.

wstelnet:

    To demonstrate the wrap command mode, I added WebSockets telnet
    client.

    For example, this runs telnetd (krb5-telnetd) on turns port 2023
    into a WebSockets port (using "respawn" mode since telnetd exits
    after each connection closes):

        sudo ./utils/wsproxy.py --wrap-mode=respawn 2023 -- telnetd -debug 2023

    Then the utils/wstelnet.html page can be used to connect to the
    telnetd server on port 2023. The telnet client includes VT100.js
    (from http://code.google.com/p/sshconsole) which handles the
    terminal emulation and rendering.

rebind:

    The rebind LD_PRELOAD library is used by wsproxy in wrap command
    mode to intercept bind() system calls and move the port to
    a different port on loopback/localhost. The rebind.so library can
    be built by running make in the utils directory.

    The rebind library can be used separately from wsproxy by setting
    the REBIND_OLD_PORT and REBIND_NEW_PORT environment variables
    prior to executing a command. For example:

        export export REBIND_PORT_OLD="23"
        export export REBIND_PORT_NEW="65023"
        LD_PRELOAD=./rebind.so telnetd -debug 23

    Alternately, the rebind script does the same thing:

        rebind 23 65023 telnetd -debug 23

Other changes/notes:

- wsproxy no longer daemonizes by default. Remove -f/--foreground
  option and add -D/--deamon option.

- When wsproxy is used to wrap a command in "respawn" mode, the
  command will not be respawn more often than 3 times within 10
  seconds.

- Move getKeysym routine out of Canvas object so that it can be called
  directly.
2011-01-12 13:15:11 -06:00
Joel Martin 86725f9b4c wswrapper: add dup2, fix select w/ NULL timeout.
- add dup2 functionality. This requires adding a ref cnt to the
  _WS_connections structure so that we only free the structure once
  all dup'd referenced are closed. Also, refactor malloc and free of
  connection structure into _WS_alloc and _WS_free.
- allow select to accept a NULL timeout value which means sleep
  forever instead of segfaulting.
- fix some compile warnings related to ppoll definition.
- move some WebSockets related html test pages into utils and symlink
  them from tests.
2011-01-08 21:46:36 -06:00
Joel Martin 6a88340929 Refactor and cleanup websocket.py and deps.
Moved websocket.py code into a class WebSocketServer. WebSockets
server implementations will sub-class and define a handler() method
which is passed the client socket after. Global variable settings have been
changed to be parameters for WebSocketServer when created.

Subclass implementations still have to handle queueing and sending but
the parent class handles everything else (daemonizing, websocket
handshake, encode/decode, etc). It would be better if the parent class
could handle queueing and sending. This adds some buffering and
polling complexity to the parent class but it would be better to do so
at some point. However, the result is still much cleaner as can be
seen in wsecho.py.

Refactored wsproxy.py and wstest.py (formerly ws.py) to use the new
class. Added wsecho.py as a simple echo server.

- rename tests/ws.py to utils/wstest.py and add a symlink from
  tests/wstest.py

- rename tests/ws.html to tests/wstest.html to match utils/wstest.py.

- add utils/wsecho.py

- add tests/wsecho.html which communicates with wsecho.py and simply
  sends periodic messages and shows what is received.
2011-01-08 15:29:01 -06:00
Joel Martin 6ace64d3ae utils/README.md: horizontal looks better.
Flip table back to be horizontal. More readable.
2011-01-06 19:21:17 -06:00
Joel Martin 90966d6251 utils/README.md: flip table. Add web server info.
Flip the feature table to be tall instead of wide.

Added row about "web server" functionality in wsproxy.py.
2011-01-06 19:17:32 -06:00
Joel Martin 9aaf26e878 Merge branch 'master' of git@github.com:kanaka/noVNC 2011-01-06 19:13:39 -06:00
Joel Martin 02a7dd2c29 Merge branch 'master' of git@github.com:kanaka/noVNC 2011-01-06 17:33:22 -07:00
Joel Martin 96bc3d3088 wsproxy.py: add web serving capability.
- Added ability to respond to normal web requests. This is basically
  integrating web.py functionality into wsproxy. This is only in the
  python version and it is off by default when calling wsproxy. Turn
  it on with --web DIR where DIR is the web root directory.

Next task is to clean up wsproxy.py. It's gotten unwieldy and it
really no longer needs to be parallel to the C version.
2011-01-06 18:26:54 -06:00
Joel Martin 58dc1947de wsproxy: warn when no cert. C sock close cleanup.
Warn early about no SSL cert and add clearer warning when a connection
comes in as SSL but no cert file exists.

For the C version, cleanup closing of the connection socket. Use
shutdown for a cleaner cleanup with the client.
2011-01-04 13:14:46 -06:00
Joel Martin 58da507bb8 README: add companies/projects using noVNC. 2011-01-04 12:19:54 -06:00
Joel Martin 9b940131d3 include/canvas.js: show full user agent in console. 2011-01-04 10:30:26 -06:00
Joel Martin e3716842ef include/rfb.js: show Flash version in console. 2011-01-04 10:27:25 -06:00
Joel Martin bf5ee68828 Expose getKeysym and add keyboard test.
Related to issue Non-US keyboard layout option issue:
https://github.com/kanaka/noVNC/issues#issue/21
2011-01-03 12:34:41 -06:00
Joel Martin 2574936f60 utils/README.md, docs/TODO, docs/notes: updates.
Add wswrapper info to utils/README.md and docs/TODO. Remove innacurate
info from docs/notes.
2010-12-30 11:00:50 -07:00
Joel Martin 71ba9a7a54 wswrapper: update README, DO_MSG def for output.
Update README to mention wswrapper. Add DO_MSG define which controls
whether wswrapper code generates basic output.
2010-12-29 14:11:28 -07:00
Joel Martin 56d9aa816b wswrapper: interpose on poll/ppoll also.
poll/ppoll interposer builds but is untested.
2010-12-27 19:44:14 -07:00
Joel Martin 64dbc6bb63 wswrapper: timeout select.
The select call needs to timeout if a WebSocket socket keeps reporting
ready but actually isn't ready. To prevent it hanging forever in that
condition, the timeout value is now adjusted now for each call.

Move the DO_DEBUG and DO_TRACE settings to wswrapper.c.
2010-12-27 16:08:27 -07:00
Joel Martin 6b900d25d0 wswrapper: interpose select/pselect. Cleaup.
Interpose on select/pselect so that WebSockets sockets are only
reported as ready if they have enough to actually decode at least
1 byte of real data. This prevents hanging in read/recv after
WebSocket is reported as ready but is not actually ready because empty
frames or less than four base64 bytes have been received.

Split defines and constant defintions into wswrapper.h.

Cleanup debug output and add TRACE for more detailed tracing debug
output.

Major TODO is that select needs to timeout if WebSocket socket keeps
reporting ready but actually isn't ready. That condition will
currently hang forever because the select timeout value is not
adjusted when looping.
2010-12-27 13:21:07 -07:00
Joel Martin fce6ac5cb4 Fix to "Tolerate fragmented ServerInit".
Issue #39: https://github.com/kanaka/noVNC/issues/issue/39
2010-12-24 17:39:13 -07:00
Joel Martin 318d473438 Tolerate fragmented ServerInit.
Issue #39: https://github.com/kanaka/noVNC/issues/issue/39
2010-12-24 15:02:48 -07:00
Joel Martin 0f7f146f20 utils/launch.sh: find top web dir (with vnc.html). 2010-12-21 10:17:43 -06:00
Amir Malik b992f7c7dd use cd, dirname, and pwd to determine path instead of readlink (Mac fix) 2010-12-22 00:15:33 +08:00
Amir Malik a22a3cc0ea set socket option SO_REUSEADDR to prevent "Address already in use" error 2010-12-21 23:31:46 +08:00
Joel Martin 40a653f555 wswrapper: fix preload path and interpose port.
Make path to ld preload library absolute so wswrapper works even if
path is changed before main program is executed (i.e. by the vncserver
wrapper script).

bind() was using the return value for the port number, but it's
actually the original port number that we should interpose on in the
bind() routine.
2010-12-16 14:04:16 -06:00
Joel Martin b144a0933d wswrapper: Normalize comments, remove unused headers. 2010-12-14 13:14:21 -05:00
Joel Martin c99124b527 wswrapper: Allow multiple WebSockets connections.
Allocate buffer and state memory for each accepted connection. This
allows all WebSockets connections to a given listen port to be wrapped
with WebSockets support.
2010-12-14 13:14:12 -05:00
Joel Martin 70c585968b wswrap: WSWRAP_PORT envvar and wswrap script.
wswrapper.so will only interpose on the listen port specified in
WSWRAP_PORT.

Add simple wswrap script that sets the WSWRAP_PORT, LD_PRELOAD and
invokes the command line to wrap.
2010-12-13 14:20:34 -05:00
Joel Martin e46719100c Make compatible with jQuery. Slight API change.
Rename the $() selector to $D() so that it doesn't collide with
the jQuery name.

The API change is that the 'target' option for Canvas and RFB objects
must now be a DOM Canvas element. A string is no longer accepted
because this requires that a DOM lookup is done and the Canvas and RFB
should have no UI code in them. Modularity.
2010-12-10 08:25:36 -06:00
Joel Martin 5b0bbd5c12 wswrapper: wrap existing server using LD_PRELOAD.
wswrapper.so is LD_PRELOAD shared library that interposes and turns
a generic TCP socket into a WebSockets service.

This current version works but will only allow work for a single
connection, subsequent connections will not be wrapped. In addition
the wrapper interposes on the first incoming network connection. It
should read an environment variable to determine the port to interpose
on. Also, should limit origin based on another environment variable.
Then there should be a wswrap setup script that allows easier
invocation.
2010-12-02 22:11:02 -06:00
Joel Martin 79f0a095b6 rfb.js: avoid multiple b64 sequences per frame.
Only call encode_message when the WebSockets object is actually
ready to send. Otherwise multiple base64 encode sequences can be
encoded into the same WebSockets frame. This causes the C version of
wsproxy to crash and the python version to ignore the subsequent
base64 sequence(s).

Thanks to Colin Dean (xvpsource.org) for finding this and helping
track it down.
2010-11-15 13:43:26 -05:00
Joel Martin f7ec5b2cb6 Rename default_controls.js to ui.js.
And DefaultControls to UI.
2010-11-10 16:02:19 -06:00
Joel Martin e66f3f89f2 Add Chrome Frame support. Close requests in web.py.
- Add meta tag to vnc.html and vnc_auto.html so that if Chrome Frame
  is installed, it is used.

- Add detection to default_controls.js that shows a message with
  a Chrome Frame install link if the user is using a version of IE
  without Canvas support.

- Fix web.py so that requests have their connection closed after they
  are completed.  This has been a bug for a while but it prevents
  Chrome Frame from working because Chrome Frame doesn't activate
  until the initial request connection closes.
2010-11-09 12:06:03 -06:00
Joel Martin 1ee2d93e94 wsproxy.js: Fix multi-frame decoding.
- Also, discovered node.js bug in base64 decoding. Added test case and
  filed https://github.com/ry/node/issues/issue/402
2010-11-07 22:28:08 -06:00
Joel Martin fd758dd335 First pass at wsproxy using node (node.js).
Node:
    http://nodejs.org/
    https://github.com/ry/node

It mostly works, but it eventually gets an error from the target which
is probably due to missing support for re-assembly of client
WebSockets frames.
2010-11-07 19:06:20 -06:00
Joel Martin 58b4c9408f wsproxy: Fix --key parameter use. 2010-11-06 14:12:37 -05:00
Joel Martin c1d008f1ee Fix flush with strict DOCTYPE.
- With a strict doctype, the margin size needs a "px" suffix.
2010-11-06 14:11:30 -05:00
Joel Martin cdb55d26e5 canvas.js: workaround WebKit bug, issue #28.
This is WebKit bug https://bugs.webkit.org/show_bug.cgi?id=46319

The workaround is to wrap Canvas render functions with a function that
sets a flush timer. The flush function sets the right margin and then
1ms later sets it back. This triggers the canvas to redraw with the
correct contents.

Two downsides:
- rendering is slower, but only on the busted versions of webkit.
  Correct and useful is better than fast and useless.
- There is a barely perceptible jitter of the control buttons because
  the canvas size is changing by one pixel.

To support this functionality, we also have to read out the exact
webkit version from the user agent in the render engine detection code
in include/util.js.
2010-11-06 12:23:23 -05:00
Joel Martin 455e4657f6 default_controls.js: canvas fail fix. Misc cleanup.
- Make sure that canvas exists (i.e. didn't throw an error) before
  trying to call canvas method get_canvas_uri.

- Typos in HTML render engine debug output.
2010-11-06 12:15:08 -05:00
Joel Martin 3205a3dee8 Add --key option for separate cert and key file.
If only --cert is specified then continue to assume both certificate
and key are in the same file (key first).
2010-11-06 10:55:09 -05:00
Joel Martin e70f1d947e Remove left over record code. Squelch compile warnings 2010-11-06 10:53:32 -05:00
François Revol f61274c827 wsproxy: Mac OS X build fixes
- pass CFLAGS and LDFLAGS in case one needs to use -m32
- link to libcrypto for _ERR_print_errors_fp
- __THROW is non-standard define it to nothing by default
- use b64_ntop and b64_pton instead of mangled versions, OSX doesn't mangle them in the same way
- access() takes two arguments!

Signed-off-by: François Revol <revol@free.fr>
2010-11-06 10:04:24 -05:00
Joel Martin 1f758e87d3 Issue #34: fix RFB 3.3/3.7 with no auth scheme.
- Split out ClientInitialisation state.

- In version 3.3 and 3.7, when the server has no auth (scheme
  1), then we should skip from Authentication to ClientInitialisation.
2010-10-28 16:30:41 -05:00
Joel Martin 3dc3135b21 utils/README.md: second try on cmd formatting. 2010-10-28 10:53:08 -05:00
Joel Martin 6502293f21 utils/README.md: Fix command formatting. 2010-10-28 10:52:27 -05:00
Joel Martin e5d60a8ba2 Issue #32, wsproxy README, update webkit bug info,
- Add wsproxy README.md in utils/ directory.

- Document how to build ssl module for python 2.5 and older in wsproxy
  README.

- Update browsers.md to note revision that have the webkit Canvas
  rendering bug: WebKit build 66396 through 68867 (Chrome/Chromium
  build 57968 through 61278).
2010-10-28 10:45:26 -05:00
Joel Martin f1a9971c82 Expose VNC shared mode setting in UIs.
If shared mode is false, then the server should disconnect other
connections before the current connection is allowed to proceed.
2010-10-24 18:34:50 -05:00
Joel Martin 65bca0c904 Fix style caching. Canvas cleanup from Diet-noVNC.
- Style caching gives a small performance speedup in firefox, but not
  much. Might not be worth complexity, but leave it in for now.
2010-10-18 14:30:50 -05:00
Joel Martin 028b26f14b Fix reason_len not defined bug. 2010-10-14 11:07:54 -05:00
Joel Martin ce2b6909cd rfb.js: fail() wrapper for common failed pattern. 2010-10-14 10:09:33 -05:00
Joel Martin 8b17ac27f0 Add manual flash policy socat server info. 2010-10-10 18:59:02 -05:00
Joel Martin c084c396ba utils/Makefile: clean up md5.o too. 2010-10-04 13:30:53 -04:00
Joel Martin 60440cee15 rfb.js: rQwait, cuttext simplification.
- rQwait checks the receive queue to see if there is enough data to
  satisfy the following request. If not it returns true (which is
  almost always translated into an immediate return false by the
  caller).

- rQwait is called quite a bit and this generally allows 4 lines to
  become 1 line where it is called.

- rQwait allows simplification of cuttext processing. No global
  tracking needed anymore.

Overall, about 60 lines less code.
2010-10-01 11:50:22 -05:00
Joel Martin a99959719d include/des.js: trim some fat.
DES is just used once during authentication and is not performance
sensitive so we save some space by generating and/or removing some
lookup tables. Also, shorten some very frequently used variables.

Shaves off about 100 lines.
2010-09-30 11:17:52 -05:00
Joel Martin a59f1cd269 webutil.js, util.js: split cleanup. 2010-09-29 15:05:27 -05:00
Joel Martin 5a00c9d18a Merge branch 'master' of git@github.com:kanaka/noVNC 2010-09-29 15:01:01 -05:00
Antoine Mercadal 8d5d2c8230 Split util into two file:
- util.js that contains essential functions
 - webutils.js that contains the GUI utility function.js

this helps to include noVNC in other project, especially Cappuccino Application
i
2010-09-30 03:59:56 +08:00
Joel Martin 12d2e7c192 des.js: remove decrypt and simplify.
The decrypt functionality is never used so remove it. Also, we can
assume that we are always DES encrypting 16 characters which allows
several things to be simplified in DES.

Overall this removes about 80 lines of code.
2010-09-29 14:48:19 -05:00
Joel Martin a679a97d1b Show rect/enc counts, add vnc_perf.html test.
- include/rfb.js: Keep track of the number of rects of each encoding
  type and print them out when we close a connection (if 'info'
  logging level).

- tests/vnc_perf.html: first pass at a noVNC based performance
  benchmark.

- utils/wsproxy.py: Fix the output of the record filename.
2010-09-25 15:50:43 -05:00
Joel Martin 3b20e7a90f rfb.js, canvas.js: status feedback on Canvas functionality.
Read the render mode selected by canvas and report it in the initial
page loaded status message.
2010-09-24 10:47:39 -05:00
Joel Martin 562beccf18 docs/browsers.md: noVNC webkit bug link format. 2010-09-24 10:46:59 -05:00
Joel Martin d4139a9b06 README.md: move browser page link. 2010-09-24 10:45:33 -05:00
Joel Martin 6de07adb71 README.md: add link to browsers.md, update requirements. 2010-09-24 10:29:42 -05:00
Joel Martin f01e917ecc docs/browsers.md: Separate browser support page. 2010-09-24 09:59:54 -05:00
Joel Martin ff36b1270b Refactor settings object, add connectTimeout setting.
- include/util.js: Add type and desc field to conf_default routine.
  Make comment descriptions of settings into desc parameters that can
  be queried. Also, use set_FOO in conf_default to set or coerce the
  current setting so that we always have the right type for the value.

- include/rfb.js, include/default_config.js: add connectTimeout
  setting to address situations with slow connections that may need
  more than 2 seconds.
2010-09-23 09:39:24 -05:00
Joel Martin aa78706983 rfb.js: wait for SecurityResult failure reason bytes.
Yet another weird VNC server behavior: sending a failure and length
before the reason message. To calculated the length, the reason string
is already available, why not just send everything as one packet. Oh
well.
2010-09-23 09:17:09 -05:00
Joel Martin 005d9ee999 Misc cleanup: debug logging, record filename, etc.
- include/canvas.js: When 'debug' logging, show browser detection
  values.
- test/canvas.html: Only restore the canvas to it's starting state if
  the logging level is not 'debug'.
- wsproxy.py: Append the session number to the record filename so that
  multiple sessions don't stomp on each other.
2010-09-23 08:17:00 -05:00
Joel Martin 8787e49b92 util.js: detect firefox 4.X correctly.
Update the browser detection code (from mootools) with a fix that
detects firefox 4.0 correctly.
2010-09-23 08:08:08 -05:00
Joel Martin c1eba48f79 logging: add Util.get_logging(), canvas clearing.
Only clear canvas if log level is not debug instead of using
'#__debug__' in the URL.
2010-09-22 17:11:57 -05:00
Joel Martin 57c7903f60 playback.js: move to include/ for easier reference.
Easier to reference from web site (gh-pages branch).
2010-09-22 16:55:06 -05:00
Joel Martin 31a837d55e No local cursor by default due to issues #27, #29.
In Safari, local cursor rendering is corrupt. In firefox 3.6.10, local
cursor rendering causes a segfault. Probable that the .cur format is
not 100% compliant (even though it works in Chrome and firefox 3.5 and
firefox 4.0). So just disable it by default until I can figure out how
to address the problems.
2010-09-20 16:15:40 -05:00
Joel Martin 02889945cb C proxy: Issue #14: wss:// from Safari
Addresses this issue:
http://github.com/kanaka/noVNC/issues#issue/14

This goes along with commit 7e63919e6 but for the C proxy.
2010-09-15 18:21:42 -05:00
Joel Martin 0a1184bde8 API change: add sendKey() to manually send key code.
RFB.sendKey(code, down)

If down is not specified then both a down followed by an up code will
be sent.
2010-09-15 18:14:27 -05:00
Joel Martin 7e63919e6d proxy: Issue #14: detect and allow wss:// from Safari.
Addresses this issue:
http://github.com/kanaka/noVNC/issues#issue/14

Safari starts with '\x80' rather than '\x16' like Chrome and Firefox
and having PROTOCOL_TLSv1 doesn't work with Safari. But just removing
the ssl_version allows things to work with Safari wss:// connections.

Also, if the handshake (after SSL wrapping) is null then terminate the
connection. This probably means the certificate was refused by the
client. Unfortunately Safari (the version I have) doesn't cleanly
shutdown WebSockets connections until the page is reloaded (even if
the object is no longer referenced).
2010-09-15 12:19:17 -05:00
Joel Martin e3efeb32a7 rfb.js: state refactor, add 'disconnect' state.
Add a new state 'disconnect' to reflect that we are not truly
'disconnected' until we get an onclose event. Add a disconnect timer
to match.

Handle disconnected cleanup better in updateState(). Anytime we enter
in a disconnect/disconnected state, make sure all running state is
cleaned up (WebSocket, timers, canvas).
2010-09-11 15:31:50 -05:00
Joel Martin cc374cd61a proxy: always multiprocess and add --verbose.
Always fork handlers processes. Instead printing traffic when
single-processing, print traffic if verbose flag given.
2010-09-11 15:10:54 -05:00
Joel Martin ac7bdbc22f web-socket-js (issue #37): close() when connecting
Filed this issue for this bug:
http://github.com/gimite/web-socket-js/issues/issue/37

Right now the close() call only calls __flash.close() if readyState is OPEN.
But it should really call close any time that readyState is not CLOSED or
CLOSING.

The case I ran into is when I want to do the following:
1. make a test connection
2. tell the server to setup for a connection
3. connect again

I call close on the test connection, but since it is ignored when CONNECTING,
it eventually times out with a error. But by that time I have already issued a
new connection, it causes the new connection to fail. close() should cancel
CONNECTING state too.
2010-09-11 13:52:49 -05:00
Joel Martin 071f2818a8 gimite/web-socket-js issue #35: async onclose.
Filed this bug about this issue:
http://github.com/gimite/web-socket-js/issues#issue/35

To work around the flash "recursive call" problem, WebSocket.as has
the onclose event disabled in the close() call and the javascript half
of the close() call does the onclose() call instead. This is fine, but
it needs to be asynchronous to act more like what happens with
a normal WebSockets object. The current behavior is that the onclose()
method is called inline (synchronously) when the close() is called and
this inconsistency make state handling more difficult.
2010-09-11 12:44:39 -05:00
Joel Martin edc4725260 proxy: do handshake in forked process too. 2010-09-10 14:31:34 -05:00
Joel Martin a0315ab1dc wsproxy: multiprocess capable.
Add -m, --multiprocess option which forks a handler for each
connection allowing multiple connections to the same target using the
same proxy instance.

Cleaned up the output of the handler process. Each process' output is
prefixed with an ordinal value.

Changed both the C and python versions of the proxy.
2010-09-10 13:05:48 -05:00
Joel Martin 465faf19db Remove record option from C wsproxy.
I've decided that debug/develop/extra features will just be in the
python version of the proxy. The C version (and other versions) will
just have the core functionality (unless someone wants to support it).
2010-09-10 09:58:26 -05:00
Joel Martin 5f409eeeeb License header cleanup. 2010-09-08 15:06:34 -05:00
Joel Martin 2a6018df9f web-socket-js: 9e7663771 build and remove source.
web-socket-js now has all the functionality and fixes needed for noVNC
so remove the include/as3crypto_patched directory and the
include/web-socket-js/flash-src directory (i.e. the sources for
web-socket-js). This cleans up almost 3K from the include/ directory.

Update to web-socket-js build based on upstream (gimite/web-socket-js)
9e766377188.
2010-09-08 14:57:32 -05:00
Joel Martin b5087acc24 default_controls.js: Fix cursor setting init.
The rfb variable wasn't available at the point settingsDisabled() was
being called since it was called inline with RFB() initialization. To
solve this we pass the updateState rfb variable so that the canvas can
be queried for setting the cursor_uri value.
2010-09-08 13:46:41 -05:00
Joel Martin c0f3c66489 TODO and .gitignore: updates. 2010-09-08 10:15:07 -05:00
Joel Martin d595e65685 JSLint. 2010-09-08 10:11:11 -05:00
Joel Martin 2f6a1c2bda vnc_playback.html: print frame_idx on error. 2010-09-07 16:22:28 -05:00
Joel Martin 673118fb21 Encrypt default to 'false' in vnc_auto.html also. 2010-09-07 09:57:37 -05:00
Joel Martin b8bd88d085 playback.js: realtime playback and split out code.
Preparation for online demo.

Split general playback code into tests/playback.js.

Use timestamps from recording with proxy to playback in realtime.
2010-09-01 12:31:54 -05:00
Joel Martin 975aa8c01c TODO: move long-term features to github issues. 2010-08-31 22:48:11 -05:00
Joel Martin 3afc7a2b89 Issue #15 - rfb.js: wait for security type list.
Apparently the virtualbox VNC server send the size and then the
security type list in separate frames so we need to wait for the full
list.
2010-08-31 22:22:22 -05:00
Joel Martin 3cc74720f0 canvas.js: Fix ignore for scrolled window.
When the documement/window is scrolled, the onMouseDisable routine was
not properly calculating the position to test whether to ignore the
event or not.
2010-08-31 13:36:14 -05:00
Joel Martin d67de76770 Rename tightpng img queue variable to imgQ. 2010-08-31 12:08:47 -05:00
Joel Martin 3e7a7cefc6 More timing "history" purge. 2010-08-30 15:59:53 -05:00
Joel Martin 9c57ac3985 rfb.js: JSLint'ing
Change RQ and SQ vars to rQ and sQ since caps at the start implies
a classable entity.
2010-08-30 15:57:58 -05:00
Joel Martin 0d1e1b7281 Merge init() into the constructor.
This is logical now since the external update callback can be provided
when the object is created so we don't need a separate init function.
2010-08-30 15:16:07 -05:00
Joel Martin 55dee43279 Remove psuedo-UTF8 encoding.
It's less efficient on average that base64 (150% vs 133%). It's
non-standard (0 shifted to 256 before encoding). And I rarely use it.
2010-08-27 12:10:09 -05:00
Joel Martin e8c1698995 rfb.js: remove timing history.
Turned out not to be useful (pretty much never looked at the info once
I added it). The playback test is much more useful for measuring
performance.
2010-08-27 11:29:22 -05:00
Joel Martin eabf4670fb rfb.js/tight_png: fix indexed receive queue handling.
getCLength was not using the index (RQi) into the receive queue.
2010-08-27 11:21:30 -05:00
Joel Martin 4ff85f496c Test both builtin and base64.js functions. 2010-08-26 11:34:44 -05:00
Joel Martin 67b4e9879a Indexed receive queue. Up to 2X speedup in Chrome.
Generally, most servers send hextile updates as single updates
containing many rects. Some servers send hextile updates as many small
framebuffer updates with a few rects each (such as QEMU). This latter
cases revealed that shifting off the beginning of the receive queue
(which happens after each hextile FBU) performs poorly.

This change switches to using an indexed receive queue (instead of
actually shifting off the array). When the receive queue has grown to
a certain size, then it is compacted all at once.

The code is not as clean, but this change results in more than 2X
speedup under Chrome for the pessimal case and 10-20% in firefox.
2010-08-26 10:22:29 -05:00
Joel Martin fb007628d6 Add Javascript variable container to record data.
- This allows the recorded data to be immediately usable by
  tests/vnc_playback.html
2010-08-12 09:50:49 -05:00
Joel Martin 1a5dd77d37 Treat RFB 3.6 as 3.3.
Apparently there are versions of UltraVNC that report version 3.6.
This is not a legal version according to the spec, but we'll just
force version 3.3 if we receive it. Thanks to Larry Rowe for the info.
2010-08-11 11:21:15 -05:00
Joel Martin 4ed717ad31 Scroll render test and perf speedup.
Turns out when Windows is running in QEMU and a window scroll happens,
there are lots of little hextile rects sent. This is slow in noVNC.

- Some recording/playback improvement.
- Add test harness to drive playback of recordings.
- By pulling off the rect header in one chunk we get a 3X speedup in
  Chrome and a 20% speedup in firefox (specifically for the scroll
  test).
- Also, get rid of some noise from creating timers for handle_message.
  Check to make sure there isn't already a pending timer first.
2010-08-06 16:43:24 -05:00
primalmotion b7155950d3 * take care of kanaka's suggestions
(cherry picked from commit 11f3271a52)

Signed-off-by: Joel Martin <github@martintribe.org>
2010-08-04 15:29:42 -05:00
primalmotion 6425f611d8 * Adding a way to set the DOM document to use.
This is very usefull when you need to open a new window (with a new document) from javascript,
without having to reload the script.js.
(cherry picked from commit 8ded53c1de)

Signed-off-by: Joel Martin <github@martintribe.org>
2010-08-04 15:18:17 -05:00
Joel Martin b925c96781 JSLint: use ===. 2010-08-04 15:14:40 -05:00
Joel Martin a6a1ad3d0a Remove unused imports (sys, ssl) in wsproxy.py 2010-08-04 14:33:32 -05:00
Joel Martin 5958fb4996 Python 2.4 compatible imports.
- Fallback to md5 module if hashlib not there.
- Import parse_qsl from cgi where it is in both 2.4 and 2.6
2010-08-04 14:32:10 -05:00
Joel Martin c95c24e743 Fix #19: python2.4 support.
- Replace URL parsing using "".partition() with urlparse module.
2010-08-04 14:18:55 -05:00
Joel Martin 801482be6a WebSockets orderly/clean close frame.
- When a packet with only '\xff\x00' is received, this means the
  client is doing an orderly shutdown. (WebSockets spec version 76)
2010-08-03 13:23:59 -05:00
Joel Martin 208c832b28 Encrypt default to off, TODO updates. 2010-08-03 13:20:44 -05:00
278 changed files with 9849 additions and 36822 deletions
+9 -1
View File
@@ -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
+3
View File
@@ -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
View File
@@ -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
View File
@@ -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
+2
View File
@@ -0,0 +1,2 @@
include CHANGES.txt README.md LICENSE.txt
graft include
+11
View File
@@ -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
+140 -199
View File
@@ -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>&nbsp;<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.
+39
View File
@@ -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
+373
View File
@@ -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.
+5 -50
View File
@@ -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
+4
View File
@@ -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"
+114
View File
@@ -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
View File
@@ -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
View File
@@ -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
-67
View File
@@ -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).
+13
View File
@@ -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
View File
@@ -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.
+110
View File
@@ -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/
+919
View File
@@ -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 />&nbsp; 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 += '&amp;'; break;
case '<':
stuff += '&lt;'; break;
case '>':
stuff += '&gt;'; break;
case ' ':
//stuff += '&nbsp;'; 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");
}
-75
View File
@@ -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.
*/
-13
View File
@@ -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,
-15
View File
@@ -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
-21
View File
@@ -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.
-109
View File
@@ -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.
-14
View File
@@ -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)
-14
View File
@@ -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();
}
}
}
@@ -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,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";
}
}
}
@@ -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,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